diff --git a/common/alerts.go b/common/alerts.go index 89df2f44..cc045d52 100644 --- a/common/alerts.go +++ b/common/alerts.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/Azareal/Gosora/query_gen" + "github.com/Azareal/Gosora/common/phrases" ) type AlertStmts struct { @@ -54,7 +55,7 @@ func BuildAlert(asid int, event string, elementType string, actorID int, targetU actor, err := Users.Get(actorID) if err != nil { - return "", errors.New(GetErrorPhrase("alerts_no_actor")) + return "", errors.New(phrases.GetErrorPhrase("alerts_no_actor")) } /*if elementType != "forum" { @@ -66,7 +67,7 @@ func BuildAlert(asid int, event string, elementType string, actorID int, targetU }*/ if event == "friend_invite" { - return buildAlertString(GetTmplPhrase("alerts.new_friend_invite"), []string{actor.Name}, actor.Link, actor.Avatar, asid), nil + return buildAlertString(phrases.GetTmplPhrase("alerts.new_friend_invite"), []string{actor.Name}, actor.Link, actor.Avatar, asid), nil } // Not that many events for us to handle in a forum @@ -75,13 +76,13 @@ func BuildAlert(asid int, event string, elementType string, actorID int, targetU topic, err := Topics.Get(elementID) if err != nil { DebugLogf("Unable to find linked topic %d", elementID) - return "", errors.New(GetErrorPhrase("alerts_no_linked_topic")) + return "", errors.New(phrases.GetErrorPhrase("alerts_no_linked_topic")) } // Store the forum ID in the targetUser column instead of making a new one? o.O // Add an additional column for extra information later on when we add the ability to link directly to posts. We don't need the forum data for now... - return buildAlertString(GetTmplPhrase("alerts.forum_new_topic"), []string{actor.Name, topic.Title}, topic.Link, actor.Avatar, asid), nil + return buildAlertString(phrases.GetTmplPhrase("alerts.forum_new_topic"), []string{actor.Name, topic.Title}, topic.Link, actor.Avatar, asid), nil } - return buildAlertString(GetTmplPhrase("alerts.forum_unknown_action"), []string{actor.Name}, "", actor.Avatar, asid), nil + return buildAlertString(phrases.GetTmplPhrase("alerts.forum_unknown_action"), []string{actor.Name}, "", actor.Avatar, asid), nil } var url, area string @@ -91,7 +92,7 @@ func BuildAlert(asid int, event string, elementType string, actorID int, targetU topic, err := Topics.Get(elementID) if err != nil { DebugLogf("Unable to find linked topic %d", elementID) - return "", errors.New(GetErrorPhrase("alerts_no_linked_topic")) + return "", errors.New(phrases.GetErrorPhrase("alerts_no_linked_topic")) } url = topic.Link area = topic.Title @@ -102,7 +103,7 @@ func BuildAlert(asid int, event string, elementType string, actorID int, targetU targetUser, err = Users.Get(elementID) if err != nil { DebugLogf("Unable to find target user %d", elementID) - return "", errors.New(GetErrorPhrase("alerts_no_target_user")) + return "", errors.New(phrases.GetErrorPhrase("alerts_no_target_user")) } area = targetUser.Name url = targetUser.Link @@ -112,7 +113,7 @@ func BuildAlert(asid int, event string, elementType string, actorID int, targetU case "post": topic, err := TopicByReplyID(elementID) if err != nil { - return "", errors.New(GetErrorPhrase("alerts_no_linked_topic_by_reply")) + return "", errors.New(phrases.GetErrorPhrase("alerts_no_linked_topic_by_reply")) } url = topic.Link area = topic.Title @@ -120,7 +121,7 @@ func BuildAlert(asid int, event string, elementType string, actorID int, targetU phraseName += "_own" } default: - return "", errors.New(GetErrorPhrase("alerts_invalid_elementtype")) + return "", errors.New(phrases.GetErrorPhrase("alerts_invalid_elementtype")) } switch event { @@ -132,7 +133,7 @@ func BuildAlert(asid int, event string, elementType string, actorID int, targetU phraseName += "_reply" } - return buildAlertString(GetTmplPhrase(phraseName), []string{actor.Name, area}, url, actor.Avatar, asid), nil + return buildAlertString(phrases.GetTmplPhrase(phraseName), []string{actor.Name, area}, url, actor.Avatar, asid), nil } func buildAlertString(msg string, sub []string, path string, avatar string, asid int) string { diff --git a/common/errors.go b/common/errors.go index 1770beae..95b96bd9 100644 --- a/common/errors.go +++ b/common/errors.go @@ -6,6 +6,8 @@ import ( "runtime/debug" "strings" "sync" + + "github.com/Azareal/Gosora/common/phrases" ) type ErrorItem struct { @@ -101,7 +103,7 @@ func errorHeader(w http.ResponseWriter, user User, title string) *Header { // ? - Add a user parameter? func InternalError(err error, w http.ResponseWriter, r *http.Request) RouteError { w.WriteHeader(500) - pi := ErrorPage{errorHeader(w, GuestUser, GetErrorPhrase("internal_error_title")), GetErrorPhrase("internal_error_body")} + pi := ErrorPage{errorHeader(w, GuestUser, phrases.GetErrorPhrase("internal_error_title")), phrases.GetErrorPhrase("internal_error_body")} handleErrorTemplate(w, r, pi) LogError(err) return HandledRouteError() @@ -120,7 +122,7 @@ func InternalErrorJSQ(err error, w http.ResponseWriter, r *http.Request, isJs bo // ? - Add a user parameter? func InternalErrorJS(err error, w http.ResponseWriter, r *http.Request) RouteError { w.WriteHeader(500) - writeJsonError(GetErrorPhrase("internal_error_body"), w) + writeJsonError(phrases.GetErrorPhrase("internal_error_body"), w) LogError(err) return HandledRouteError() } @@ -128,7 +130,7 @@ func InternalErrorJS(err error, w http.ResponseWriter, r *http.Request) RouteErr // When the task system detects if the database is down, some database errors might lip by this func DatabaseError(w http.ResponseWriter, r *http.Request) RouteError { w.WriteHeader(500) - pi := ErrorPage{errorHeader(w, GuestUser, GetErrorPhrase("internal_error_title")), GetErrorPhrase("internal_error_body")} + pi := ErrorPage{errorHeader(w, GuestUser, phrases.GetErrorPhrase("internal_error_title")), phrases.GetErrorPhrase("internal_error_body")} handleErrorTemplate(w, r, pi) return HandledRouteError() } @@ -137,7 +139,7 @@ func InternalErrorXML(err error, w http.ResponseWriter, r *http.Request) RouteEr w.Header().Set("Content-Type", "application/xml") w.WriteHeader(500) w.Write([]byte(` -` + GetErrorPhrase("internal_error_body") + ``)) +` + phrases.GetErrorPhrase("internal_error_body") + ``)) LogError(err) return HandledRouteError() } @@ -147,14 +149,14 @@ func SilentInternalErrorXML(err error, w http.ResponseWriter, r *http.Request) R w.Header().Set("Content-Type", "application/xml") w.WriteHeader(500) w.Write([]byte(` -` + GetErrorPhrase("internal_error_body") + ``)) +` + phrases.GetErrorPhrase("internal_error_body") + ``)) log.Print("InternalError: ", err) return HandledRouteError() } func PreError(errmsg string, w http.ResponseWriter, r *http.Request) RouteError { w.WriteHeader(500) - pi := ErrorPage{errorHeader(w, GuestUser, GetErrorPhrase("error_title")), errmsg} + pi := ErrorPage{errorHeader(w, GuestUser, phrases.GetErrorPhrase("error_title")), errmsg} handleErrorTemplate(w, r, pi) return HandledRouteError() } @@ -176,7 +178,7 @@ func PreErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, isJs boo // TODO: Pass header in for this and similar errors instead of having to pass in both user and w? Would also allow for more stateful things, although this could be a problem func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user User) RouteError { w.WriteHeader(500) - pi := ErrorPage{errorHeader(w, user, GetErrorPhrase("local_error_title")), errmsg} + pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("local_error_title")), errmsg} handleErrorTemplate(w, r, pi) return HandledRouteError() } @@ -198,7 +200,7 @@ func LocalErrorJS(errmsg string, w http.ResponseWriter, r *http.Request) RouteEr // NoPermissions is an error shown to the end-user when they try to access an area which they aren't authorised to access func NoPermissions(w http.ResponseWriter, r *http.Request, user User) RouteError { w.WriteHeader(403) - pi := ErrorPage{errorHeader(w, user, GetErrorPhrase("no_permissions_title")), GetErrorPhrase("no_permissions_body")} + pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("no_permissions_title")), phrases.GetErrorPhrase("no_permissions_body")} handleErrorTemplate(w, r, pi) return HandledRouteError() } @@ -212,14 +214,14 @@ func NoPermissionsJSQ(w http.ResponseWriter, r *http.Request, user User, isJs bo func NoPermissionsJS(w http.ResponseWriter, r *http.Request, user User) RouteError { w.WriteHeader(403) - writeJsonError(GetErrorPhrase("no_permissions_body"), w) + writeJsonError(phrases.GetErrorPhrase("no_permissions_body"), w) return HandledRouteError() } // ? - Is this actually used? Should it be used? A ban in Gosora should be more of a permission revocation to stop them posting rather than something which spits up an error page, right? func Banned(w http.ResponseWriter, r *http.Request, user User) RouteError { w.WriteHeader(403) - pi := ErrorPage{errorHeader(w, user, GetErrorPhrase("banned_title")), GetErrorPhrase("banned_body")} + pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("banned_title")), phrases.GetErrorPhrase("banned_body")} handleErrorTemplate(w, r, pi) return HandledRouteError() } @@ -235,7 +237,7 @@ func BannedJSQ(w http.ResponseWriter, r *http.Request, user User, isJs bool) Rou func BannedJS(w http.ResponseWriter, r *http.Request, user User) RouteError { w.WriteHeader(403) - writeJsonError(GetErrorPhrase("banned_body"), w) + writeJsonError(phrases.GetErrorPhrase("banned_body"), w) return HandledRouteError() } @@ -251,7 +253,7 @@ func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user User, isJs bo // LoginRequired is an error shown to the end-user when they try to access an area which requires them to login func LoginRequired(w http.ResponseWriter, r *http.Request, user User) RouteError { w.WriteHeader(401) - pi := ErrorPage{errorHeader(w, user, GetErrorPhrase("no_permissions_title")), GetErrorPhrase("login_required_body")} + pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("no_permissions_title")), phrases.GetErrorPhrase("login_required_body")} handleErrorTemplate(w, r, pi) return HandledRouteError() } @@ -259,7 +261,7 @@ func LoginRequired(w http.ResponseWriter, r *http.Request, user User) RouteError // nolint func LoginRequiredJS(w http.ResponseWriter, r *http.Request, user User) RouteError { w.WriteHeader(401) - writeJsonError(GetErrorPhrase("login_required_body"), w) + writeJsonError(phrases.GetErrorPhrase("login_required_body"), w) return HandledRouteError() } @@ -267,7 +269,7 @@ func LoginRequiredJS(w http.ResponseWriter, r *http.Request, user User) RouteErr // ? - Should we add JS and JSQ versions of this? func SecurityError(w http.ResponseWriter, r *http.Request, user User) RouteError { w.WriteHeader(403) - pi := ErrorPage{errorHeader(w, user, GetErrorPhrase("security_error_title")), GetErrorPhrase("security_error_body")} + pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("security_error_title")), phrases.GetErrorPhrase("security_error_body")} if RunPreRenderHook("pre_render_security_error", w, r, &user, &pi) { return nil } @@ -282,7 +284,7 @@ func SecurityError(w http.ResponseWriter, r *http.Request, user User) RouteError // ? - Add a JSQ and JS version of this? // ? - Add a user parameter? func NotFound(w http.ResponseWriter, r *http.Request, header *Header) RouteError { - return CustomError(GetErrorPhrase("not_found_body"), 404, GetErrorPhrase("not_found_title"), w, r, header, GuestUser) + return CustomError(phrases.GetErrorPhrase("not_found_body"), 404, phrases.GetErrorPhrase("not_found_title"), w, r, header, GuestUser) } // CustomError lets us make custom error types which aren't covered by the generic functions above diff --git a/common/menus.go b/common/menus.go index 2da40530..8e312b7c 100644 --- a/common/menus.go +++ b/common/menus.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/Azareal/Gosora/query_gen" + "github.com/Azareal/Gosora/common/phrases" ) type MenuItemList []MenuItem @@ -346,7 +347,7 @@ func (hold *MenuListHolder) ScanItem(menuTmpls map[string]MenuTmpl, mitem MenuIt } if bytes.Equal(variable[:dotAt], []byte("lang")) { - renderBuffer = append(renderBuffer, []byte(GetTmplPhrase(string(bytes.TrimPrefix(variable[dotAt:], []byte(".")))))) + renderBuffer = append(renderBuffer, []byte(phrases.GetTmplPhrase(string(bytes.TrimPrefix(variable[dotAt:], []byte(".")))))) continue } @@ -385,7 +386,7 @@ func (hold *MenuListHolder) ScanItem(menuTmpls map[string]MenuTmpl, mitem MenuIt if bytes.Equal(renderItem[1:dotAt], []byte("lang")) { //fmt.Println("lang var: ", string(renderItem[dotAt+1:endFence])) - renderBuffer = append(renderBuffer, []byte(GetTmplPhrase(string(renderItem[dotAt+1:endFence])))) + renderBuffer = append(renderBuffer, []byte(phrases.GetTmplPhrase(string(renderItem[dotAt+1:endFence])))) } else { fmt.Println("other var: ", string(variable[:dotAt])) if len(renderItem) > 0 { diff --git a/common/pages.go b/common/pages.go index 72e0d5af..c771caa2 100644 --- a/common/pages.go +++ b/common/pages.go @@ -6,6 +6,8 @@ import ( "runtime" "sync" "time" + + "github.com/Azareal/Gosora/common/phrases" ) // TODO: Allow resources in spots other than /static/ and possibly even external domains (e.g. CDNs) @@ -44,7 +46,7 @@ func (header *Header) AddSheet(name string) { } func (header *Header) AddNotice(name string) { - header.NoticeList = append(header.NoticeList, GetNoticePhrase(name)) + header.NoticeList = append(header.NoticeList, phrases.GetNoticePhrase(name)) } // TODO: Add this to routes which don't use templates. E.g. Json APIs. diff --git a/common/permissions.go b/common/permissions.go index 2f82a08e..8be8db56 100644 --- a/common/permissions.go +++ b/common/permissions.go @@ -5,6 +5,7 @@ import ( "log" "github.com/Azareal/Gosora/query_gen" + "github.com/Azareal/Gosora/common/phrases" ) // TODO: Refactor the perms system @@ -158,7 +159,7 @@ func StripInvalidPreset(preset string) string { // TODO: Move this into the phrase system? func PresetToLang(preset string) string { - phrases := GetAllPermPresets() + phrases := phrases.GetAllPermPresets() phrase, ok := phrases[preset] if !ok { phrase = phrases["unknown"] diff --git a/common/phrases.go b/common/phrases/phrases.go similarity index 91% rename from common/phrases.go rename to common/phrases/phrases.go index 926754d1..f8e502de 100644 --- a/common/phrases.go +++ b/common/phrases/phrases.go @@ -4,7 +4,7 @@ * Copyright Azareal 2017 - 2019 * */ -package common +package phrases import ( "encoding/json" @@ -61,7 +61,7 @@ type LanguagePack struct { var langPacks sync.Map // nolint it is used var langTmplIndicesToNames [][]string // [tmplID][index]phraseName -func InitPhrases() error { +func InitPhrases(lang string) error { log.Print("Loading the language packs") err := filepath.Walk("./langs", func(path string, f os.FileInfo, err error) error { if f.IsDir() { @@ -122,9 +122,9 @@ func InitPhrases() error { return errors.New("You don't have any language packs") } - langPack, ok := langPacks.Load(Site.Language) + langPack, ok := langPacks.Load(lang) if !ok { - return errors.New("Couldn't find the " + Site.Language + " language pack") + return errors.New("Couldn't find the " + lang + " language pack") } currentLangPack.Store(langPack) return nil @@ -154,14 +154,14 @@ func GetLevelPhrase(level int) string { func GetGlobalPermPhrase(name string) string { res, ok := currentLangPack.Load().(*LanguagePack).GlobalPerms[name] if !ok { - return getPhrasePlaceholder("perms", name) + return getPlaceholder("perms", name) } return res } func GetLocalPermPhrase(name string) string { res, ok := currentLangPack.Load().(*LanguagePack).LocalPerms[name] if !ok { - return getPhrasePlaceholder("perms", name) + return getPlaceholder("perms", name) } return res } @@ -169,7 +169,7 @@ func GetLocalPermPhrase(name string) string { func GetSettingPhrase(name string) string { res, ok := currentLangPack.Load().(*LanguagePack).SettingPhrases[name] if !ok { - return getPhrasePlaceholder("settings", name) + return getPlaceholder("settings", name) } return res } @@ -185,7 +185,7 @@ func GetAllPermPresets() map[string]string { func GetAccountPhrase(name string) string { res, ok := currentLangPack.Load().(*LanguagePack).Accounts[name] if !ok { - return getPhrasePlaceholder("account", name) + return getPlaceholder("account", name) } return res } @@ -209,7 +209,7 @@ func GetOSPhrase(name string) (string, bool) { func GetHumanLangPhrase(name string) (string, bool) { res, ok := currentLangPack.Load().(*LanguagePack).HumanLanguages[name] if !ok { - return getPhrasePlaceholder("humanlang", name), false + return getPlaceholder("humanlang", name), false } return res, true } @@ -218,7 +218,7 @@ func GetHumanLangPhrase(name string) (string, bool) { func GetErrorPhrase(name string) string { res, ok := currentLangPack.Load().(*LanguagePack).Errors[name] if !ok { - return getPhrasePlaceholder("error", name) + return getPlaceholder("error", name) } return res } @@ -226,7 +226,7 @@ func GetErrorPhrase(name string) string { func GetNoticePhrase(name string) string { res, ok := currentLangPack.Load().(*LanguagePack).NoticePhrases[name] if !ok { - return getPhrasePlaceholder("notices", name) + return getPlaceholder("notices", name) } return res } @@ -234,7 +234,7 @@ func GetNoticePhrase(name string) string { func GetTitlePhrase(name string) string { res, ok := currentLangPack.Load().(*LanguagePack).PageTitles[name] if !ok { - return getPhrasePlaceholder("title", name) + return getPlaceholder("title", name) } return res } @@ -242,7 +242,7 @@ func GetTitlePhrase(name string) string { func GetTitlePhrasef(name string, params ...interface{}) string { res, ok := currentLangPack.Load().(*LanguagePack).PageTitles[name] if !ok { - return getPhrasePlaceholder("title", name) + return getPlaceholder("title", name) } return fmt.Sprintf(res, params...) } @@ -250,7 +250,7 @@ func GetTitlePhrasef(name string, params ...interface{}) string { func GetTmplPhrase(name string) string { res, ok := currentLangPack.Load().(*LanguagePack).TmplPhrases[name] if !ok { - return getPhrasePlaceholder("tmpl", name) + return getPlaceholder("tmpl", name) } return res } @@ -258,7 +258,7 @@ func GetTmplPhrase(name string) string { func GetTmplPhrasef(name string, params ...interface{}) string { res, ok := currentLangPack.Load().(*LanguagePack).TmplPhrases[name] if !ok { - return getPhrasePlaceholder("tmpl", name) + return getPlaceholder("tmpl", name) } return fmt.Sprintf(res, params...) } @@ -272,7 +272,7 @@ func GetTmplPhrasesByPrefix(prefix string) (phrases map[string]string, ok bool) return res, ok } -func getPhrasePlaceholder(prefix string, suffix string) string { +func getPlaceholder(prefix string, suffix string) string { return "{lang." + prefix + "[" + suffix + "]}" } diff --git a/common/template_init.go b/common/template_init.go index fca76cc5..77f702f3 100644 --- a/common/template_init.go +++ b/common/template_init.go @@ -13,6 +13,7 @@ import ( "github.com/Azareal/Gosora/common/alerts" "github.com/Azareal/Gosora/common/templates" + "github.com/Azareal/Gosora/common/phrases" ) var Ctemplates []string @@ -532,7 +533,7 @@ func InitTemplates() error { panic("phraseNameInt is not a string") } // TODO: Log non-existent phrases? - return template.HTML(GetTmplPhrase(phraseName)) + return template.HTML(phrases.GetTmplPhrase(phraseName)) } fmap["level"] = func(levelInt interface{}) interface{} { @@ -540,7 +541,7 @@ func InitTemplates() error { if !ok { panic("levelInt is not an integer") } - return template.HTML(GetLevelPhrase(level)) + return template.HTML(phrases.GetLevelPhrase(level)) } fmap["scope"] = func(name interface{}) interface{} { diff --git a/common/templates/templates.go b/common/templates/templates.go index 79e2e1a2..8d547865 100644 --- a/common/templates/templates.go +++ b/common/templates/templates.go @@ -14,6 +14,8 @@ import ( // TODO: Turn this file into a library var textOverlapList = make(map[string]int) +// TODO: Stop hard-coding this here +var langPkg = "github.com/Azareal/Gosora/common/phrases" type VarItem struct { Name string @@ -177,6 +179,10 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe out += c.rootIterate(c.templateList[fname], varholder, holdreflect, fname) c.TemplateFragmentCount[fname] = c.fragmentCursor[fname] + 1 + if len(c.langIndexToName) > 0 { + c.importMap[langPkg] = langPkg + } + var importList string for _, item := range c.importMap { importList += "import \"" + item + "\"\n" @@ -211,7 +217,7 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe fout += "\tcommon.TmplPtrMap[\"o_" + fname + "\"] = Template_" + fname + "\n" } if len(c.langIndexToName) > 0 { - fout += "\t" + fname + "_tmpl_phrase_id = common.RegisterTmplPhraseNames([]string{\n" + fout += "\t" + fname + "_tmpl_phrase_id = phrases.RegisterTmplPhraseNames([]string{\n" for _, name := range c.langIndexToName { fout += "\t\t" + `"` + name + `"` + ",\n" } @@ -222,7 +228,7 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe fout += "// nolint\nfunc Template_" + fname + "(tmpl_" + fname + "_vars " + expects + ", w io.Writer) error {\n" if len(c.langIndexToName) > 0 { - fout += "var phrases = common.GetTmplPhrasesBytes(" + fname + "_tmpl_phrase_id)\n" + fout += "var plist = phrases.GetTmplPhrasesBytes(" + fname + "_tmpl_phrase_id)\n" } fout += varString + out + "return nil\n}\n" @@ -714,7 +720,7 @@ ArgLoop: } c.langIndexToName = append(c.langIndexToName, leftParam) - out = "w.Write(phrases[" + strconv.Itoa(len(c.langIndexToName)-1) + "])\n" + out = "w.Write(plist[" + strconv.Itoa(len(c.langIndexToName)-1) + "])\n" literal = true break ArgLoop case "level": @@ -727,8 +733,9 @@ ArgLoop: leftParam, _ = c.compileIfVarsub(leftOperand, varholder, templateName, holdreflect) // TODO: Refactor this - out = "w.Write([]byte(common.GetLevelPhrase(" + leftParam + ")))\n" + out = "w.Write([]byte(phrases.GetLevelPhrase(" + leftParam + ")))\n" literal = true + c.importMap[langPkg] = langPkg break ArgLoop case "scope": literal = true diff --git a/common/theme.go b/common/theme.go index 569f1e9e..ac05a828 100644 --- a/common/theme.go +++ b/common/theme.go @@ -14,6 +14,8 @@ import ( "path/filepath" "strings" "text/template" + + "github.com/Azareal/Gosora/common/phrases" ) var ErrNoDefaultTheme = errors.New("The default theme isn't registered in the system") @@ -82,7 +84,7 @@ func (theme *Theme) LoadStaticFiles() error { } func (theme *Theme) AddThemeStaticFiles() error { - phraseMap := GetTmplPhrases() + phraseMap := phrases.GetTmplPhrases() // TODO: Use a function instead of a closure to make this more testable? What about a function call inside the closure to take the theme variable into account? return filepath.Walk("./themes/"+theme.Name+"/public", func(path string, f os.FileInfo, err error) error { DebugLog("Attempting to add static file '" + path + "' for default theme '" + theme.Name + "'") diff --git a/common/websockets.go b/common/websockets.go index b5d6995d..686cdc54 100644 --- a/common/websockets.go +++ b/common/websockets.go @@ -21,6 +21,7 @@ import ( "github.com/Azareal/gopsutil/cpu" "github.com/Azareal/gopsutil/mem" "github.com/gorilla/websocket" + "github.com/Azareal/Gosora/common/phrases" ) // TODO: Disable WebSockets on high load? Add a Control Panel interface for disabling it? @@ -288,9 +289,9 @@ AdminStatLoop: // nolint // TODO: Use JSON for this to make things more portable and easier to convert to MessagePack, if need be? if !noStatUpdates { - w.Write([]byte("set #dash-totonline " + GetTmplPhrasef("panel_dashboard_online", totonline, totunit) + "\r")) - w.Write([]byte("set #dash-gonline " + GetTmplPhrasef("panel_dashboard_guests_online", gonline, gunit) + "\r")) - w.Write([]byte("set #dash-uonline " + GetTmplPhrasef("panel_dashboard_users_online", uonline, uunit) + "\r")) + w.Write([]byte("set #dash-totonline " + phrases.GetTmplPhrasef("panel_dashboard_online", totonline, totunit) + "\r")) + w.Write([]byte("set #dash-gonline " + phrases.GetTmplPhrasef("panel_dashboard_guests_online", gonline, gunit) + "\r")) + w.Write([]byte("set #dash-uonline " + phrases.GetTmplPhrasef("panel_dashboard_users_online", uonline, uunit) + "\r")) w.Write([]byte("set #dash-reqs " + strconv.Itoa(reqCount) + " reqs / second\r")) w.Write([]byte("set-class #dash-totonline grid_item grid_stat " + onlineColour + "\r")) diff --git a/general_test.go b/general_test.go index 361f38f5..c0c63133 100644 --- a/general_test.go +++ b/general_test.go @@ -17,7 +17,6 @@ import ( "github.com/Azareal/Gosora/install" "github.com/Azareal/Gosora/query_gen" "github.com/Azareal/Gosora/routes" - //"github.com/husobee/vestigo" ) //var dbTest *sql.DB @@ -111,12 +110,7 @@ func init() { // TODO: Swap out LocalError for a panic for this? func BenchmarkTopicAdminRouteParallel(b *testing.B) { - b.ReportAllocs() - err := gloinit() - if err != nil { - b.Fatal(err) - } - + binit(b) prev := common.Dev.DebugMode prev2 := common.Dev.SuperDebug common.Dev.DebugMode = false @@ -158,13 +152,8 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) { } func BenchmarkTopicAdminRouteParallelWithRouter(b *testing.B) { - b.ReportAllocs() - err := gloinit() - if err != nil { - b.Fatal(err) - } - - router, err = NewGenRouter(http.FileServer(http.Dir("./uploads"))) + binit(b) + router, err := NewGenRouter(http.FileServer(http.Dir("./uploads"))) if err != nil { b.Fatal(err) } @@ -218,12 +207,7 @@ func BenchmarkTopicAdminRouteParallelAltAlt(b *testing.B) { } func BenchmarkTopicGuestRouteParallel(b *testing.B) { - b.ReportAllocs() - err := gloinit() - if err != nil { - b.Fatal(err) - } - + binit(b) prev := common.Dev.DebugMode prev2 := common.Dev.SuperDebug common.Dev.DebugMode = false @@ -247,12 +231,7 @@ func BenchmarkTopicGuestRouteParallel(b *testing.B) { } func BenchmarkTopicGuestRouteParallelDebugMode(b *testing.B) { - b.ReportAllocs() - err := gloinit() - if err != nil { - b.Fatal(err) - } - + binit(b) prev := common.Dev.DebugMode prev2 := common.Dev.SuperDebug common.Dev.DebugMode = true @@ -276,13 +255,8 @@ func BenchmarkTopicGuestRouteParallelDebugMode(b *testing.B) { } func BenchmarkTopicGuestRouteParallelWithRouter(b *testing.B) { - b.ReportAllocs() - err := gloinit() - if err != nil { - b.Fatal(err) - } - - router, err = NewGenRouter(http.FileServer(http.Dir("./uploads"))) + binit(b) + router, err := NewGenRouter(http.FileServer(http.Dir("./uploads"))) if err != nil { b.Fatal(err) } @@ -319,13 +293,8 @@ func BenchmarkTopicGuestRouteParallelWithRouter(b *testing.B) { } func BenchmarkBadRouteGuestRouteParallelWithRouter(b *testing.B) { - b.ReportAllocs() - err := gloinit() - if err != nil { - b.Fatal(err) - } - - router, err = NewGenRouter(http.FileServer(http.Dir("./uploads"))) + binit(b) + router, err := NewGenRouter(http.FileServer(http.Dir("./uploads"))) if err != nil { b.Fatal(err) } @@ -349,96 +318,60 @@ func BenchmarkBadRouteGuestRouteParallelWithRouter(b *testing.B) { common.Dev.SuperDebug = prev2 } -func BenchmarkTopicsGuestRouteParallelWithRouter(b *testing.B) { - b.ReportAllocs() - err := gloinit() - if err != nil { - b.Fatal(err) - } - - router, err = NewGenRouter(http.FileServer(http.Dir("./uploads"))) - if err != nil { - b.Fatal(err) - } - prev := common.Dev.DebugMode - prev2 := common.Dev.SuperDebug +func obRoute(b *testing.B,path string) { + binit(b) + cfg := NewStashConfig() common.Dev.DebugMode = false common.Dev.SuperDebug = false + b.RunParallel(benchRoute(b,path)) + cfg.Restore() +} - b.RunParallel(func(pb *testing.PB) { - for pb.Next() { - listW := httptest.NewRecorder() - listReq := httptest.NewRequest("GET", "/topics/", bytes.NewReader(nil)) - listReq.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36") - listReq.Header.Set("Host", "localhost") - listReq.Host = "localhost" - router.ServeHTTP(listW, listReq) - if listW.Code != 200 { - b.Log(listW.Body) - b.Fatal("HTTP Error!") - } - } - }) - - common.Dev.DebugMode = prev - common.Dev.SuperDebug = prev2 +func BenchmarkTopicsGuestRouteParallelWithRouter(b *testing.B) { + obRoute(b,"/topics/") } func BenchmarkForumsGuestRouteParallelWithRouter(b *testing.B) { - b.ReportAllocs() - err := gloinit() - if err != nil { - b.Fatal(err) - } - - router, err = NewGenRouter(http.FileServer(http.Dir("./uploads"))) - if err != nil { - b.Fatal(err) - } - prev := common.Dev.DebugMode - prev2 := common.Dev.SuperDebug - common.Dev.DebugMode = false - common.Dev.SuperDebug = false - - b.RunParallel(func(pb *testing.PB) { - for pb.Next() { - listW := httptest.NewRecorder() - listReq := httptest.NewRequest("GET", "/forums/", bytes.NewReader(nil)) - listReq.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36") - listReq.Header.Set("Host", "localhost") - listReq.Host = "localhost" - router.ServeHTTP(listW, listReq) - if listW.Code != 200 { - b.Log(listW.Body) - b.Fatal("HTTP Error!") - } - } - }) - - common.Dev.DebugMode = prev - common.Dev.SuperDebug = prev2 + obRoute(b,"/forums/") } func BenchmarkForumGuestRouteParallelWithRouter(b *testing.B) { + obRoute(b,"/forum/general.2") +} + +func binit(b *testing.B) { b.ReportAllocs() err := gloinit() if err != nil { b.Fatal(err) } +} - router, err = NewGenRouter(http.FileServer(http.Dir("./uploads"))) +type StashConfig struct { + prev bool + prev2 bool +} + +func NewStashConfig() *StashConfig { + prev := common.Dev.DebugMode + prev2 := common.Dev.SuperDebug + return &StashConfig{prev,prev2} +} + +func (cfg *StashConfig) Restore() { + common.Dev.DebugMode = cfg.prev + common.Dev.SuperDebug = cfg.prev2 +} + +func benchRoute(b *testing.B, path string) func(*testing.PB) { + router, err := NewGenRouter(http.FileServer(http.Dir("./uploads"))) if err != nil { b.Fatal(err) } - prev := common.Dev.DebugMode - prev2 := common.Dev.SuperDebug - common.Dev.DebugMode = false - common.Dev.SuperDebug = false - - b.RunParallel(func(pb *testing.PB) { + return func(pb *testing.PB) { for pb.Next() { listW := httptest.NewRecorder() - listReq := httptest.NewRequest("GET", "/forum/general.2", bytes.NewReader(nil)) + listReq := httptest.NewRequest("GET", path, bytes.NewReader(nil)) listReq.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36") listReq.Header.Set("Host", "localhost") listReq.Host = "localhost" @@ -448,10 +381,11 @@ func BenchmarkForumGuestRouteParallelWithRouter(b *testing.B) { b.Fatal("HTTP Error!") } } - }) + } +} - common.Dev.DebugMode = prev - common.Dev.SuperDebug = prev2 +func BenchmarkProfileGuestRouteParallelWithRouter(b *testing.B) { + obRoute(b,"/profile/admin.1") } // TODO: Make these routes compatible with the changes to the router @@ -459,7 +393,6 @@ func BenchmarkForumGuestRouteParallelWithRouter(b *testing.B) { func BenchmarkForumsAdminRouteParallel(b *testing.B) { b.ReportAllocs() gloinit() - b.RunParallel(func(pb *testing.PB) { admin, err := users.Get(1) if err != nil { @@ -473,9 +406,9 @@ func BenchmarkForumsAdminRouteParallel(b *testing.B) { forumsW := httptest.NewRecorder() forumsReq := httptest.NewRequest("get","/forums/",bytes.NewReader(nil)) - forumsReq_admin := forums_req - forumsReq_admin.AddCookie(&adminUidCookie) - forumsReq_admin.AddCookie(&adminSessionCookie) + forumsReqAdmin := forums_req + forumsReqAdmin.AddCookie(&adminUidCookie) + forumsReqAdmin.AddCookie(&adminSessionCookie) forumsHandler := http.HandlerFunc(route_forums) for pb.Next() { diff --git a/main.go b/main.go index 51b6917c..c9697126 100644 --- a/main.go +++ b/main.go @@ -23,6 +23,7 @@ import ( "github.com/Azareal/Gosora/common" "github.com/Azareal/Gosora/common/counters" + "github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/routes" "github.com/Azareal/Gosora/query_gen" "github.com/fsnotify/fsnotify" @@ -56,7 +57,7 @@ func afterDBInit() (err error) { if err != nil { return errors.WithStack(err) } - err = common.InitPhrases() + err = phrases.InitPhrases(common.Site.Language) if err != nil { return errors.WithStack(err) } @@ -229,7 +230,7 @@ func main() { // TODO: Add a flag for enabling the profiler if false { - f, err := os.Create("./logs/cpuprof.prof") + f, err := os.Create("./logs/cpu.prof") if err != nil { log.Fatal(err) } @@ -421,6 +422,14 @@ func main() { // Start up the WebSocket ticks common.WsHub.Start() + if false { + f, err := os.Create("./logs/cpu.prof") + if err != nil { + log.Fatal(err) + } + pprof.StartCPUProfile(f) + } + //if profiling { // pprof.StopCPUProfile() //} diff --git a/misc_test.go b/misc_test.go index 0d70ae0c..0978614e 100644 --- a/misc_test.go +++ b/misc_test.go @@ -10,8 +10,16 @@ import ( "time" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" ) +func miscinit(t *testing.T) { + err := gloinit() + if err != nil { + t.Fatal(err) + } +} + func recordMustExist(t *testing.T, err error, errmsg string, args ...interface{}) { if err == ErrNoRows { debug.PrintStack() @@ -33,12 +41,7 @@ func recordMustNotExist(t *testing.T, err error, errmsg string, args ...interfac } func TestUserStore(t *testing.T) { - if !gloinited { - err := gloinit() - if err != nil { - t.Fatal(err) - } - } + miscinit(t) if !common.PluginsInited { common.InitPlugins() } @@ -344,12 +347,7 @@ func expect(t *testing.T, item bool, errmsg string) { } func TestPermsMiddleware(t *testing.T) { - if !gloinited { - err := gloinit() - if err != nil { - t.Fatal(err) - } - } + miscinit(t) if !common.PluginsInited { common.InitPlugins() } @@ -410,12 +408,7 @@ func TestPermsMiddleware(t *testing.T) { } func TestTopicStore(t *testing.T) { - if !gloinited { - err := gloinit() - if err != nil { - t.Fatal(err) - } - } + miscinit(t) if !common.PluginsInited { common.InitPlugins() } @@ -531,9 +524,7 @@ func topicStoreTest(t *testing.T, newID int) { } func TestForumStore(t *testing.T) { - if !gloinited { - gloinit() - } + miscinit(t) if !common.PluginsInited { common.InitPlugins() } @@ -593,9 +584,7 @@ func TestForumStore(t *testing.T) { // TODO: Implement this func TestForumPermsStore(t *testing.T) { - if !gloinited { - gloinit() - } + miscinit(t) if !common.PluginsInited { common.InitPlugins() } @@ -603,9 +592,7 @@ func TestForumPermsStore(t *testing.T) { // TODO: Test the group permissions func TestGroupStore(t *testing.T) { - if !gloinited { - gloinit() - } + miscinit(t) if !common.PluginsInited { common.InitPlugins() } @@ -704,9 +691,7 @@ func TestGroupStore(t *testing.T) { } func TestReplyStore(t *testing.T) { - if !gloinited { - gloinit() - } + miscinit(t) if !common.PluginsInited { common.InitPlugins() } @@ -759,9 +744,7 @@ func TestReplyStore(t *testing.T) { } func TestProfileReplyStore(t *testing.T) { - if !gloinited { - gloinit() - } + miscinit(t) if !common.PluginsInited { common.InitPlugins() } @@ -800,10 +783,7 @@ func TestProfileReplyStore(t *testing.T) { } func TestLogs(t *testing.T) { - if !gloinited { - gloinit() - } - + miscinit(t) gTests := func(store common.LogStore, phrase string) { expect(t, store.GlobalCount() == 0, "There shouldn't be any "+phrase) logs, err := store.GetOffset(0, 25) @@ -837,9 +817,7 @@ func TestLogs(t *testing.T) { // TODO: Add tests for registration logs func TestPluginManager(t *testing.T) { - if !gloinited { - gloinit() - } + miscinit(t) if !common.PluginsInited { common.InitPlugins() } @@ -989,10 +967,10 @@ func TestPluginManager(t *testing.T) { } func TestPhrases(t *testing.T) { - expect(t, common.GetGlobalPermPhrase("BanUsers") == "Can ban users", "Not the expected phrase") - expect(t, common.GetGlobalPermPhrase("NoSuchPerm") == "{lang.perms[NoSuchPerm]}", "Not the expected phrase") - expect(t, common.GetLocalPermPhrase("ViewTopic") == "Can view topics", "Not the expected phrase") - expect(t, common.GetLocalPermPhrase("NoSuchPerm") == "{lang.perms[NoSuchPerm]}", "Not the expected phrase") + expect(t, phrases.GetGlobalPermPhrase("BanUsers") == "Can ban users", "Not the expected phrase") + expect(t, phrases.GetGlobalPermPhrase("NoSuchPerm") == "{lang.perms[NoSuchPerm]}", "Not the expected phrase") + expect(t, phrases.GetLocalPermPhrase("ViewTopic") == "Can view topics", "Not the expected phrase") + expect(t, phrases.GetLocalPermPhrase("NoSuchPerm") == "{lang.perms[NoSuchPerm]}", "Not the expected phrase") // TODO: Cover the other phrase types, also try switching between languages to see if anything strange happens } diff --git a/routes.go b/routes.go index 3f967386..0b2aa3de 100644 --- a/routes.go +++ b/routes.go @@ -16,6 +16,7 @@ import ( "unicode" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" ) // A blank list to fill out that parameter in Page for routes which don't use it @@ -157,21 +158,21 @@ func routeAPIPhrases(w http.ResponseWriter, r *http.Request, user common.User) c return common.PreErrorJS("You haven't requested any phrases", w, r) } - var phrases map[string]string + var plist map[string]string // A little optimisation to avoid copying entries from one map to the other, if we don't have to mutate it if len(positives) > 1 { - phrases = make(map[string]string) + plist = make(map[string]string) for _, positive := range positives { // ! Constrain it to topic and status phrases for now if !strings.HasPrefix(positive, "topic") && !strings.HasPrefix(positive, "status") && !strings.HasPrefix(positive, "alerts") { return common.PreErrorJS("Not implemented!", w, r) } - pPhrases, ok := common.GetTmplPhrasesByPrefix(positive) + pPhrases, ok := phrases.GetTmplPhrasesByPrefix(positive) if !ok { return common.PreErrorJS("No such prefix", w, r) } for name, phrase := range pPhrases { - phrases[name] = phrase + plist[name] = phrase } } } else { @@ -179,23 +180,23 @@ func routeAPIPhrases(w http.ResponseWriter, r *http.Request, user common.User) c if !strings.HasPrefix(positives[0], "topic") && !strings.HasPrefix(positives[0], "status") && !strings.HasPrefix(positives[0], "alerts") { return common.PreErrorJS("Not implemented!", w, r) } - pPhrases, ok := common.GetTmplPhrasesByPrefix(positives[0]) + pPhrases, ok := phrases.GetTmplPhrasesByPrefix(positives[0]) if !ok { return common.PreErrorJS("No such prefix", w, r) } - phrases = pPhrases + plist = pPhrases } for _, negation := range negations { - for name, _ := range phrases { + for name, _ := range plist { if strings.HasPrefix(name, negation) { - delete(phrases, name) + delete(plist, name) } } } // TODO: Cache the output of this, especially for things like topic, so we don't have to waste more time than we need on this - jsonBytes, err := json.Marshal(phrases) + jsonBytes, err := json.Marshal(plist) if err != nil { return common.InternalError(err, w, r) } diff --git a/routes/account.go b/routes/account.go index 91727704..812c89f2 100644 --- a/routes/account.go +++ b/routes/account.go @@ -16,6 +16,7 @@ import ( "github.com/Azareal/Gosora/common" "github.com/Azareal/Gosora/query_gen" + "github.com/Azareal/Gosora/common/phrases" ) // A blank list to fill out that parameter in Page for routes which don't use it @@ -29,7 +30,7 @@ func AccountLogin(w http.ResponseWriter, r *http.Request, user common.User) comm if user.Loggedin { return common.LocalError("You're already logged in.", w, r, user) } - header.Title = common.GetTitlePhrase("login") + header.Title = phrases.GetTitlePhrase("login") pi := common.Page{header, tList, nil} return renderTemplate("login", w, r, header, pi) } @@ -140,7 +141,7 @@ func AccountLoginMFAVerify(w http.ResponseWriter, r *http.Request, user common.U if user.Loggedin { return common.LocalError("You're already logged in.", w, r, user) } - header.Title = common.GetTitlePhrase("login_mfa_verify") + header.Title = phrases.GetTitlePhrase("login_mfa_verify") uid, provSession, signedSession, err := mfaGetCookies(r) if err != nil { @@ -193,7 +194,7 @@ func AccountRegister(w http.ResponseWriter, r *http.Request, user common.User) c if user.Loggedin { return common.LocalError("You're already logged in.", w, r, user) } - header.Title = common.GetTitlePhrase("register") + header.Title = phrases.GetTitlePhrase("register") pi := common.Page{header, tList, nil} return renderTemplate("register", w, r, header, pi) @@ -224,14 +225,14 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.U } if r.PostFormValue("tos") != "0" { - regError(common.GetErrorPhrase("register_might_be_machine"), "trap-question") + regError(phrases.GetErrorPhrase("register_might_be_machine"), "trap-question") } if !common.Config.DisableJSAntispam { h := sha256.New() h.Write([]byte(common.JSTokenBox.Load().(string))) h.Write([]byte(user.LastIP)) if r.PostFormValue("golden-watch") != hex.EncodeToString(h.Sum(nil)) { - regError(common.GetErrorPhrase("register_might_be_machine"), "js-antispam") + regError(phrases.GetErrorPhrase("register_might_be_machine"), "js-antispam") } } @@ -239,21 +240,21 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.U // TODO: Add a dedicated function for validating emails email := common.SanitiseSingleLine(r.PostFormValue("email")) if username == "" { - regError(common.GetErrorPhrase("register_need_username"), "no-username") + regError(phrases.GetErrorPhrase("register_need_username"), "no-username") } if email == "" { - regError(common.GetErrorPhrase("register_need_email"), "no-email") + regError(phrases.GetErrorPhrase("register_need_email"), "no-email") } // This is so a numeric name won't interfere with mentioning a user by ID, there might be a better way of doing this like perhaps !@ to mean IDs and @ to mean usernames in the pre-parser usernameBits := strings.Split(username, " ") if isNumeric(usernameBits[0]) { - regError(common.GetErrorPhrase("register_first_word_numeric"), "numeric-name") + regError(phrases.GetErrorPhrase("register_first_word_numeric"), "numeric-name") } ok := common.HasSuspiciousEmail(email) if ok { - regError(common.GetErrorPhrase("register_suspicious_email"), "suspicious-email") + regError(phrases.GetErrorPhrase("register_suspicious_email"), "suspicious-email") } password := r.PostFormValue("password") @@ -265,7 +266,7 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.U // Do the two inputted passwords match..? confirmPassword := r.PostFormValue("confirm_password") if password != confirmPassword { - regError(common.GetErrorPhrase("register_password_mismatch"), "password-mismatch") + regError(phrases.GetErrorPhrase("register_password_mismatch"), "password-mismatch") } } @@ -298,14 +299,14 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.U if err != nil { return common.InternalError(err, w, r) } - return common.LocalError(common.GetErrorPhrase("register_username_unavailable"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("register_username_unavailable"), w, r, user) } else if err == common.ErrLongUsername { regLog.FailureReason += "username-too-long" err = regLog.Commit() if err != nil { return common.InternalError(err, w, r) } - return common.LocalError(common.GetErrorPhrase("register_username_too_long_prefix")+strconv.Itoa(common.Config.MaxUsernameLength), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("register_username_too_long_prefix")+strconv.Itoa(common.Config.MaxUsernameLength), w, r, user) } regLog.FailureReason += "internal-error" err2 := regLog.Commit() @@ -329,7 +330,7 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.U } if !common.SendValidationEmail(username, email, token) { - return common.LocalError(common.GetErrorPhrase("register_email_fail"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("register_email_fail"), w, r, user) } } @@ -349,7 +350,7 @@ func accountEditHead(titlePhrase string, w http.ResponseWriter, r *http.Request, if ferr != nil { return nil, ferr } - header.Title = common.GetTitlePhrase(titlePhrase) + header.Title = phrases.GetTitlePhrase(titlePhrase) header.Path = "/user/edit/" header.AddSheet(header.Theme.Name + "/account.css") header.AddScript("account.js") @@ -389,6 +390,7 @@ func AccountEdit(w http.ResponseWriter, r *http.Request, user common.User) commo return renderTemplate("account", w, r, header, pi) } +//edit_password func AccountEditPassword(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { header, ferr := accountEditHead("account_password", w, r, &user) if ferr != nil { @@ -736,7 +738,7 @@ func LevelList(w http.ResponseWriter, r *http.Request, user common.User) common. if ferr != nil { return ferr } - header.Title = common.GetTitlePhrase("account_level_list") + header.Title = phrases.GetTitlePhrase("account_level_list") var fScores = common.GetLevels(20) var levels = make([]common.LevelListItem, len(fScores)) diff --git a/routes/forum_list.go b/routes/forum_list.go index c9babf47..331c60bf 100644 --- a/routes/forum_list.go +++ b/routes/forum_list.go @@ -5,6 +5,7 @@ import ( "net/http" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" ) func ForumList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { @@ -12,7 +13,7 @@ func ForumList(w http.ResponseWriter, r *http.Request, user common.User) common. if ferr != nil { return ferr } - header.Title = common.GetTitlePhrase("forums") + header.Title = phrases.GetTitlePhrase("forums") header.Zone = "forums" header.Path = "/forums/" header.MetaDesc = header.Settings["meta_desc"].(string) diff --git a/routes/misc.go b/routes/misc.go index 247cebcb..5d7502d9 100644 --- a/routes/misc.go +++ b/routes/misc.go @@ -11,6 +11,7 @@ import ( "time" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/query_gen" ) @@ -53,7 +54,7 @@ func Overview(w http.ResponseWriter, r *http.Request, user common.User) common.R if ferr != nil { return ferr } - header.Title = common.GetTitlePhrase("overview") + header.Title = phrases.GetTitlePhrase("overview") header.Zone = "overview" pi := common.Page{header, tList, nil} @@ -72,7 +73,7 @@ func CustomPage(w http.ResponseWriter, r *http.Request, user common.User, name s if ferr != nil { return ferr } - header.Title = common.GetTitlePhrase("page") + header.Title = phrases.GetTitlePhrase("page") header.Zone = "custom_page" name = common.SanitiseSingleLine(name) diff --git a/routes/moderate.go b/routes/moderate.go index c2d15d84..2ee30360 100644 --- a/routes/moderate.go +++ b/routes/moderate.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" ) func IPSearch(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { @@ -11,7 +12,7 @@ func IPSearch(w http.ResponseWriter, r *http.Request, user common.User) common.R if ferr != nil { return ferr } - header.Title = common.GetTitlePhrase("ip_search") + header.Title = phrases.GetTitlePhrase("ip_search") // TODO: How should we handle the permissions if we extend this into an alt detector of sorts? if !user.Perms.ViewIPs { diff --git a/routes/panel/analytics.go b/routes/panel/analytics.go index 10cd8ae7..4f063b4a 100644 --- a/routes/panel/analytics.go +++ b/routes/panel/analytics.go @@ -9,6 +9,7 @@ import ( "time" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/query_gen" ) @@ -227,7 +228,7 @@ func AnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user common.Use graph := common.PanelTimeGraph{Series: viewList, Labels: labelList} common.DebugLogf("graph: %+v\n", graph) - friendlyAgent, ok := common.GetUserAgentPhrase(agent) + friendlyAgent, ok := phrases.GetUserAgentPhrase(agent) if !ok { friendlyAgent = agent } @@ -312,7 +313,7 @@ func AnalyticsSystemViews(w http.ResponseWriter, r *http.Request, user common.Us graph := common.PanelTimeGraph{Series: viewList, Labels: labelList} common.DebugLogf("graph: %+v\n", graph) - friendlySystem, ok := common.GetOSPhrase(system) + friendlySystem, ok := phrases.GetOSPhrase(system) if !ok { friendlySystem = system } @@ -352,7 +353,7 @@ func AnalyticsLanguageViews(w http.ResponseWriter, r *http.Request, user common. graph := common.PanelTimeGraph{Series: viewList, Labels: labelList} common.DebugLogf("graph: %+v\n", graph) - friendlyLang, ok := common.GetHumanLangPhrase(lang) + friendlyLang, ok := phrases.GetHumanLangPhrase(lang) if !ok { friendlyLang = lang } @@ -584,7 +585,7 @@ func AnalyticsAgents(w http.ResponseWriter, r *http.Request, user common.User) c // TODO: Sort this slice var agentItems []common.PanelAnalyticsAgentsItem for agent, count := range agentMap { - aAgent, ok := common.GetUserAgentPhrase(agent) + aAgent, ok := phrases.GetUserAgentPhrase(agent) if !ok { aAgent = agent } @@ -622,7 +623,7 @@ func AnalyticsSystems(w http.ResponseWriter, r *http.Request, user common.User) // TODO: Sort this slice var systemItems []common.PanelAnalyticsAgentsItem for system, count := range osMap { - sSystem, ok := common.GetOSPhrase(system) + sSystem, ok := phrases.GetOSPhrase(system) if !ok { sSystem = system } @@ -661,7 +662,7 @@ func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user common.User // TODO: Sort this slice var langItems []common.PanelAnalyticsAgentsItem for lang, count := range langMap { - lLang, ok := common.GetHumanLangPhrase(lang) + lLang, ok := phrases.GetHumanLangPhrase(lang) if !ok { lLang = lang } diff --git a/routes/panel/common.go b/routes/panel/common.go index 7f8873fa..ea2282c6 100644 --- a/routes/panel/common.go +++ b/routes/panel/common.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" ) // A blank list to fill out that parameter in Page for routes which don't use it @@ -37,7 +38,7 @@ func buildBasePage(w http.ResponseWriter, r *http.Request, user *common.User, ti if ferr != nil { return nil, ferr } - header.Title = common.GetTitlePhrase("panel_" + titlePhrase) + header.Title = phrases.GetTitlePhrase("panel_" + titlePhrase) return &common.BasePanelPage{header, stats, zone, common.ReportForumID}, nil } diff --git a/routes/panel/dashboard.go b/routes/panel/dashboard.go index dcaae9ee..63f603c9 100644 --- a/routes/panel/dashboard.go +++ b/routes/panel/dashboard.go @@ -7,6 +7,7 @@ import ( "strconv" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/query_gen" "github.com/Azareal/gopsutil/mem" "github.com/pkg/errors" @@ -142,18 +143,18 @@ func Dashboard(w http.ResponseWriter, r *http.Request, user common.User) common. // TODO: Allow for more complex phrase structures than just suffixes var postCount = extractStat(stmts.todaysPostCount) - var postInterval = common.GetTmplPhrase("panel_dashboard_day_suffix") + var postInterval = phrases.GetTmplPhrase("panel_dashboard_day_suffix") var postColour = greaterThanSwitch(postCount, 5, 25) var topicCount = extractStat(stmts.todaysTopicCount) - var topicInterval = common.GetTmplPhrase("panel_dashboard_day_suffix") + var topicInterval = phrases.GetTmplPhrase("panel_dashboard_day_suffix") var topicColour = greaterThanSwitch(topicCount, 0, 8) var reportCount = extractStat(stmts.todaysTopicCountByForum, common.ReportForumID) - var reportInterval = common.GetTmplPhrase("panel_dashboard_week_suffix") + var reportInterval = phrases.GetTmplPhrase("panel_dashboard_week_suffix") var newUserCount = extractStat(stmts.todaysNewUserCount) - var newUserInterval = common.GetTmplPhrase("panel_dashboard_week_suffix") + var newUserInterval = phrases.GetTmplPhrase("panel_dashboard_week_suffix") // Did any of the extractStats fail? if intErr != nil { @@ -187,9 +188,9 @@ func Dashboard(w http.ResponseWriter, r *http.Request, user common.User) common. uonline, uunit := common.ConvertFriendlyUnit(uonline) gonline, gunit := common.ConvertFriendlyUnit(gonline) - addElement(common.GridElement{"dash-totonline", common.GetTmplPhrasef("panel_dashboard_online", totonline, totunit), 3, "grid_stat " + onlineColour, "", "", "The number of people who are currently online"}) - addElement(common.GridElement{"dash-gonline", common.GetTmplPhrasef("panel_dashboard_guests_online", gonline, gunit), 4, "grid_stat " + onlineGuestsColour, "", "", "The number of guests who are currently online"}) - addElement(common.GridElement{"dash-uonline", common.GetTmplPhrasef("panel_dashboard_users_online", uonline, uunit), 5, "grid_stat " + onlineUsersColour, "", "", "The number of logged-in users who are currently online"}) + addElement(common.GridElement{"dash-totonline", phrases.GetTmplPhrasef("panel_dashboard_online", totonline, totunit), 3, "grid_stat " + onlineColour, "", "", "The number of people who are currently online"}) + addElement(common.GridElement{"dash-gonline", phrases.GetTmplPhrasef("panel_dashboard_guests_online", gonline, gunit), 4, "grid_stat " + onlineGuestsColour, "", "", "The number of guests who are currently online"}) + addElement(common.GridElement{"dash-uonline", phrases.GetTmplPhrasef("panel_dashboard_users_online", uonline, uunit), 5, "grid_stat " + onlineUsersColour, "", "", "The number of logged-in users who are currently online"}) addElement(common.GridElement{"dash-reqs", strconv.Itoa(reqCount) + " reqs / second", 7, "grid_stat grid_end_group " + topicColour, "", "", "The number of requests over the last 24 hours"}) } diff --git a/routes/panel/forums.go b/routes/panel/forums.go index c80e4c74..c17ba28c 100644 --- a/routes/panel/forums.go +++ b/routes/panel/forums.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" ) func Forums(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { @@ -329,7 +330,7 @@ func ForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, user common. // TODO: Load the phrases in bulk for efficiency? // TODO: Reduce the amount of code duplication between this and the group editor. Also, can we grind this down into one line or use a code generator to stay current more easily? var addNameLangToggle = func(permStr string, perm bool) { - formattedPermList = append(formattedPermList, common.NameLangToggle{permStr, common.GetLocalPermPhrase(permStr), perm}) + formattedPermList = append(formattedPermList, common.NameLangToggle{permStr, phrases.GetLocalPermPhrase(permStr), perm}) } addNameLangToggle("ViewTopic", forumPerms.ViewTopic) addNameLangToggle("LikeItem", forumPerms.LikeItem) diff --git a/routes/panel/groups.go b/routes/panel/groups.go index 7952cc51..b7d7fe93 100644 --- a/routes/panel/groups.go +++ b/routes/panel/groups.go @@ -6,6 +6,7 @@ import ( "strconv" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" ) func Groups(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { @@ -72,7 +73,7 @@ func GroupsEdit(w http.ResponseWriter, r *http.Request, user common.User, sgid s gid, err := strconv.Atoi(sgid) if err != nil { - return common.LocalError(common.GetErrorPhrase("url_id_must_be_integer"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r, user) } group, err := common.Groups.Get(gid) @@ -84,10 +85,10 @@ func GroupsEdit(w http.ResponseWriter, r *http.Request, user common.User, sgid s } if group.IsAdmin && !user.Perms.EditGroupAdmin { - return common.LocalError(common.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user) } if group.IsMod && !user.Perms.EditGroupSuperMod { - return common.LocalError(common.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user) } var rank string @@ -120,7 +121,7 @@ func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user common.User, s gid, err := strconv.Atoi(sgid) if err != nil { - return common.LocalError(common.GetErrorPhrase("url_id_must_be_integer"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r, user) } group, err := common.Groups.Get(gid) @@ -132,17 +133,17 @@ func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user common.User, s } if group.IsAdmin && !user.Perms.EditGroupAdmin { - return common.LocalError(common.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user) } if group.IsMod && !user.Perms.EditGroupSuperMod { - return common.LocalError(common.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user) } // TODO: Load the phrases in bulk for efficiency? var localPerms []common.NameLangToggle var addLocalPerm = func(permStr string, perm bool) { - localPerms = append(localPerms, common.NameLangToggle{permStr, common.GetLocalPermPhrase(permStr), perm}) + localPerms = append(localPerms, common.NameLangToggle{permStr, phrases.GetLocalPermPhrase(permStr), perm}) } addLocalPerm("ViewTopic", group.Perms.ViewTopic) @@ -160,7 +161,7 @@ func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user common.User, s var globalPerms []common.NameLangToggle var addGlobalPerm = func(permStr string, perm bool) { - globalPerms = append(globalPerms, common.NameLangToggle{permStr, common.GetGlobalPermPhrase(permStr), perm}) + globalPerms = append(globalPerms, common.NameLangToggle{permStr, phrases.GetGlobalPermPhrase(permStr), perm}) } addGlobalPerm("BanUsers", group.Perms.BanUsers) @@ -199,7 +200,7 @@ func GroupsEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, gid, err := strconv.Atoi(sgid) if err != nil { - return common.LocalError(common.GetErrorPhrase("id_must_be_integer"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user) } group, err := common.Groups.Get(gid) @@ -211,15 +212,15 @@ func GroupsEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, } if group.IsAdmin && !user.Perms.EditGroupAdmin { - return common.LocalError(common.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user) } if group.IsMod && !user.Perms.EditGroupSuperMod { - return common.LocalError(common.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user) } gname := r.FormValue("group-name") if gname == "" { - return common.LocalError(common.GetErrorPhrase("panel_groups_need_name"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_need_name"), w, r, user) } gtag := r.FormValue("group-tag") rank := r.FormValue("group-type") @@ -240,28 +241,28 @@ func GroupsEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, if rank != originalRank && originalRank != "Guest" { if !user.Perms.EditGroupGlobalPerms { - return common.LocalError(common.GetErrorPhrase("panel_groups_cannot_edit_group_type"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_edit_group_type"), w, r, user) } switch rank { case "Admin": if !user.Perms.EditGroupAdmin { - return common.LocalError(common.GetErrorPhrase("panel_groups_edit_cannot_designate_admin"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_edit_cannot_designate_admin"), w, r, user) } err = group.ChangeRank(true, true, false) case "Mod": if !user.Perms.EditGroupSuperMod { - return common.LocalError(common.GetErrorPhrase("panel_groups_edit_cannot_designate_supermod"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_edit_cannot_designate_supermod"), w, r, user) } err = group.ChangeRank(false, true, false) case "Banned": err = group.ChangeRank(false, false, true) case "Guest": - return common.LocalError(common.GetErrorPhrase("panel_groups_cannot_be_guest"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_be_guest"), w, r, user) case "Member": err = group.ChangeRank(false, false, false) default: - return common.LocalError(common.GetErrorPhrase("panel_groups_invalid_group_type"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_invalid_group_type"), w, r, user) } if err != nil { return common.InternalError(err, w, r) @@ -288,7 +289,7 @@ func GroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user common.U gid, err := strconv.Atoi(sgid) if err != nil { - return common.LocalError(common.GetErrorPhrase("id_must_be_integer"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user) } group, err := common.Groups.Get(gid) @@ -300,10 +301,10 @@ func GroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user common.U } if group.IsAdmin && !user.Perms.EditGroupAdmin { - return common.LocalError(common.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user) } if group.IsMod && !user.Perms.EditGroupSuperMod { - return common.LocalError(common.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user) } var pmap = make(map[string]bool) @@ -342,7 +343,7 @@ func GroupsCreateSubmit(w http.ResponseWriter, r *http.Request, user common.User groupName := r.PostFormValue("group-name") if groupName == "" { - return common.LocalError(common.GetErrorPhrase("panel_groups_need_name"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_need_name"), w, r, user) } groupTag := r.PostFormValue("group-tag") @@ -351,13 +352,13 @@ func GroupsCreateSubmit(w http.ResponseWriter, r *http.Request, user common.User groupType := r.PostFormValue("group-type") if groupType == "Admin" { if !user.Perms.EditGroupAdmin { - return common.LocalError(common.GetErrorPhrase("panel_groups_create_cannot_designate_admin"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_create_cannot_designate_admin"), w, r, user) } isAdmin = true isMod = true } else if groupType == "Mod" { if !user.Perms.EditGroupSuperMod { - return common.LocalError(common.GetErrorPhrase("panel_groups_create_cannot_designate_supermod"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("panel_groups_create_cannot_designate_supermod"), w, r, user) } isMod = true } else if groupType == "Banned" { diff --git a/routes/panel/settings.go b/routes/panel/settings.go index f552ca8f..7cfa1d40 100644 --- a/routes/panel/settings.go +++ b/routes/panel/settings.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" ) func Settings(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { @@ -22,7 +23,7 @@ func Settings(w http.ResponseWriter, r *http.Request, user common.User) common.R if err != nil { return common.InternalError(err, w, r) } - settingPhrases := common.GetAllSettingPhrases() + settingPhrases := phrases.GetAllSettingPhrases() var settingList []*common.PanelSetting for _, settingPtr := range settings { @@ -44,7 +45,7 @@ func Settings(w http.ResponseWriter, r *http.Request, user common.User) common.R } else if setting.Type == "html-attribute" { setting.Type = "textarea" } - settingList = append(settingList, &common.PanelSetting{setting, common.GetSettingPhrase(setting.Name)}) + settingList = append(settingList, &common.PanelSetting{setting, phrases.GetSettingPhrase(setting.Name)}) } pi := common.PanelPage{basePage, tList, settingList} @@ -69,12 +70,11 @@ func SettingEdit(w http.ResponseWriter, r *http.Request, user common.User, sname var itemList []common.OptionLabel if setting.Type == "list" { - llist := common.GetSettingPhrase(setting.Name + "_label") + llist := phrases.GetSettingPhrase(setting.Name + "_label") conv, err := strconv.Atoi(setting.Content) if err != nil { return common.LocalError("The value of this setting couldn't be converted to an integer", w, r, user) } - //fmt.Println("llist: ", llist) for index, label := range strings.Split(llist, ",") { itemList = append(itemList, common.OptionLabel{ @@ -87,7 +87,7 @@ func SettingEdit(w http.ResponseWriter, r *http.Request, user common.User, sname setting.Type = "textarea" } - pSetting := &common.PanelSetting{setting, common.GetSettingPhrase(setting.Name)} + pSetting := &common.PanelSetting{setting, phrases.GetSettingPhrase(setting.Name)} pi := common.PanelSettingPage{basePage, itemList, pSetting} return renderTemplate("panel_setting", w, r, user, &pi) } diff --git a/routes/panel/themes.go b/routes/panel/themes.go index 0cefac1b..825aaedf 100644 --- a/routes/panel/themes.go +++ b/routes/panel/themes.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" ) func Themes(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { @@ -73,7 +74,7 @@ func ThemesMenus(w http.ResponseWriter, r *http.Request, user common.User) commo for mid, list := range common.Menus.GetAllMap() { var name = "" if mid == 1 { - name = common.GetTmplPhrase("panel_themes_menus_main") + name = phrases.GetTmplPhrase("panel_themes_menus_main") } menuList = append(menuList, common.PanelMenuListItem{ Name: name, @@ -99,7 +100,7 @@ func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user common.User, s mid, err := strconv.Atoi(smid) if err != nil { - return common.LocalError(common.GetErrorPhrase("url_id_must_be_integer"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r, user) } menuHold, err := common.Menus.Get(mid) @@ -145,7 +146,7 @@ func ThemesMenuItemEdit(w http.ResponseWriter, r *http.Request, user common.User itemID, err := strconv.Atoi(sitemID) if err != nil { - return common.LocalError(common.GetErrorPhrase("url_id_must_be_integer"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r, user) } menuItem, err := common.Menus.ItemStore().Get(itemID) @@ -217,7 +218,7 @@ func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user commo itemID, err := strconv.Atoi(sitemID) if err != nil { - return common.LocalErrorJSQ(common.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs) + return common.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs) } menuItem, err := common.Menus.ItemStore().Get(itemID) @@ -252,7 +253,7 @@ func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, user com } menuID, err := strconv.Atoi(smenuID) if err != nil { - return common.LocalErrorJSQ(common.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs) + return common.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs) } menuItem := common.MenuItem{MenuID: menuID} @@ -276,7 +277,7 @@ func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, user com itemID, err := strconv.Atoi(sitemID) if err != nil { - return common.LocalErrorJSQ(common.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs) + return common.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs) } menuItem, err := common.Menus.ItemStore().Get(itemID) if err == sql.ErrNoRows { @@ -305,7 +306,7 @@ func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user comm mid, err := strconv.Atoi(smid) if err != nil { - return common.LocalErrorJSQ(common.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs) + return common.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs) } menuHold, err := common.Menus.Get(mid) if err == sql.ErrNoRows { diff --git a/routes/profile.go b/routes/profile.go index b60b2124..f85bf255 100644 --- a/routes/profile.go +++ b/routes/profile.go @@ -8,6 +8,7 @@ import ( "time" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/query_gen" ) @@ -68,7 +69,7 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User) commo } puser.Init() } - header.Title = common.GetTitlePhrasef("profile", puser.Name) + header.Title = phrases.GetTitlePhrasef("profile", puser.Name) header.Path = common.BuildProfileURL(common.NameToSlug(puser.Name), puser.ID) // Get the replies.. @@ -100,7 +101,7 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User) commo if group.Tag != "" { replyTag = group.Tag } else if puser.ID == replyCreatedBy { - replyTag = common.GetTmplPhrase("profile_owner_tag") + replyTag = phrases.GetTmplPhrase("profile_owner_tag") } else { replyTag = "" } diff --git a/routes/topic.go b/routes/topic.go index b17ec148..de1922fc 100644 --- a/routes/topic.go +++ b/routes/topic.go @@ -15,6 +15,7 @@ import ( "github.com/Azareal/Gosora/common" "github.com/Azareal/Gosora/common/counters" + "github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/query_gen" ) @@ -48,7 +49,7 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit tid, err := strconv.Atoi(halves[1]) if err != nil { - return common.PreError(common.GetErrorPhrase("url_id_must_be_integer"), w, r) + return common.PreError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r) } // Get the topic... @@ -162,22 +163,22 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit if replyItem.ActionType != "" { switch replyItem.ActionType { case "lock": - replyItem.ActionType = common.GetTmplPhrasef("topic.action_topic_lock",replyItem.UserLink,replyItem.CreatedByName) + replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_lock",replyItem.UserLink,replyItem.CreatedByName) replyItem.ActionIcon = "🔒︎" case "unlock": - replyItem.ActionType = common.GetTmplPhrasef("topic.action_topic_unlock",replyItem.UserLink,replyItem.CreatedByName) + replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_unlock",replyItem.UserLink,replyItem.CreatedByName) replyItem.ActionIcon = "🔓︎" case "stick": - replyItem.ActionType = common.GetTmplPhrasef("topic.action_topic_stick",replyItem.UserLink,replyItem.CreatedByName) + replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_stick",replyItem.UserLink,replyItem.CreatedByName) replyItem.ActionIcon = "📌︎" case "unstick": - replyItem.ActionType = common.GetTmplPhrasef("topic.action_topic_unstick",replyItem.UserLink,replyItem.CreatedByName) + replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_unstick",replyItem.UserLink,replyItem.CreatedByName) replyItem.ActionIcon = "📌︎" case "move": - replyItem.ActionType = common.GetTmplPhrasef("topic.action_topic_move",replyItem.UserLink,replyItem.CreatedByName) + replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_move",replyItem.UserLink,replyItem.CreatedByName) // TODO: Only fire this off if a corresponding phrase for the ActionType doesn't exist? Or maybe have some sort of action registry? default: - replyItem.ActionType = common.GetTmplPhrasef("topic.action_topic_default",replyItem.ActionType) + replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_default",replyItem.ActionType) replyItem.ActionIcon = "" } } @@ -237,7 +238,7 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user common.User, sfid if sfid != "" { fid, err = strconv.Atoi(sfid) if err != nil { - return common.LocalError(common.GetErrorPhrase("url_id_must_be_integer"), w, r, user) + return common.LocalError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r, user) } } if fid == 0 { @@ -252,7 +253,7 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user common.User, sfid return common.NoPermissions(w, r, user) } // TODO: Add a phrase for this - header.Title = common.GetTitlePhrase("create_topic") + header.Title = phrases.GetTitlePhrase("create_topic") header.Zone = "create_topic" // Lock this to the forum being linked? @@ -343,8 +344,8 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User) var maxPollOptions = 10 var pollInputItems = make(map[int]string) for key, values := range r.Form { - common.DebugDetail("key: ", key) - common.DebugDetailf("values: %+v\n", values) + //common.DebugDetail("key: ", key) + //common.DebugDetailf("values: %+v\n", values) for _, value := range values { if strings.HasPrefix(key, "pollinputitem[") { halves := strings.Split(key, "[") @@ -474,10 +475,9 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User) // TODO: Disable stat updates in posts handled by plugin_guilds func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User, stid string) common.RouteError { isJs := (r.PostFormValue("js") == "1") - tid, err := strconv.Atoi(stid) if err != nil { - return common.PreErrorJSQ(common.GetErrorPhrase("id_must_be_integer"), w, r, isJs) + return common.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, isJs) } topic, err := common.Topics.Get(tid) @@ -593,74 +593,59 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User) } func StickTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User, stid string) common.RouteError { + topic,rerr := topicActionPre(stid,"pin",w,r,user) + if rerr != nil { + return rerr + } + if !user.Perms.ViewTopic || !user.Perms.PinTopic { + return common.NoPermissions(w, r, user) + } + return topicActionPost(topic.Stick(),"stick",w,r,topic,user) +} + +func topicActionPre(stid string, action string, w http.ResponseWriter, r *http.Request, user common.User) (*common.Topic, common.RouteError) { tid, err := strconv.Atoi(stid) if err != nil { - return common.PreError(common.GetErrorPhrase("id_must_be_integer"), w, r) + return nil,common.PreError(phrases.GetErrorPhrase("id_must_be_integer"), w, r) } topic, err := common.Topics.Get(tid) if err == sql.ErrNoRows { - return common.PreError("The topic you tried to pin doesn't exist.", w, r) + return nil, common.PreError("The topic you tried to "+action+" doesn't exist.", w, r) } else if err != nil { - return common.InternalError(err, w, r) + return nil, common.InternalError(err, w, r) } // TODO: Add hooks to make use of headerLite _, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID) if ferr != nil { - return ferr - } - if !user.Perms.ViewTopic || !user.Perms.PinTopic { - return common.NoPermissions(w, r, user) + return nil, ferr } - err = topic.Stick() + return topic, nil +} + +func topicActionPost(err error, action string,w http.ResponseWriter, r *http.Request, topic *common.Topic, user common.User) common.RouteError { if err != nil { return common.InternalError(err, w, r) } - - err = addTopicAction("stick", topic, user) + err = addTopicAction(action, topic, user) if err != nil { return common.InternalError(err, w, r) } - http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther) + http.Redirect(w, r, "/topic/"+strconv.Itoa(topic.ID), http.StatusSeeOther) return nil } func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User, stid string) common.RouteError { - tid, err := strconv.Atoi(stid) - if err != nil { - return common.PreError(common.GetErrorPhrase("id_must_be_integer"), w, r) - } - - topic, err := common.Topics.Get(tid) - if err == sql.ErrNoRows { - return common.PreError("The topic you tried to unpin doesn't exist.", w, r) - } else if err != nil { - return common.InternalError(err, w, r) - } - - // TODO: Add hooks to make use of headerLite - _, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID) - if ferr != nil { - return ferr + topic,rerr := topicActionPre(stid,"unpin",w,r,user) + if rerr != nil { + return rerr } if !user.Perms.ViewTopic || !user.Perms.PinTopic { return common.NoPermissions(w, r, user) } - - err = topic.Unstick() - if err != nil { - return common.InternalError(err, w, r) - } - - err = addTopicAction("unstick", topic, user) - if err != nil { - return common.InternalError(err, w, r) - } - - http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther) - return nil + return topicActionPost(topic.Unstick(),"unstick",w,r,topic,user) } func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { @@ -722,39 +707,14 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User) c } func UnlockTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User, stid string) common.RouteError { - tid, err := strconv.Atoi(stid) - if err != nil { - return common.PreError(common.GetErrorPhrase("id_must_be_integer"), w, r) - } - - topic, err := common.Topics.Get(tid) - if err == sql.ErrNoRows { - return common.PreError("The topic you tried to unlock doesn't exist.", w, r) - } else if err != nil { - return common.InternalError(err, w, r) - } - - // TODO: Add hooks to make use of headerLite - _, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID) - if ferr != nil { - return ferr + topic,rerr := topicActionPre(stid,"unlock",w,r,user) + if rerr != nil { + return rerr } if !user.Perms.ViewTopic || !user.Perms.CloseTopic { return common.NoPermissions(w, r, user) } - - err = topic.Unlock() - if err != nil { - return common.InternalError(err, w, r) - } - - err = addTopicAction("unlock", topic, user) - if err != nil { - return common.InternalError(err, w, r) - } - - http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther) - return nil + return topicActionPost(topic.Unlock(),"unlock",w,r,topic,user) } // ! JS only route @@ -762,7 +722,7 @@ func UnlockTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User, func MoveTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User, sfid string) common.RouteError { fid, err := strconv.Atoi(sfid) if err != nil { - return common.PreErrorJS(common.GetErrorPhrase("id_must_be_integer"), w, r) + return common.PreErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r) } // TODO: Move this to some sort of middleware @@ -833,7 +793,7 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User, s isJs := (r.PostFormValue("isJs") == "1") tid, err := strconv.Atoi(stid) if err != nil { - return common.PreErrorJSQ(common.GetErrorPhrase("id_must_be_integer"), w, r, isJs) + return common.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, isJs) } topic, err := common.Topics.Get(tid) diff --git a/routes/topic_list.go b/routes/topic_list.go index 57547997..38af81fa 100644 --- a/routes/topic_list.go +++ b/routes/topic_list.go @@ -6,6 +6,7 @@ import ( "strconv" "github.com/Azareal/Gosora/common" + "github.com/Azareal/Gosora/common/phrases" ) func TopicList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { @@ -13,7 +14,7 @@ func TopicList(w http.ResponseWriter, r *http.Request, user common.User) common. if ferr != nil { return ferr } - header.Title = common.GetTitlePhrase("topics") + header.Title = phrases.GetTitlePhrase("topics") header.Zone = "topics" header.Path = "/topics/" header.MetaDesc = header.Settings["meta_desc"].(string) @@ -61,7 +62,7 @@ func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user common.Use if ferr != nil { return ferr } - header.Title = common.GetTitlePhrase("topics") + header.Title = phrases.GetTitlePhrase("topics") header.Zone = "topics" header.Path = "/topics/" header.MetaDesc = header.Settings["meta_desc"].(string)