diff --git a/controllers/modpanel.go b/controllers/modpanel.go index 5bbe43c1..c9f88a20 100644 --- a/controllers/modpanel.go +++ b/controllers/modpanel.go @@ -546,7 +546,7 @@ func torrentManyAction(c *gin.Context) { messages.AddErrorT("errors", "invalid_torrent_category") } - if !categories.CategoryExists(category) { + if !categories.Exists(category) { messages.AddErrorT("errors", "invalid_torrent_category") } } diff --git a/controllers/publicSettingsHandler.go b/controllers/publicSettingsHandler.go index 040bdd1d..8ee05ca9 100644 --- a/controllers/publicSettingsHandler.go +++ b/controllers/publicSettingsHandler.go @@ -14,21 +14,21 @@ import ( // LanguagesJSONResponse : Structure containing all the languages to parse it as a JSON response type LanguagesJSONResponse struct { - Current string `json:"current"` - Languages map[string]string `json:"languages"` + Current string `json:"current"` + Languages publicSettings.Languages `json:"language"` } // SeePublicSettingsHandler : Controller to view the languages and themes func SeePublicSettingsHandler(c *gin.Context) { _, Tlang := publicSettings.GetTfuncAndLanguageFromRequest(c) availableLanguages := publicSettings.GetAvailableLanguages() - + languagesJson := LanguagesJSONResponse{Tlang.Tag, availableLanguages} contentType := c.Request.Header.Get("Content-Type") if contentType == "application/json" { c.Header("Content-Type", "application/json") - c.JSON(http.StatusOK, LanguagesJSONResponse{Tlang.Tag, availableLanguages}) + c.JSON(http.StatusOK, languagesJson) } else { - changeLanguageTemplate(c, Tlang.Tag, availableLanguages) + formTemplate(c, "user/public/settings.jet.html", languagesJson) } } @@ -43,7 +43,7 @@ func ChangePublicSettingsHandler(c *gin.Context) { availableLanguages := publicSettings.GetAvailableLanguages() - if _, exists := availableLanguages[lang]; !exists { + if !availableLanguages.Exist(lang) { messages.AddErrorT("errors", "language_not_available") } // FIXME Are the settings actually sanitized? diff --git a/controllers/rss_handler.go b/controllers/rss_handler.go index 1486fb3b..c73fe107 100644 --- a/controllers/rss_handler.go +++ b/controllers/rss_handler.go @@ -177,7 +177,7 @@ func RSSTorznabHandler(c *gin.Context) { } if t == "caps" { T := publicSettings.GetTfuncFromRequest(c) - cat := categories.GetCategoriesSelect(true, true) + cat := categories.GetSelect(true, true) var categories []*nyaafeeds.RssCategoryTorznab categories = append(categories, &nyaafeeds.RssCategoryTorznab{ ID: "5070", diff --git a/controllers/template.go b/controllers/template.go index 13d2ed3c..11207e98 100644 --- a/controllers/template.go +++ b/controllers/template.go @@ -144,7 +144,7 @@ func torrentTemplate(c *gin.Context, torrent models.TorrentJSON, rootFolder *fil renderTemplate(c, path.Join(SiteDir, "torrents/view.jet.html"), vars) } -func userProfileEditTemplate(c *gin.Context, userProfile *models.User, userForm userValidator.UserForm, languages map[string]string) { +func userProfileEditTemplate(c *gin.Context, userProfile *models.User, userForm userValidator.UserForm, languages publicSettings.Languages) { vars := commonVars(c) vars.Set("UserProfile", userProfile) vars.Set("UserForm", userForm) @@ -169,13 +169,6 @@ func databaseDumpTemplate(c *gin.Context, listDumps []models.DatabaseDumpJSON, G vars.Set("GPGLink", GPGLink) renderTemplate(c, path.Join(SiteDir, "database/dumps.jet.html"), vars) } -func changeLanguageTemplate(c *gin.Context, language string, languages map[string]string) { - vars := commonVars(c) - vars.Set("Language", language) - vars.Set("Languages", languages) - renderTemplate(c, path.Join(SiteDir, "user/public/settings.jet.html"), vars) -} - func panelAdminTemplate(c *gin.Context, torrent []models.Torrent, reports []models.TorrentReportJSON, users []models.User, comments []models.Comment) { vars := newPanelCommonVariables(c) vars.Set("Torrents", torrent) diff --git a/controllers/template_functions.go b/controllers/template_functions.go index 99b563b7..043155a8 100644 --- a/controllers/template_functions.go +++ b/controllers/template_functions.go @@ -162,10 +162,10 @@ func templateFunctions(vars jet.VarMap) jet.VarMap { }) vars.Set("GetHostname", format.GetHostname) vars.Set("GetCategories", func(keepParent bool, keepChild bool) map[string]string { - return categories.GetCategoriesSelect(keepParent, keepChild) + return categories.GetSelect(keepParent, keepChild) }) vars.Set("GetCategory", func(category string, keepParent bool) (categoryRet map[string]string) { - cat := categories.GetCategoriesSelect(true, true) + cat := categories.GetSelect(true, true) var keys []string for name := range cat { keys = append(keys, name) @@ -191,8 +191,8 @@ func templateFunctions(vars jet.VarMap) jet.VarMap { vars.Set("CategoryName", func(category string, sub_category string) string { s := category + "_" + sub_category - if category, ok := categories.GetCategories()[s]; ok { - return category + if category, ok := categories.GetByID(s); ok { + return category.Name } return "" }) diff --git a/controllers/template_test.go b/controllers/template_test.go index 143c374b..0d8f570f 100644 --- a/controllers/template_test.go +++ b/controllers/template_test.go @@ -56,7 +56,7 @@ func walkDirTest(dir string, t *testing.T) { }, "edit.jet.html": func(vars jet.VarMap) jet.VarMap { vars.Set("Form", &torrentValidator.TorrentRequest{}) - vars.Set("Languages", make(map[string]string)) + vars.Set("Languages", publicSettings.Languages{{"", ""}}) return vars }, "upload.jet.html": func(vars jet.VarMap) jet.VarMap { @@ -69,8 +69,7 @@ func walkDirTest(dir string, t *testing.T) { return vars }, "settings.jet.html": func(vars jet.VarMap) jet.VarMap { - vars.Set("Language", "") - vars.Set("Languages", make(map[string]string)) + vars.Set("Form", &LanguagesJSONResponse{"", publicSettings.Languages{{"", ""}}}) return vars }, "login.jet.html": func(vars jet.VarMap) jet.VarMap { diff --git a/templates/site/user/edit.jet.html b/templates/site/user/edit.jet.html index e1e6040d..5f41e8fb 100644 --- a/templates/site/user/edit.jet.html +++ b/templates/site/user/edit.jet.html @@ -17,8 +17,8 @@

{{ yield errors(name="language")}} diff --git a/templates/site/user/public/settings.jet.html b/templates/site/user/public/settings.jet.html index 1280e213..028f236c 100644 --- a/templates/site/user/public/settings.jet.html +++ b/templates/site/user/public/settings.jet.html @@ -8,9 +8,8 @@

{{ T("language")}}

{{ T("theme")}}

diff --git a/utils/categories/categories.go b/utils/categories/categories.go index 94479889..c821176a 100644 --- a/utils/categories/categories.go +++ b/utils/categories/categories.go @@ -1,39 +1,89 @@ package categories import ( + "sort" + "github.com/NyaaPantsu/nyaa/config" ) -var categories map[string]string +// Category is a struct defining a category +type Category struct { + ID string + Name string +} -// GetCategories : function to get all categories depending on the actual website from config/categories.go -func GetCategories() map[string]string { - if categories != nil { - return categories - } - - if config.IsSukebei() { - categories = config.Conf.Torrents.SukebeiCategories - } else { - categories = config.Conf.Torrents.CleanCategories +// Cateogories is a struct defining an array of categories +type Categories []Category + +var categories Categories +var Index map[string]int + +func init() { + if len(categories) == 0 { + var cats map[string]string + if config.IsSukebei() { + cats = config.Conf.Torrents.SukebeiCategories + } else { + cats = config.Conf.Torrents.CleanCategories + } + + // Sorting categories alphabetically + var index []string + ids := make(map[string]string) + Index = make(map[string]int, len(cats)) + for id, name := range cats { + index = append(index, name) + ids[name] = id + } + sort.Strings(index) + + // Creating index of categories + for k, name := range index { + categories = append(categories, Category{ids[name], name}) + Index[ids[name]] = k + } } +} +// All : function to get all categories depending on the actual website from config/categories.go +func All() Categories { return categories } -// CategoryExists : Check if a category exist in config -func CategoryExists(category string) bool { - _, exists := GetCategories()[category] - return exists +// Get : function to get a category by the key in the index array +func Get(key int) Category { + return categories[key] } -// GetCategoriesSelect : Format categories in map ordered alphabetically -func GetCategoriesSelect(keepParent bool, keepChild bool) map[string]string { - categories := GetCategories() +// Get : function to get a category by the id of the category from the database +func GetByID(id string) (Category, bool) { + if key, ok := Index[id]; ok { + return categories[key], true + } + return Category{"", ""}, false +} + +// Exists : Check if a category exist in config +func (cats Categories) Exists(category string) bool { + for _, cat := range cats { + if cat.Name == category { + return true + } + } + return false +} + +// Exists : Check if a category exist in config +func Exists(category string) bool { + return categories.Exists(category) +} + +// GetSelect : Format categories in map ordered alphabetically +func GetSelect(keepParent bool, keepChild bool) map[string]string { catSelect := make(map[string]string, len(categories)) - for k, v := range categories { - if (keepParent && keepChild) || (len(k) > 2 && !keepParent) || (len(k) <= 2 && !keepChild) { - catSelect[v] = k + for _, v := range categories { + if (keepParent && keepChild) || (len(v.ID) > 2 && !keepParent) || (len(v.ID) <= 2 && !keepChild) { + catSelect[v.Name] = v.ID } } return catSelect diff --git a/utils/feeds/convert.go b/utils/feeds/convert.go index 54ac57d3..c4b5f882 100644 --- a/utils/feeds/convert.go +++ b/utils/feeds/convert.go @@ -39,7 +39,7 @@ func convertCat(cat string) string { c := strconv.Itoa(cI) sub := strconv.Itoa(subI) - if categories.CategoryExists(c + "_" + sub) { + if categories.Exists(c + "_" + sub) { return c + "_" + sub } diff --git a/utils/publicSettings/publicSettings.go b/utils/publicSettings/publicSettings.go index 0887ffe0..7f09e7c5 100644 --- a/utils/publicSettings/publicSettings.go +++ b/utils/publicSettings/publicSettings.go @@ -7,6 +7,8 @@ import ( "path" "path/filepath" + "sort" + "github.com/NyaaPantsu/nyaa/config" "github.com/NyaaPantsu/nyaa/models" "github.com/gin-gonic/gin" @@ -19,12 +21,20 @@ type UserRetriever interface { RetrieveCurrentUser(c *gin.Context) (*models.User, error) } +type Language struct { + Name string + Code string +} + +type Languages []Language + // TemplateTfunc : T func used in template type TemplateTfunc func(string, ...interface{}) template.HTML var ( defaultLanguage = config.Conf.I18n.DefaultLanguage userRetriever UserRetriever + languages Languages ) // InitI18n : Initialize the languages translation @@ -83,21 +93,32 @@ func TfuncAndLanguageWithFallback(language string, languages ...string) (i18n.Tr return translateFunction, tLang, err1 } -// GetAvailableLanguages : Get languages available on the website -func GetAvailableLanguages() (languages map[string]string) { - languages = make(map[string]string) +// GetAvailableLanguages : Get languages available on the website, languages are parsed once at runtime +func GetAvailableLanguages() Languages { + if len(languages) > 0 { + return languages + } var T i18n.TranslateFunc + + // Need this to sort out languages alphabetically by language tag + var codes []string for _, languageTag := range i18n.LanguageTags() { + codes = append(codes, languageTag) + } + sort.Strings(codes) + + // Now build languages array + for _, languageTag := range codes { T, _ = i18n.Tfunc(languageTag) /* Translation files should have an ID with the translated language name. If they don't, just use the languageTag */ if languageName := T("language_name"); languageName != "language_name" { - languages[languageTag] = languageName + languages = append(languages, Language{languageName, languageTag}) } else { - languages[languageTag] = languageTag + languages = append(languages, Language{languageName, languageTag}) } } - return + return languages } // GetDefaultTfunc : Gets T func from default language @@ -181,3 +202,14 @@ func getCurrentUser(c *gin.Context) (*models.User, error) { } return userRetriever.RetrieveCurrentUser(c) } + +func (langs Languages) Exist(name string) bool { + + for _, language := range langs { + if language.Code == name || language.Name == name { + return true + } + } + + return false +} diff --git a/utils/search/structs/structs.go b/utils/search/structs/structs.go index 54e19bd0..aa4862e6 100644 --- a/utils/search/structs/structs.go +++ b/utils/search/structs/structs.go @@ -202,7 +202,7 @@ func ParseCategories(s string) []*Category { if err == nil { sub = uint8(tmp) } - if catUtil.CategoryExists(partsCat[0] + "_" + partsCat[1]) { + if catUtil.Exists(partsCat[0] + "_" + partsCat[1]) { categories = append(categories, &Category{ Main: c, Sub: sub, diff --git a/utils/torrentLanguages/torrent_languages.go b/utils/torrentLanguages/torrent_languages.go index 495c6659..271e35f3 100644 --- a/utils/torrentLanguages/torrent_languages.go +++ b/utils/torrentLanguages/torrent_languages.go @@ -13,12 +13,14 @@ var torrentLanguages []string func initTorrentLanguages() { languages := publicSettings.GetAvailableLanguages() - for code := range languages { - torrentLanguages = append(torrentLanguages, code) + + for _, lang := range languages { + torrentLanguages = append(torrentLanguages, lang.Code) } // Also support languages we don't have a translation torrentLanguages = append(torrentLanguages, config.Conf.Torrents.AdditionalLanguages...) + sort.Strings(torrentLanguages) } diff --git a/utils/validator/torrent/functions.go b/utils/validator/torrent/functions.go index a0cb1802..dd2b6a5f 100644 --- a/utils/validator/torrent/functions.go +++ b/utils/validator/torrent/functions.go @@ -4,6 +4,13 @@ import ( "encoding/base32" "encoding/hex" "errors" + "io" + "mime/multipart" + "net/url" + "regexp" + "strconv" + "strings" + "github.com/NyaaPantsu/nyaa/config" "github.com/NyaaPantsu/nyaa/utils/categories" "github.com/NyaaPantsu/nyaa/utils/format" @@ -11,12 +18,6 @@ import ( "github.com/NyaaPantsu/nyaa/utils/torrentLanguages" "github.com/gin-gonic/gin" "github.com/zeebo/bencode" - "io" - "mime/multipart" - "net/url" - "regexp" - "strconv" - "strings" ) func (r *TorrentRequest) ValidateName() error { @@ -102,7 +103,7 @@ func (r *TorrentRequest) ExtractCategory() error { return errors.New("torrent_cat_invalid") } - if !categories.CategoryExists(r.Category) { + if !categories.Exists(r.Category) { return errors.New("torrent_cat_invalid") }