From 938bd27e3b2c22ccf32c5bd02895f85e174b32b1 Mon Sep 17 00:00:00 2001 From: akuma06 Date: Sat, 22 Jul 2017 01:14:16 +0200 Subject: [PATCH 1/5] Initial tag system --- models/tag.go | 11 +++++++++++ models/torrent.go | 5 +++-- models/user.go | 16 ++++++++++++++++ templates/template_test.go | 2 +- utils/publicSettings/publicSettings_test.go | 10 ++++++---- 5 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 models/tag.go diff --git a/models/tag.go b/models/tag.go new file mode 100644 index 00000000..0cf84658 --- /dev/null +++ b/models/tag.go @@ -0,0 +1,11 @@ +package models + +// Tag model for a torrent vote system +type Tag struct { + TorrentID uint `gorm:"column:torrent_id"` + UserID uint `gorm:"column:user_id"` + Tag string `gorm:"column:tag"` + Type string `gorm:"column:type"` + Weight float64 `gorm:"column:weight"` + Accepted bool `gorm:"column:accepted"` +} diff --git a/models/torrent.go b/models/torrent.go index 4b6dc8dc..3ef6fbed 100644 --- a/models/torrent.go +++ b/models/torrent.go @@ -53,7 +53,7 @@ type Torrent struct { Filesize int64 `gorm:"column:filesize"` Description string `gorm:"column:description"` WebsiteLink string `gorm:"column:website_link"` - AnidbID string `gorm:"column:anidb_id"` + DbID string `gorm:"column:db_id"` Trackers string `gorm:"column:trackers"` // Indicates the language of the torrent's content (eg. subs, dubs, raws, manga TLs) Language string `gorm:"column:language"` @@ -63,6 +63,7 @@ type Torrent struct { OldUploader string `gorm:"-"` // ??????? OldComments []OldComment `gorm:"ForeignKey:torrent_id"` Comments []Comment `gorm:"ForeignKey:torrent_id"` + Tags []Tag `gorm:"-"` Scrape *Scrape `gorm:"AssociationForeignKey:ID;ForeignKey:torrent_id"` FileList []File `gorm:"ForeignKey:torrent_id"` Languages []string `gorm:"-"` // This is parsed when retrieved from db @@ -84,7 +85,7 @@ type TorrentJSON struct { Comments []CommentJSON `json:"comments"` SubCategory string `json:"sub_category"` Category string `json:"category"` - AnidbID string `json:"anidb_id"` + DbID string `json:"db_id"` UploaderID uint `json:"uploader_id"` UploaderName template.HTML `json:"uploader_name"` OldUploader template.HTML `json:"uploader_old"` diff --git a/models/user.go b/models/user.go index 4bf3e249..0a3da3f1 100644 --- a/models/user.go +++ b/models/user.go @@ -12,6 +12,8 @@ import ( "errors" + "math" + "github.com/NyaaPantsu/nyaa/config" "github.com/NyaaPantsu/nyaa/utils/crypto" ) @@ -45,6 +47,7 @@ type User struct { Mascot string `gorm:"column:mascot"` MascotURL string `gorm:"column:mascot_url"` UserSettings string `gorm:"column:settings"` + Pantsu float64 `gorm:"column:pantsu"` // TODO: move this to PublicUser Followers []User // Don't work `gorm:"foreignkey:user_id;associationforeignkey:follower_id;many2many:user_follows"` @@ -390,3 +393,16 @@ func (u *User) Filter() *User { u.Torrents = torrents return u } + +// IncreasePantsu is a function that uses the formula to increase the Pantsu points of a user +func (u *User) IncreasePantsu() { + if u.Pantsu <= 0 { + u.Pantsu = 1 // Pantsu points should never be less or equal to 0. This would trigger a division by 0 + } + u.Pantsu = u.Pantsu * (1 + 1/(math.Pow(math.Log(u.Pantsu+1), 5))) // First votes substancially increases the vote, further it increase slowly +} + +// DecreasePantsu is a function that uses the formula to decrease the Pantsu points of a user +func (u *User) DecreasePantsu() { + u.Pantsu = 0.8 * u.Pantsu // You lose 20% of your pantsu points each wrong vote +} diff --git a/templates/template_test.go b/templates/template_test.go index a020968f..af9f52e6 100644 --- a/templates/template_test.go +++ b/templates/template_test.go @@ -43,7 +43,7 @@ func TestTemplates(t *testing.T) { type ContextTest map[string]func(jet.VarMap) jet.VarMap func walkDirTest(dir string, t *testing.T) { - fakeUser := &models.User{1, "test", "test", "test", 1, time.Now(), time.Now(), "test", time.Now(), "en", "test", "test", "test", "test", []models.User{}, []models.User{}, "test", []models.Torrent{}, []models.Notification{}, 1, models.UserSettings{}} + fakeUser := &models.User{1, "test", "test", "test", 1, time.Now(), time.Now(), "test", time.Now(), "en", "test", "test", "test", "test", 0, []models.User{}, []models.User{}, "test", []models.Torrent{}, []models.Notification{}, 1, models.UserSettings{}} fakeComment := &models.Comment{1, 1, 1, "test", time.Now(), time.Now(), nil, &models.Torrent{}, fakeUser} fakeScrapeData := &models.Scrape{1, 0, 0, 10, time.Now()} fakeFile := &models.File{1, 1, "l12:somefile.mp4e", 3} diff --git a/utils/publicSettings/publicSettings_test.go b/utils/publicSettings/publicSettings_test.go index d1eed9d4..c070e4b1 100644 --- a/utils/publicSettings/publicSettings_test.go +++ b/utils/publicSettings/publicSettings_test.go @@ -6,7 +6,6 @@ import ( "github.com/nicksnyder/go-i18n/i18n" "golang.org/x/text/language" - "golang.org/x/text/language/display" "fmt" @@ -46,7 +45,7 @@ func TestLanguages(t *testing.T) { if displayLang.String() == "und" { t.Errorf("Couldn't find the language display for the language %s", displayLang.String()) } - n := display.Tags(displayLang) + //n := display.Tags(displayLang) tags := i18n.LanguageTags() for _, languageTag := range tags { @@ -55,8 +54,11 @@ func TestLanguages(t *testing.T) { if lang.String() == "und" { t.Errorf("Couldn't find the language root for the language %s", languageTag) } - fmt.Printf("Name of the language natively: %s\n", strings.Title(display.Self.Name(lang))) - fmt.Printf("Name of the language in %s: %s\n", displayLang.String(), n.Name(lang)) + for _, t := range strings.Split(languageTag, ", ") { + fmt.Printf("UPDATE torrents SET language='%s' WHERE language='%s';\n", lang, t) + } + //fmt.Printf("Name of the language natively: %s\n", strings.Title(display.Self.Name(lang))) + //fmt.Printf("Name of the language in %s: %s\n", displayLang.String(), n.Name(lang)) } } From e5c115b4003d804c56675672b2e504cced0459af Mon Sep 17 00:00:00 2001 From: akuma06 Date: Fri, 28 Jul 2017 20:43:22 +0200 Subject: [PATCH 2/5] Adding tag post controller --- config/default_config.yml | 3 +++ config/structs.go | 5 +++++ controllers/torrent/tag.go | 27 +++++++++++++++++++++++++++ controllers/torrent/view.go | 24 +++++++++++++++++++++++- models/gorm.go | 4 ++++ models/tag.go | 30 ++++++++++++++++++++++++++++++ models/torrent.go | 20 +++++++++++++++++--- models/user.go | 11 +++++++++++ models/users/find.go | 9 +++++++++ 9 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 controllers/torrent/tag.go diff --git a/config/default_config.yml b/config/default_config.yml index d6cd6c17..919e222b 100644 --- a/config/default_config.yml +++ b/config/default_config.yml @@ -126,6 +126,9 @@ torrents: order: torrent_id # TorrentSort : Default sorting order for torrents sort: DESC + tags: +# Torrent Tag Max weight for automatic system approval + max_weight: 100.00 users: default_notifications_settings: {"new_torrent": true, "new_torrent_email": false, "new_comment": true, "new_comment_email": false, "new_responses": false, "new_responses_email": false, "new_follower": false, "new_follower_email": false, "followed": false, "followed_email": false} navigation: diff --git a/config/structs.go b/config/structs.go index 8e1ead8a..1ca64932 100644 --- a/config/structs.go +++ b/config/structs.go @@ -46,6 +46,10 @@ type Config struct { Models ModelsConfig `yaml:"models,flow,omitempty"` } +type Tags struct { + MaxWeight float64 `yaml:"max_weight,omitempty"` +} + // WebAddressConfig : Config struct for web addresses type WebAddressConfig struct { Nyaa string `yaml:"nyaa,omitempty"` @@ -119,6 +123,7 @@ type TorrentsConfig struct { Trackers TrackersConfig `yaml:"trackers,flow,omitempty"` Order string `yaml:"order,omitempty"` Sort string `yaml:"sort,omitempty"` + Tags Tags `yaml:"tags,omitempty"` } // UsersConfig : Config struct for Users diff --git a/controllers/torrent/tag.go b/controllers/torrent/tag.go new file mode 100644 index 00000000..f1a87f6f --- /dev/null +++ b/controllers/torrent/tag.go @@ -0,0 +1,27 @@ +package torrentController + +import ( + "github.com/NyaaPantsu/nyaa/models" + "github.com/NyaaPantsu/nyaa/models/tags" + msg "github.com/NyaaPantsu/nyaa/utils/messages" + "github.com/NyaaPantsu/nyaa/utils/validator" + "github.com/NyaaPantsu/nyaa/utils/validator/tags" + "github.com/gin-gonic/gin" +) + +func postTag(c *gin.Context, torrent *models.Torrent, user *models.User) { + messages := msg.GetMessages(c) + tagForm := &tagsValidator.CreateForm{} + + c.Bind(tagForm) + validator.ValidateForm(tagForm, messages) + + for _, tag := range user.Tags { + if tag.Tag == tagForm.Tag { + return // already a tag by the user, don't add one more + } + } + + tags.Create(tagForm.Tag, tagForm.Type, torrent, user) // Add a tag to the db + tags.Filter(tagForm.Tag, tagForm.Type, torrent.ID) // Check if we have a tag reaching the maximum weight, if yes, deletes every tag and add only the one accepted +} diff --git a/controllers/torrent/view.go b/controllers/torrent/view.go index 2f23370a..ff52e2b3 100644 --- a/controllers/torrent/view.go +++ b/controllers/torrent/view.go @@ -20,35 +20,57 @@ func ViewHandler(c *gin.Context) { messages := msg.GetMessages(c) user := router.GetUser(c) + // Display success message on upload if c.Request.URL.Query()["success"] != nil { messages.AddInfoT("infos", "torrent_uploaded") } + // Display success message on edit if c.Request.URL.Query()["success_edit"] != nil { messages.AddInfoT("infos", "torrent_updated") } + // Display wrong captcha error message if c.Request.URL.Query()["badcaptcha"] != nil { messages.AddErrorT("errors", "bad_captcha") } + // Display reported successful message if c.Request.URL.Query()["reported"] != nil { messages.AddInfoTf("infos", "report_msg", id) } + // Retrieve the torrent torrent, err := torrents.FindByID(uint(id)) - if c.Request.URL.Query()["notif"] != nil { + // If come from notification, toggle the notification as read + if c.Request.URL.Query()["notif"] != nil && user.ID > 0 { notifications.ToggleReadNotification(torrent.Identifier(), user.ID) } + // If torrent not found, display 404 if err != nil { c.Status(http.StatusNotFound) return } + + // We load tags for user and torrents + user.LoadTags(torrent) + torrent.LoadTags() + + // We add a tag if posted + if c.PostForm("tag") != "" && user.ID > 0 { + postTag(c, torrent, user) + } + + // Convert torrent to the JSON Model used to display a torrent + // Since many datas need to be parsed from a simple torrent model to the actual display b := torrent.ToJSON() + // Get the folder root for the filelist view folder := filelist.FileListToFolder(torrent.FileList, "root") captchaID := "" + //Generate a captcha if user.NeedsCaptcha() { captchaID = captcha.GetID() } + // Display finally the view templates.Torrent(c, b, folder, captchaID) } diff --git a/models/gorm.go b/models/gorm.go index 8d906a87..506bbe7c 100644 --- a/models/gorm.go +++ b/models/gorm.go @@ -106,5 +106,9 @@ func GormInit(conf *config.Config, logger Logger) (*gorm.DB, error) { if db.Error != nil { return db, db.Error } + db.AutoMigrate(&Tag{}) + if db.Error != nil { + return db, db.Error + } return db, nil } diff --git a/models/tag.go b/models/tag.go index 0cf84658..b27abb81 100644 --- a/models/tag.go +++ b/models/tag.go @@ -1,5 +1,12 @@ package models +import ( + "errors" + "net/http" + + "github.com/fatih/structs" +) + // Tag model for a torrent vote system type Tag struct { TorrentID uint `gorm:"column:torrent_id"` @@ -8,4 +15,27 @@ type Tag struct { Type string `gorm:"column:type"` Weight float64 `gorm:"column:weight"` Accepted bool `gorm:"column:accepted"` + Total float64 `gorm:"-"` +} + +// Update a tag +func (ta *Tag) Update() (int, error) { + if ORM.Model(ta).UpdateColumn(ta.toMap()).Error != nil { + return http.StatusInternalServerError, errors.New("Tag was not updated") + } + return http.StatusOK, nil +} + +// Delete : delete a tag based on id +func (ta *Tag) Delete() (int, error) { + if ORM.Delete(ta).Error != nil { + return http.StatusInternalServerError, errors.New("tag_not_deleted") + } + + return http.StatusOK, nil +} + +// toMap : convert the model to a map of interface +func (ta *Tag) toMap() map[string]interface{} { + return structs.Map(ta) } diff --git a/models/torrent.go b/models/torrent.go index 3ef6fbed..82d18581 100644 --- a/models/torrent.go +++ b/models/torrent.go @@ -98,6 +98,7 @@ type TorrentJSON struct { Completed uint32 `json:"completed"` LastScrape time.Time `json:"last_scrape"` FileList []FileJSON `json:"file_list"` + Tags []Tag `json:"-"` // not needed in json to reduce db calls } // Size : Returns the total size of memory recursively allocated for this struct @@ -347,6 +348,7 @@ func (t *Torrent) ToJSON() TorrentJSON { Completed: scrape.Completed, LastScrape: scrape.LastScrape, FileList: fileListJSON, + Tags: t.Tags, } return res @@ -365,7 +367,6 @@ func TorrentsToJSON(t []Torrent) []TorrentJSON { // Update : Update a torrent based on model func (t *Torrent) Update(unscope bool) (int, error) { - cache.C.Delete(t.Identifier()) db := ORM if unscope { db = ORM.Unscoped() @@ -385,6 +386,8 @@ func (t *Torrent) Update(unscope bool) (int, error) { log.Errorf("Unable to update torrent to ES index: %s", err) } } + // We only flush cache after update + cache.C.Delete(t.Identifier()) return http.StatusOK, nil } @@ -394,9 +397,8 @@ func (t *Torrent) UpdateUnscope() (int, error) { return t.Update(true) } -// DeleteTorrent : delete a torrent based on id +// Delete : delete a torrent based on id func (t *Torrent) Delete(definitely bool) (*Torrent, int, error) { - cache.C.Flush() db := ORM if definitely { db = ORM.Unscoped() @@ -413,6 +415,8 @@ func (t *Torrent) Delete(definitely bool) (*Torrent, int, error) { log.Errorf("Unable to delete torrent to ES index: %s", err) } } + // We flush cache only after delete + cache.C.Flush() return t, http.StatusOK, nil } @@ -426,3 +430,13 @@ func (t *Torrent) DefinitelyDelete() (*Torrent, int, error) { func (t *Torrent) toMap() map[string]interface{} { return structs.Map(t) } + +// LoadTags : load all the unique tags with summed up weight from the database in torrent +func (t *Torrent) LoadTags() { + // Only load if necessary + if len(t.Tags) == 0 { + // Should output a query like this: SELECT tag, type, accepted, SUM(weight) as total FROM tags WHERE torrent_id=923000 GROUP BY type, tag ORDER BY type, total DESC + err := ORM.Select("tag, type, accepted, SUM(weight) as total").Where("torrent_id = ?", t.ID).Group("type, tag").Order("type ASC, total DESC").Find(&t.Tags).Error + log.CheckErrorWithMessage(err, "LOAD_TAGS_ERROR: Couldn't load tags!") + } +} diff --git a/models/user.go b/models/user.go index 854174db..8688b19c 100644 --- a/models/user.go +++ b/models/user.go @@ -59,6 +59,7 @@ type User struct { UnreadNotifications int `gorm:"-"` // We don't want to loop every notifications when accessing user unread notif Settings UserSettings `gorm:"-"` // We don't want to load settings everytime, stock it as a string, parse it when needed + Tags []Tag `gorm:"-"` // We load tags only when viewing a torrent } // UserJSON : User model conversion in JSON @@ -406,3 +407,13 @@ func (u *User) IncreasePantsu() { func (u *User) DecreasePantsu() { u.Pantsu = 0.8 * u.Pantsu // You lose 20% of your pantsu points each wrong vote } + +func (u *User) LoadTags(torrent *Torrent) { + if u.ID == 0 { + return + } + if err := ORM.Where("torrent_id = ? AND user_id = ?", torrent.ID, u.ID).Find(&u.Tags).Error; err != nil { + log.CheckErrorWithMessage(err, "LOAD_TAGS_ERROR: Couldn't load tags!") + return + } +} diff --git a/models/users/find.go b/models/users/find.go index a530b5d3..f480b7d6 100644 --- a/models/users/find.go +++ b/models/users/find.go @@ -105,6 +105,15 @@ func FindByID(id uint) (*models.User, int, error) { return user, http.StatusOK, nil } +// FindRawByID retrieves a user by ID without anything. +func FindRawByID(id uint) (*models.User, int, error) { + var user = &models.User{} + if models.ORM.Last(user, id).RecordNotFound() { + return user, http.StatusNotFound, errors.New("user_not_found") + } + return user, http.StatusOK, nil +} + func SessionByID(id uint) (*models.User, int, error) { var user = &models.User{} if models.ORM.Preload("Notifications").Where("user_id = ?", id).First(user).RecordNotFound() { // We only load unread notifications From 8dddc5240c207c735cc9c631f5338a248fd6b2f9 Mon Sep 17 00:00:00 2001 From: akuma06 Date: Fri, 28 Jul 2017 23:02:37 +0200 Subject: [PATCH 3/5] Added html views + fix template test + View & JSON Controller --- config/default_config.yml | 5 +++ config/structs.go | 24 ++++++++--- controllers/torrent/router.go | 2 + controllers/torrent/tag.go | 57 +++++++++++++++++++++++++++ templates/site/torrents/edit.jet.html | 6 +-- templates/site/torrents/tag.jet.html | 29 ++++++++++++++ templates/template_test.go | 10 +++-- translations/en-us.all.json | 24 +++++++++++ 8 files changed, 145 insertions(+), 12 deletions(-) create mode 100644 templates/site/torrents/tag.jet.html diff --git a/config/default_config.yml b/config/default_config.yml index 919e222b..7c833de1 100644 --- a/config/default_config.yml +++ b/config/default_config.yml @@ -129,6 +129,11 @@ torrents: tags: # Torrent Tag Max weight for automatic system approval max_weight: 100.00 +# Array of tag types allowed for now + types: + - anidbid + - vndbid + - quality users: default_notifications_settings: {"new_torrent": true, "new_torrent_email": false, "new_comment": true, "new_comment_email": false, "new_responses": false, "new_responses_email": false, "new_follower": false, "new_follower_email": false, "followed": false, "followed_email": false} navigation: diff --git a/config/structs.go b/config/structs.go index 1ca64932..c21c76dd 100644 --- a/config/structs.go +++ b/config/structs.go @@ -47,7 +47,8 @@ type Config struct { } type Tags struct { - MaxWeight float64 `yaml:"max_weight,omitempty"` + MaxWeight float64 `yaml:"max_weight,omitempty"` + Types ArrayString `yaml:"types,omitempty"` } // WebAddressConfig : Config struct for web addresses @@ -102,8 +103,8 @@ type ScraperConfig struct { // TrackersConfig ; Config struct for Trackers type TrackersConfig struct { - Default []string `yaml:"default,flow,omitempty"` - NeededTrackers []int `yaml:"needed,flow,omitempty"` + Default ArrayString `yaml:"default,flow,omitempty"` + NeededTrackers []int `yaml:"needed,flow,omitempty"` } // TorrentsConfig : Config struct for Torrents @@ -111,9 +112,9 @@ type TorrentsConfig struct { Status []bool `yaml:"status,omitempty,omitempty"` SukebeiCategories map[string]string `yaml:"sukebei_categories,omitempty"` CleanCategories map[string]string `yaml:"clean_categories,omitempty"` - EnglishOnlyCategories []string `yaml:"english_only_categories,omitempty"` - NonEnglishOnlyCategories []string `yaml:"non_english_only_categories,omitempty"` - AdditionalLanguages []string `yaml:"additional_languages,omitempty"` + EnglishOnlyCategories ArrayString `yaml:"english_only_categories,omitempty"` + NonEnglishOnlyCategories ArrayString `yaml:"non_english_only_categories,omitempty"` + AdditionalLanguages ArrayString `yaml:"additional_languages,omitempty"` FileStorage string `yaml:"filestorage,omitempty"` StorageLink string `yaml:"storage_link,omitempty"` CacheLink string `yaml:"cache_link,omitempty"` @@ -198,3 +199,14 @@ type SearchConfig struct { ElasticsearchIndex string `yaml:"es_index,omitempty"` ElasticsearchType string `yaml:"es_type,omitempty"` } + +type ArrayString []string + +func (ar ArrayString) Contains(str string) bool { + for _, s := range ar { + if s == str { + return true + } + } + return false +} diff --git a/controllers/torrent/router.go b/controllers/torrent/router.go index 126654b8..3cb584ef 100644 --- a/controllers/torrent/router.go +++ b/controllers/torrent/router.go @@ -9,6 +9,8 @@ func init() { { torrentRoutes.GET("/", TorrentEditUserPanel) torrentRoutes.POST("/", TorrentPostEditUserPanel) + torrentRoutes.GET("/tag", ViewFormTag) + torrentRoutes.POST("/tag", ViewFormTag) torrentRoutes.GET("/delete", TorrentDeleteUserPanel) } torrentViewRoutes := router.Get().Group("/view") diff --git a/controllers/torrent/tag.go b/controllers/torrent/tag.go index f1a87f6f..7ee60fd3 100644 --- a/controllers/torrent/tag.go +++ b/controllers/torrent/tag.go @@ -1,8 +1,17 @@ package torrentController import ( + "errors" + + "fmt" + "net/http" + "strconv" + + "github.com/NyaaPantsu/nyaa/controllers/router" "github.com/NyaaPantsu/nyaa/models" "github.com/NyaaPantsu/nyaa/models/tags" + "github.com/NyaaPantsu/nyaa/models/torrents" + "github.com/NyaaPantsu/nyaa/templates" msg "github.com/NyaaPantsu/nyaa/utils/messages" "github.com/NyaaPantsu/nyaa/utils/validator" "github.com/NyaaPantsu/nyaa/utils/validator/tags" @@ -16,6 +25,12 @@ func postTag(c *gin.Context, torrent *models.Torrent, user *models.User) { c.Bind(tagForm) validator.ValidateForm(tagForm, messages) + // We check that the tag type sent is one enabled in config.yml + if !tagsValidator.CheckTagType(tagForm.Type) { + messages.ErrorT(errors.New("wrong_tag_type")) + return + } + for _, tag := range user.Tags { if tag.Tag == tagForm.Tag { return // already a tag by the user, don't add one more @@ -25,3 +40,45 @@ func postTag(c *gin.Context, torrent *models.Torrent, user *models.User) { tags.Create(tagForm.Tag, tagForm.Type, torrent, user) // Add a tag to the db tags.Filter(tagForm.Tag, tagForm.Type, torrent.ID) // Check if we have a tag reaching the maximum weight, if yes, deletes every tag and add only the one accepted } + +func ViewFormTag(c *gin.Context) { + messages := msg.GetMessages(c) + user := router.GetUser(c) + id, _ := strconv.ParseInt(c.Query("id"), 10, 32) + // Retrieve the torrent + torrent, err := torrents.FindByID(uint(id)) + + // If torrent not found, display 404 + if err != nil { + c.Status(http.StatusNotFound) + return + } + + // We load tags for user and torrents + user.LoadTags(torrent) + torrent.LoadTags() + + // We add a tag if posted + if c.PostForm("tag") != "" && user.ID > 0 { + postTag(c, torrent, user) + if !messages.HasErrors() { + if _, ok := c.GetQuery("json"); ok { + c.JSON(http.StatusOK, struct { + Ok bool + }{true}) + return + } + c.Redirect(http.StatusSeeOther, fmt.Sprintf("/view/%d", id)) + } + if _, ok := c.GetQuery("json"); ok { + c.JSON(http.StatusOK, struct { + Ok bool + }{false}) + return + } + } + tagForm := &tagsValidator.CreateForm{} + c.Bind(tagForm) + + templates.Form(c, "/site/torrents/tag.jet.html", tagForm) +} diff --git a/templates/site/torrents/edit.jet.html b/templates/site/torrents/edit.jet.html index 943cfe0b..820d81e4 100644 --- a/templates/site/torrents/edit.jet.html +++ b/templates/site/torrents/edit.jet.html @@ -10,12 +10,12 @@ {{ yield csrf_field() }}
- + {{ yield errors(name="name")}}
- {{ range _, cat := GetCategories(false, true) }} @@ -25,7 +25,7 @@
-
+
{{ yield flagList(languages=GetTorrentLanguages(), selected=Form.Languages) }}
{{ yield errors(name="language")}} diff --git a/templates/site/torrents/tag.jet.html b/templates/site/torrents/tag.jet.html new file mode 100644 index 00000000..01623443 --- /dev/null +++ b/templates/site/torrents/tag.jet.html @@ -0,0 +1,29 @@ +{{ extends "layouts/index_site" }} +{{ import "layouts/partials/helpers/csrf" }} +{{ import "layouts/partials/helpers/errors" }} +{{block title()}}{{T("add_tag")}}{{end}} +{{block content_body()}} +
+

