diff --git a/common/errors.go b/common/errors.go
index 6d095eac..f0485dff 100644
--- a/common/errors.go
+++ b/common/errors.go
@@ -129,12 +129,14 @@ func errorHeader(w http.ResponseWriter, user User, title string) *Header {
header := DefaultHeader(w, user)
header.Title = title
header.Zone = "error"
+ prepResources(&user, header, header.Theme)
return header
}
// TODO: Dump the request?
// InternalError is the main function for handling internal errors, while simultaneously printing out a page for the end-user to let them know that *something* has gone wrong
// ? - Add a user parameter?
+// ! Do not call CustomError here or we might get an error loop
func InternalError(err error, w http.ResponseWriter, r *http.Request) RouteError {
w.WriteHeader(500)
pi := ErrorPage{errorHeader(w, GuestUser, phrases.GetErrorPhrase("internal_error_title")), phrases.GetErrorPhrase("internal_error_body")}
@@ -188,6 +190,7 @@ func SilentInternalErrorXML(err error, w http.ResponseWriter, r *http.Request) R
return HandledRouteError()
}
+// ! Do not call CustomError here otherwise we might get an error loop
func PreError(errmsg string, w http.ResponseWriter, r *http.Request) RouteError {
w.WriteHeader(500)
pi := ErrorPage{errorHeader(w, GuestUser, phrases.GetErrorPhrase("error_title")), errmsg}
@@ -342,9 +345,12 @@ func NotFoundJSQ(w http.ResponseWriter, r *http.Request, header *Header, js bool
}
// CustomError lets us make custom error types which aren't covered by the generic functions above
-func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, header *Header, user User) RouteError {
+func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, header *Header, user User) (rerr RouteError) {
if header == nil {
- header = DefaultHeader(w, user)
+ header, rerr = UserCheck(w, r, &user)
+ if rerr != nil {
+ header = errorHeader(w, user, errtitle)
+ }
}
header.Title = errtitle
header.Zone = "error"
diff --git a/common/routes_common.go b/common/routes_common.go
index 8c7ee2c8..c235d903 100644
--- a/common/routes_common.go
+++ b/common/routes_common.go
@@ -95,18 +95,7 @@ func cascadeForumPerms(fperms *ForumPerms, user *User) {
// Even if they have the right permissions, the control panel is only open to supermods+. There are many areas without subpermissions which assume that the current user is a supermod+ and admins are extremely unlikely to give these permissions to someone who isn't at-least a supermod to begin with
// TODO: Do a panel specific theme?
func panelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Header, stats PanelStats, rerr RouteError) {
- var theme = &Theme{Name: ""}
- cookie, err := r.Cookie("current_theme")
- if err == nil {
- inTheme, ok := Themes[html.EscapeString(cookie.Value)]
- if ok && !theme.HideFromThemes {
- theme = inTheme
- }
- }
- if theme.Name == "" {
- theme = Themes[DefaultThemeBox.Load().(string)]
- }
-
+ theme := getTheme(r)
header = &Header{
Site: Site,
Settings: SettingBox.Load().(SettingMap),
@@ -186,8 +175,7 @@ func simpleUserCheck(w http.ResponseWriter, r *http.Request, user *User) (header
}, nil
}
-// TODO: Add the ability for admins to restrict certain themes to certain groups?
-func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Header, rerr RouteError) {
+func getTheme(r *http.Request) *Theme {
var theme = &Theme{Name: ""}
cookie, err := r.Cookie("current_theme")
@@ -201,6 +189,13 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Head
theme = Themes[DefaultThemeBox.Load().(string)]
}
+ return theme
+}
+
+// TODO: Add the ability for admins to restrict certain themes to certain groups?
+// ! Be careful about firing errors off here as CustomError uses this
+func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Header, rerr RouteError) {
+ theme := getTheme(r)
header = &Header{
Site: Site,
Settings: SettingBox.Load().(SettingMap),
@@ -220,13 +215,20 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Head
if user.Loggedin && !user.Active {
header.AddNotice("account_inactive")
}
+
// An optimisation so we don't populate StartedAt for users who shouldn't see the stat anyway
// ? - Should we only show this in debug mode? It might be useful for detecting issues in production, if we show it there as-well
if user.IsAdmin {
header.StartedAt = time.Now()
}
+ prepResources(user,header,theme)
+ return header, nil
+}
+
+func prepResources(user *User, header *Header, theme *Theme) {
header.AddSheet(theme.Name + "/main.css")
+
if len(theme.Resources) > 0 {
rlist := theme.Resources
for _, resource := range rlist {
@@ -269,8 +271,6 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Head
addPreScript("topic_c_edit_post")
addPreScript("topic_c_attach_item")
}
-
- return header, nil
}
func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) {
diff --git a/langs/english.json b/langs/english.json
index 572857b9..252ced77 100644
--- a/langs/english.json
+++ b/langs/english.json
@@ -903,7 +903,24 @@
"panel_logs_registration_attempt":"Attempt",
"panel_logs_registration_email":"email",
"panel_logs_registration_reason":"reason",
+
"panel_logs_moderation_head":"Mod Action Logs",
+ "panel_logs_moderation_action_topic_stick":"%s was pinned by %s",
+ "panel_logs_moderation_action_topic_unstick":"%s was unpinned by %s",
+ "panel_logs_moderation_action_topic_lock":"%s was locked by %s",
+ "panel_logs_moderation_action_topic_unlock":"%s was reopened by %s",
+ "panel_logs_moderation_action_topic_delete":"Topic #%d was deleted by %s",
+ "panel_logs_moderation_action_topic_move":"%s was moved by %s",
+ "panel_logs_moderation_action_topic_move_dest":"%s was moved to %s by %s",
+ "panel_logs_moderation_action_topic_unknown":"Unknown action '%s' on elementType '%s' by %s",
+ "panel_logs_moderation_action_reply_delete":"A reply in %s was deleted by %s",
+ "panel_logs_moderation_action_user_ban":"%s was banned by %s",
+ "panel_logs_moderation_action_user_unban":"%s was unbanned by %s",
+ "panel_logs_moderation_action_user_activate":"%s was activated by %s",
+ "panel_logs_moderation_action_unknown":"Unknown action '%s' on elementType '%s' by %s",
+
+ "user_unknown":"Unknown",
+
"panel_logs_administration_head":"Admin Action Logs",
"panel_plugins_head":"Plugins",
diff --git a/routes/panel/logs.go b/routes/panel/logs.go
index 6e6c6e55..699d0c58 100644
--- a/routes/panel/logs.go
+++ b/routes/panel/logs.go
@@ -8,6 +8,7 @@ import (
"strings"
"github.com/Azareal/Gosora/common"
+ "github.com/Azareal/Gosora/common/phrases"
)
// TODO: Link the usernames for successful registrations to the profiles
@@ -37,46 +38,44 @@ func LogsRegs(w http.ResponseWriter, r *http.Request, user common.User) common.R
}
// TODO: Log errors when something really screwy is going on?
+// TODO: Base the slugs on the localised usernames?
func handleUnknownUser(user *common.User, err error) *common.User {
if err != nil {
- return &common.User{Name: "Unknown", Link: common.BuildProfileURL("unknown", 0)}
+ return &common.User{Name: phrases.GetTmplPhrase("user_unknown"), Link: common.BuildProfileURL("unknown", 0)}
}
return user
}
func handleUnknownTopic(topic *common.Topic, err error) *common.Topic {
if err != nil {
- return &common.Topic{Title: "Unknown", Link: common.BuildProfileURL("unknown", 0)}
+ return &common.Topic{Title: phrases.GetTmplPhrase("user_unknown"), Link: common.BuildTopicURL("unknown", 0)}
}
return topic
}
// TODO: Move the log building logic into /common/ and it's own abstraction
-// TODO: Localise this
func topicElementTypeAction(action string, elementType string, elementID int, actor *common.User, topic *common.Topic) (out string) {
if action == "delete" {
- return fmt.Sprintf("Topic #%d was deleted by %s", elementID, actor.Link, actor.Name)
+ return phrases.GetTmplPhrasef("panel_logs_moderation_action_topic_delete", elementID, actor.Link, actor.Name)
}
+ var tbit string
aarr := strings.Split(action, "-")
switch aarr[0] {
- case "lock":
- out = "%s was locked by %s"
- case "unlock":
- out = "%s was reopened by %s"
- case "stick":
- out = "%s was pinned by %s"
- case "unstick":
- out = "%s was unpinned by %s"
+ case "lock","unlock","stick","unstick":
+ tbit = aarr[0]
case "move":
if len(aarr) == 2 {
fid, _ := strconv.Atoi(aarr[1])
forum, err := common.Forums.Get(fid)
if err == nil {
- return fmt.Sprintf("%s was moved to %s by %s", topic.Link, topic.Title, forum.Link, forum.Name, actor.Link, actor.Name)
+ return phrases.GetTmplPhrasef("panel_logs_moderation_action_topic_move_dest", topic.Link, topic.Title, forum.Link, forum.Name, actor.Link, actor.Name)
}
}
- out = "%s was moved by %s" // TODO: Add where it was moved to, we'll have to change the source data for that, most likely? Investigate that and try to work this in
+ tbit = "move"
default:
- return fmt.Sprintf("Unknown action '%s' on elementType '%s' by %s", action, elementType, actor.Link, actor.Name)
+ return phrases.GetTmplPhrasef("panel_logs_moderation_action_topic_unknown", action, elementType, actor.Link, actor.Name)
+ }
+ if tbit != "" {
+ return phrases.GetTmplPhrasef("panel_logs_moderation_action_topic_"+tbit, topic.Link, topic.Title, actor.Link, actor.Name)
}
return fmt.Sprintf(out, topic.Link, topic.Title, actor.Link, actor.Name)
}
@@ -88,24 +87,16 @@ func modlogsElementType(action string, elementType string, elementID int, actor
out = topicElementTypeAction(action, elementType, elementID, actor, topic)
case "user":
targetUser := handleUnknownUser(common.Users.Get(elementID))
- switch action {
- case "ban":
- out = "%s was banned by %s"
- case "unban":
- out = "%s was unbanned by %s"
- case "activate":
- out = "%s was activated by %s"
- }
- out = fmt.Sprintf(out, targetUser.Link, targetUser.Name, actor.Link, actor.Name)
+ out = phrases.GetTmplPhrasef("panel_logs_moderation_action_user_"+action, targetUser.Link, targetUser.Name, actor.Link, actor.Name)
case "reply":
if action == "delete" {
topic := handleUnknownTopic(common.TopicByReplyID(elementID))
- out = fmt.Sprintf("A reply in %s was deleted by %s", topic.Link, topic.Title, actor.Link, actor.Name)
+ out = phrases.GetTmplPhrasef("panel_logs_moderation_action_reply_delete", topic.Link, topic.Title, actor.Link, actor.Name)
}
}
if out == "" {
- out = fmt.Sprintf("Unknown action '%s' on elementType '%s' by %s", action, elementType, actor.Link, actor.Name)
+ out = phrases.GetTmplPhrasef("panel_logs_moderation_action_unknown", action, elementType, actor.Link, actor.Name)
}
return out
}
diff --git a/routes/topic.go b/routes/topic.go
index d42dbdba..234e0910 100644
--- a/routes/topic.go
+++ b/routes/topic.go
@@ -51,7 +51,7 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, header
// Get the topic...
topic, err := common.GetTopicUser(&user, tid)
if err == sql.ErrNoRows {
- return common.NotFound(w, r, nil) // TODO: Can we add a simplified invocation of headerVars here? This is likely to be an extremely common NotFound
+ return common.NotFound(w, r, nil) // TODO: Can we add a simplified invocation of header here? This is likely to be an extremely common NotFound
} else if err != nil {
return common.InternalError(err, w, r)
}