{{ T("add_tag") }}

+
+ {{ yield csrf_field() }} +
+ + + {{ yield errors(name="Tag")}} +
+
+ + + {{ yield errors(name="Type")}} +
+ +
+
+
+
+{{end}} \ No newline at end of file diff --git a/templates/template_test.go b/templates/template_test.go index 378f2963..0ec3bad7 100644 --- a/templates/template_test.go +++ b/templates/template_test.go @@ -45,11 +45,11 @@ func TestTemplates(t *testing.T) { type ContextTest map[string]func(jet.VarMap) jet.VarMap func walkDirTest(dir string, t *testing.T) { - fakeUser := &models.User{1, "test", "test", "test", 1, time.Now(), time.Now(), "test", time.Now(), "en", "test", "test", "test", "test", 0, []models.User{}, []models.User{}, "test", []models.Torrent{}, []models.Notification{}, 1, models.UserSettings{}} fu := "http://nyaa.cat" em := "cop@cat.fe" - fakeTag := &models.Tag{1, 1, "12345", "anidbid", 1, false} + fakeTag := &models.Tag{1, 1, "12345", "anidbid", 1, false, 0} + fakeUser := &models.User{1, "test", "test", "test", 1, time.Now(), time.Now(), "test", time.Now(), "en", "test", "test", "test", "test", 0, []models.User{}, []models.User{}, "test", []models.Torrent{}, []models.Notification{}, 1, models.UserSettings{}, []models.Tag{*fakeTag}} fakeComment := &models.Comment{1, 1, 1, "test", time.Now(), time.Now(), nil, &models.Torrent{}, fakeUser} fakeScrapeData := &models.Scrape{1, 0, 0, 10, time.Now()} fakeFile := &models.File{1, 1, "l12:somefile.mp4e", 3} @@ -65,6 +65,7 @@ func walkDirTest(dir string, t *testing.T) { fakeOauthForm := apiValidator.CreateForm{"", "f", []string{fu}, []string{}, []string{}, "", "fedr", fu, fu, fu, fu, []string{em}, ""} fakeOauthModel := fakeOauthForm.Bind(&models.OauthClient{}) fakeClient := client.Client{"", "", "", []string{""}, []string{""}, []string{""}, "", "", "", "", "", "", []string{""}, false} + contextvariables := ContextTest{ "dumps.jet.html": func(variables jet.VarMap) jet.VarMap { variables.Set("GPGLink", "test") @@ -160,7 +161,6 @@ func walkDirTest(dir string, t *testing.T) { return variables }, "callback.jet.html": func(variables jet.VarMap) jet.VarMap { - variables.Set("Callback", true) variables.Set("AccessToken", "") variables.Set("RefreshToken", "") @@ -192,6 +192,10 @@ func walkDirTest(dir string, t *testing.T) { variables.Set("Form", fakeOauthForm) return variables }, + "tag.jet.html": func(variables jet.VarMap) jet.VarMap { + variables.Set("Form", fakeTag) + return variables + }, } fmt.Printf("\nTesting Folder: %s\n", dir) diff --git a/translations/en-us.all.json b/translations/en-us.all.json index 02f1d9d2..e56cbb11 100644 --- a/translations/en-us.all.json +++ b/translations/en-us.all.json @@ -1926,5 +1926,29 @@ { "id": "torrent_age", "translation": "{1} days {2} hours ago" + }, + { + "id": "wrong_tag_type", + "translation": "The tag type selected doesn't exist" + }, + { + "id": "add_tag", + "translation": "Add a Tag" + }, + { + "id": "tagtype", + "translation": "Tag Type" + }, + { + "id": "tagtype_anidbid", + "translation": "Anidb ID" + }, + { + "id": "tagtype_vndbid", + "translation": "VNdb ID" + }, + { + "id": "tagtype_quality", + "translation": "Quality tag" } ] From 92b82b7e8115c8b2b2760001b4a81ecf39be4cee Mon Sep 17 00:00:00 2001 From: akuma06 Date: Fri, 28 Jul 2017 23:26:07 +0200 Subject: [PATCH 4/5] Fix for new gorm dependency --- models/torrents/find.go | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/models/torrents/find.go b/models/torrents/find.go index a0f41c32..e56e3452 100644 --- a/models/torrents/find.go +++ b/models/torrents/find.go @@ -145,26 +145,27 @@ func findOrderBy(parameters *structs.WhereParams, orderBy string, limit int, off } // build custom db query for performance reasons - dbQuery := "SELECT * FROM " + config.Get().Models.TorrentsTableName + dbQuery := models.ORM.Unscoped().Preload("Scrape").Preload("FileList") + if withUser { + dbQuery = dbQuery.Preload("Uploader") + } + if countAll { + dbQuery = dbQuery.Preload("Comments") + } + if conditions != "" { - dbQuery = dbQuery + " WHERE " + conditions + dbQuery = dbQuery.Where(conditions, params...) } if orderBy == "" { // default OrderBy - orderBy = "torrent_id DESC" + orderBy = "torrent_date DESC" } - dbQuery = dbQuery + " ORDER BY " + orderBy + dbQuery = dbQuery.Order(orderBy) if limit != 0 || offset != 0 { // if limits provided - dbQuery = dbQuery + " LIMIT " + strconv.Itoa(limit) + " OFFSET " + strconv.Itoa(offset) + dbQuery = dbQuery.Limit(strconv.Itoa(limit)).Offset(strconv.Itoa(offset)) } - dbQ := models.ORM.Preload("Scrape") - if withUser { - dbQ = dbQ.Preload("Uploader") - } - if countAll { - dbQ = dbQ.Preload("Comments") - } - err = dbQ.Preload("FileList").Raw(dbQuery, params...).Find(&torrents).Error + + err = dbQuery.Find(&torrents).Error // cache.C.Set(fmt.Sprintf("%v", parameters), &structs.TorrentCache{torrents, count}, 5*time.Minute) // Cache shouldn't be done here but in search util return } From af7f57650e45f8f4630f78421d07f3e35a187939 Mon Sep 17 00:00:00 2001 From: akuma06 Date: Fri, 28 Jul 2017 23:32:03 +0200 Subject: [PATCH 5/5] fix pq syntax error on NOT --- models/torrents/find.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/torrents/find.go b/models/torrents/find.go index e56e3452..b9cd29da 100644 --- a/models/torrents/find.go +++ b/models/torrents/find.go @@ -127,7 +127,7 @@ func findOrderBy(parameters *structs.WhereParams, orderBy string, limit int, off if !deleted { conditionArray = append(conditionArray, "deleted_at IS NULL") } else { - conditionArray = append(conditionArray, "deleted_at NOT NULL") + conditionArray = append(conditionArray, "deleted_at IS NOT NULL") } conditions := strings.Join(conditionArray, " AND ")