Add ActivityMatches store impl.

Comment out errorBuffer.
Optimise LogWarning() with a string builder.
Avoid allocing byte slice in MicroNotFound()
Rename basePage to bp.
Reduce boilerplate.
This commit is contained in:
Azareal 2021-04-28 18:39:08 +10:00
parent 01a19ede79
commit 0c1f5cac94
5 changed files with 150 additions and 88 deletions

View File

@ -0,0 +1,54 @@
package common
import (
"database/sql"
qgen "github.com/Azareal/Gosora/query_gen"
)
var ActivityMatches ActivityStreamMatches
type ActivityStreamMatches interface {
Add(watcher, asid int) error
Delete(watcher, asid int) error
DeleteAndCountChanged(watcher, asid int) (int, error)
CountAsid(asid int) int
}
type DefaultActivityStreamMatches struct {
add *sql.Stmt
delete *sql.Stmt
countAsid *sql.Stmt
}
func NewDefaultActivityStreamMatches(acc *qgen.Accumulator) (*DefaultActivityStreamMatches, error) {
asm := "activity_stream_matches"
return &DefaultActivityStreamMatches{
add: acc.Insert(asm).Columns("watcher,asid").Fields("?,?").Prepare(),
delete: acc.Delete(asm).Where("watcher=? AND asid=?").Prepare(),
countAsid: acc.Count(asm).Where("asid=?").Prepare(),
}, acc.FirstError()
}
func (s *DefaultActivityStreamMatches) Add(watcher, asid int) error {
_, e := s.add.Exec(watcher, asid)
return e
}
func (s *DefaultActivityStreamMatches) Delete(watcher, asid int) error {
_, e := s.delete.Exec(watcher, asid)
return e
}
func (s *DefaultActivityStreamMatches) DeleteAndCountChanged(watcher, asid int) (int, error) {
res, e := s.delete.Exec(watcher, asid)
if e != nil {
return 0, e
}
c64, e := res.RowsAffected()
return int(c64), e
}
func (s *DefaultActivityStreamMatches) CountAsid(asid int) int {
return Countf(s.countAsid, asid)
}

View File

@ -7,8 +7,9 @@ import (
"runtime/debug" "runtime/debug"
"strings" "strings"
"sync" "sync"
"sync/atomic"
"github.com/Azareal/Gosora/common/phrases" p "github.com/Azareal/Gosora/common/phrases"
) )
type ErrorItem struct { type ErrorItem struct {
@ -20,7 +21,8 @@ type ErrorItem struct {
// TODO: Use the errorBuffer variable to construct the system log in the Control Panel. Should we log errors caused by users too? Or just collect statistics on those or do nothing? Intercept recover()? Could we intercept the logger instead here? We might get too much information, if we intercept the logger, maybe make it part of the Debug page? // TODO: Use the errorBuffer variable to construct the system log in the Control Panel. Should we log errors caused by users too? Or just collect statistics on those or do nothing? Intercept recover()? Could we intercept the logger instead here? We might get too much information, if we intercept the logger, maybe make it part of the Debug page?
// ? - Should we pass Header / HeaderLite rather than forcing the errors to pull the global Header instance? // ? - Should we pass Header / HeaderLite rather than forcing the errors to pull the global Header instance?
var errorBufferMutex sync.RWMutex var errorBufferMutex sync.RWMutex
var errorBuffer []ErrorItem //var errorBuffer []ErrorItem
var ErrorCountSinceStartup int64
//var notfoundCountPerSecond int //var notfoundCountPerSecond int
//var nopermsCountPerSecond int //var nopermsCountPerSecond int
@ -110,24 +112,29 @@ func LogError(err error, extra ...string) {
} }
func LogWarning(err error, extra ...string) { func LogWarning(err error, extra ...string) {
var errmsg string var esb strings.Builder
for _, extraBit := range extra { for _, extraBit := range extra {
errmsg += extraBit + "\n" esb.WriteString(extraBit)
esb.WriteRune(10)
} }
if err == nil { if err == nil {
errmsg += "nil error found" esb.WriteString("nil error found")
} else { } else {
errmsg += err.Error() esb.WriteString(err.Error())
} }
esb.WriteRune(10)
errmsg := esb.String()
errorBufferMutex.Lock() errorBufferMutex.Lock()
defer errorBufferMutex.Unlock() defer errorBufferMutex.Unlock()
stack := debug.Stack() // debug.Stack() can't be executed concurrently, so we'll guard this with a mutex too stack := debug.Stack() // debug.Stack() can't be executed concurrently, so we'll guard this with a mutex too
Err(errmsg+"\n", string(stack)) Err(errmsg, string(stack))
errorBuffer = append(errorBuffer, ErrorItem{err, stack}) //errorBuffer = append(errorBuffer, ErrorItem{err, stack})
atomic.AddInt64(&ErrorCountSinceStartup,1)
} }
func errorHeader(w http.ResponseWriter, user *User, title string) *Header { func errorHeader(w http.ResponseWriter, u *User, title string) *Header {
h := DefaultHeader(w, user) h := DefaultHeader(w, u)
h.Title = title h.Title = title
h.Zone = "error" h.Zone = "error"
return h return h
@ -138,7 +145,7 @@ func errorHeader(w http.ResponseWriter, user *User, title string) *Header {
// ? - Add a user parameter? // ? - Add a user parameter?
// ! Do not call CustomError here or we might get an error loop // ! Do not call CustomError here or we might get an error loop
func InternalError(err error, w http.ResponseWriter, r *http.Request) RouteError { func InternalError(err error, w http.ResponseWriter, r *http.Request) RouteError {
pi := ErrorPage{errorHeader(w, &GuestUser, phrases.GetErrorPhrase("internal_error_title")), phrases.GetErrorPhrase("internal_error_body")} pi := ErrorPage{errorHeader(w, &GuestUser, p.GetErrorPhrase("internal_error_title")), p.GetErrorPhrase("internal_error_body")}
handleErrorTemplate(w, r, pi, 500) handleErrorTemplate(w, r, pi, 500)
LogError(err) LogError(err)
return HandledRouteError() return HandledRouteError()
@ -157,14 +164,14 @@ func InternalErrorJSQ(err error, w http.ResponseWriter, r *http.Request, js bool
// ? - Add a user parameter? // ? - Add a user parameter?
func InternalErrorJS(err error, w http.ResponseWriter, r *http.Request) RouteError { func InternalErrorJS(err error, w http.ResponseWriter, r *http.Request) RouteError {
w.WriteHeader(500) w.WriteHeader(500)
writeJsonError(phrases.GetErrorPhrase("internal_error_body"), w) writeJsonError(p.GetErrorPhrase("internal_error_body"), w)
LogError(err) LogError(err)
return HandledRouteError() return HandledRouteError()
} }
// When the task system detects if the database is down, some database errors might slip by this // When the task system detects if the database is down, some database errors might slip by this
func DatabaseError(w http.ResponseWriter, r *http.Request) RouteError { func DatabaseError(w http.ResponseWriter, r *http.Request) RouteError {
pi := ErrorPage{errorHeader(w, &GuestUser, phrases.GetErrorPhrase("internal_error_title")), phrases.GetErrorPhrase("internal_error_body")} pi := ErrorPage{errorHeader(w, &GuestUser, p.GetErrorPhrase("internal_error_title")), p.GetErrorPhrase("internal_error_body")}
handleErrorTemplate(w, r, pi, 500) handleErrorTemplate(w, r, pi, 500)
return HandledRouteError() return HandledRouteError()
} }
@ -173,7 +180,7 @@ func InternalErrorXML(err error, w http.ResponseWriter, r *http.Request) RouteEr
w.Header().Set("Content-Type", "application/xml") w.Header().Set("Content-Type", "application/xml")
w.WriteHeader(500) w.WriteHeader(500)
w.Write([]byte(`<?xml version="1.0"encoding="UTF-8"?> w.Write([]byte(`<?xml version="1.0"encoding="UTF-8"?>
<error>` + phrases.GetErrorPhrase("internal_error_body") + `</error>`)) <error>` + p.GetErrorPhrase("internal_error_body") + `</error>`))
LogError(err) LogError(err)
return HandledRouteError() return HandledRouteError()
} }
@ -183,14 +190,14 @@ func SilentInternalErrorXML(err error, w http.ResponseWriter, r *http.Request) R
w.Header().Set("Content-Type", "application/xml") w.Header().Set("Content-Type", "application/xml")
w.WriteHeader(500) w.WriteHeader(500)
w.Write([]byte(`<?xml version="1.0"encoding="UTF-8"?> w.Write([]byte(`<?xml version="1.0"encoding="UTF-8"?>
<error>` + phrases.GetErrorPhrase("internal_error_body") + `</error>`)) <error>` + p.GetErrorPhrase("internal_error_body") + `</error>`))
log.Print("InternalError: ", err) log.Print("InternalError: ", err)
return HandledRouteError() return HandledRouteError()
} }
// ! Do not call CustomError here otherwise we might get an error loop // ! Do not call CustomError here otherwise we might get an error loop
func PreError(errmsg string, w http.ResponseWriter, r *http.Request) RouteError { func PreError(errmsg string, w http.ResponseWriter, r *http.Request) RouteError {
pi := ErrorPage{errorHeader(w, &GuestUser, phrases.GetErrorPhrase("error_title")), errmsg} pi := ErrorPage{errorHeader(w, &GuestUser, p.GetErrorPhrase("error_title")), errmsg}
handleErrorTemplate(w, r, pi, 500) handleErrorTemplate(w, r, pi, 500)
return HandledRouteError() return HandledRouteError()
} }
@ -212,33 +219,33 @@ func PreErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, js bool)
// 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 // 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 { /*func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user *User) RouteError {
w.WriteHeader(500) w.WriteHeader(500)
pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("local_error_title")), errmsg} pi := ErrorPage{errorHeader(w, user, p.GetErrorPhrase("local_error_title")), errmsg}
handleErrorTemplate(w, r, pi) handleErrorTemplate(w, r, pi)
return HandledRouteError() return HandledRouteError()
}*/ }*/
func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user *User) RouteError { func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, u *User) RouteError {
return SimpleError(errmsg, w, r, errorHeader(w, user, "")) return SimpleError(errmsg, w, r, errorHeader(w, u, ""))
} }
func LocalErrorf(errmsg string, w http.ResponseWriter, r *http.Request, user *User, params ...interface{}) RouteError { func LocalErrorf(errmsg string, w http.ResponseWriter, r *http.Request, u *User, params ...interface{}) RouteError {
return LocalError(fmt.Sprintf(errmsg, params), w, r, user) return LocalError(fmt.Sprintf(errmsg, params), w, r, u)
} }
func SimpleError(errmsg string, w http.ResponseWriter, r *http.Request, h *Header) RouteError { func SimpleError(errmsg string, w http.ResponseWriter, r *http.Request, h *Header) RouteError {
if h == nil { if h == nil {
h = errorHeader(w, &GuestUser, phrases.GetErrorPhrase("local_error_title")) h = errorHeader(w, &GuestUser, p.GetErrorPhrase("local_error_title"))
} else { } else {
h.Title = phrases.GetErrorPhrase("local_error_title") h.Title = p.GetErrorPhrase("local_error_title")
} }
pi := ErrorPage{h, errmsg} pi := ErrorPage{h, errmsg}
handleErrorTemplate(w, r, pi, 500) handleErrorTemplate(w, r, pi, 500)
return HandledRouteError() return HandledRouteError()
} }
func LocalErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, user *User, js bool) RouteError { func LocalErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, u *User, js bool) RouteError {
if !js { if !js {
return SimpleError(errmsg, w, r, errorHeader(w, user, "")) return SimpleError(errmsg, w, r, errorHeader(w, u, ""))
} }
return LocalErrorJS(errmsg, w, r) return LocalErrorJS(errmsg, w, r)
} }
@ -252,27 +259,27 @@ func LocalErrorJS(errmsg string, w http.ResponseWriter, r *http.Request) RouteEr
// TODO: We might want to centralise the error logic in the future and just return what the error handler needs to construct the response rather than handling it here // TODO: We might want to centralise the error logic in the future and just return what the error handler needs to construct the response rather than handling it here
// NoPermissions is an error shown to the end-user when they try to access an area which they aren't authorised to access // 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, u *User) RouteError { func NoPermissions(w http.ResponseWriter, r *http.Request, u *User) RouteError {
pi := ErrorPage{errorHeader(w, u, phrases.GetErrorPhrase("no_permissions_title")), phrases.GetErrorPhrase("no_permissions_body")} pi := ErrorPage{errorHeader(w, u, p.GetErrorPhrase("no_permissions_title")), p.GetErrorPhrase("no_permissions_body")}
handleErrorTemplate(w, r, pi, 403) handleErrorTemplate(w, r, pi, 403)
return HandledRouteError() return HandledRouteError()
} }
func NoPermissionsJSQ(w http.ResponseWriter, r *http.Request, user *User, js bool) RouteError { func NoPermissionsJSQ(w http.ResponseWriter, r *http.Request, u *User, js bool) RouteError {
if !js { if !js {
return NoPermissions(w, r, user) return NoPermissions(w, r, u)
} }
return NoPermissionsJS(w, r, user) return NoPermissionsJS(w, r, u)
} }
func NoPermissionsJS(w http.ResponseWriter, r *http.Request, user *User) RouteError { func NoPermissionsJS(w http.ResponseWriter, r *http.Request, u *User) RouteError {
w.WriteHeader(403) w.WriteHeader(403)
writeJsonError(phrases.GetErrorPhrase("no_permissions_body"), w) writeJsonError(p.GetErrorPhrase("no_permissions_body"), w)
return HandledRouteError() 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? // ? - 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 { func Banned(w http.ResponseWriter, r *http.Request, u *User) RouteError {
pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("banned_title")), phrases.GetErrorPhrase("banned_body")} pi := ErrorPage{errorHeader(w, u, p.GetErrorPhrase("banned_title")), p.GetErrorPhrase("banned_body")}
handleErrorTemplate(w, r, pi, 403) handleErrorTemplate(w, r, pi, 403)
return HandledRouteError() return HandledRouteError()
} }
@ -286,50 +293,51 @@ func BannedJSQ(w http.ResponseWriter, r *http.Request, user *User, js bool) Rout
return BannedJS(w, r, user) return BannedJS(w, r, user)
} }
func BannedJS(w http.ResponseWriter, r *http.Request, user *User) RouteError { func BannedJS(w http.ResponseWriter, r *http.Request, u *User) RouteError {
w.WriteHeader(403) w.WriteHeader(403)
writeJsonError(phrases.GetErrorPhrase("banned_body"), w) writeJsonError(p.GetErrorPhrase("banned_body"), w)
return HandledRouteError() return HandledRouteError()
} }
// nolint // nolint
func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user *User, js bool) RouteError { func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, u *User, js bool) RouteError {
if !js { if !js {
return LoginRequired(w, r, user) return LoginRequired(w, r, u)
} }
return LoginRequiredJS(w, r, user) return LoginRequiredJS(w, r, u)
} }
// ? - Where is this used? Should we use it more? // ? - Where is this used? Should we use it more?
// LoginRequired is an error shown to the end-user when they try to access an area which requires them to login // 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 { func LoginRequired(w http.ResponseWriter, r *http.Request, u *User) RouteError {
return CustomError(phrases.GetErrorPhrase("login_required_body"), 401, phrases.GetErrorPhrase("no_permissions_title"), w, r, nil, user) return CustomError(p.GetErrorPhrase("login_required_body"), 401, p.GetErrorPhrase("no_permissions_title"), w, r, nil, u)
} }
// nolint // nolint
func LoginRequiredJS(w http.ResponseWriter, r *http.Request, user *User) RouteError { func LoginRequiredJS(w http.ResponseWriter, r *http.Request, u *User) RouteError {
w.WriteHeader(401) w.WriteHeader(401)
writeJsonError(phrases.GetErrorPhrase("login_required_body"), w) writeJsonError(p.GetErrorPhrase("login_required_body"), w)
return HandledRouteError() return HandledRouteError()
} }
// SecurityError is used whenever a session mismatch is found // SecurityError is used whenever a session mismatch is found
// ? - Should we add JS and JSQ versions of this? // ? - Should we add JS and JSQ versions of this?
func SecurityError(w http.ResponseWriter, r *http.Request, user *User) RouteError { func SecurityError(w http.ResponseWriter, r *http.Request, u *User) RouteError {
pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("security_error_title")), phrases.GetErrorPhrase("security_error_body")} pi := ErrorPage{errorHeader(w, u, p.GetErrorPhrase("security_error_title")), p.GetErrorPhrase("security_error_body")}
w.Header().Set("Content-Type", "text/html;charset=utf-8") w.Header().Set("Content-Type", "text/html;charset=utf-8")
w.WriteHeader(403) w.WriteHeader(403)
err := RenderTemplateAlias("error", "security_error", w, r, pi.Header, pi) e := RenderTemplateAlias("error", "security_error", w, r, pi.Header, pi)
if err != nil { if e != nil {
LogError(err) LogError(e)
} }
return HandledRouteError() return HandledRouteError()
} }
var microNotFoundBytes = []byte("file not found")
func MicroNotFound(w http.ResponseWriter, r *http.Request) RouteError { func MicroNotFound(w http.ResponseWriter, r *http.Request) RouteError {
w.Header().Set("Content-Type", "text/html;charset=utf-8") w.Header().Set("Content-Type", "text/html;charset=utf-8")
w.WriteHeader(404) w.WriteHeader(404)
_, _ = w.Write([]byte("file not found")) _, _ = w.Write(microNotFoundBytes)
return HandledRouteError() return HandledRouteError()
} }
@ -337,13 +345,13 @@ func MicroNotFound(w http.ResponseWriter, r *http.Request) RouteError {
// ? - Add a JSQ version of this? // ? - Add a JSQ version of this?
// ? - Add a user parameter? // ? - Add a user parameter?
func NotFound(w http.ResponseWriter, r *http.Request, h *Header) RouteError { func NotFound(w http.ResponseWriter, r *http.Request, h *Header) RouteError {
return CustomError(phrases.GetErrorPhrase("not_found_body"), 404, phrases.GetErrorPhrase("not_found_title"), w, r, h, &GuestUser) return CustomError(p.GetErrorPhrase("not_found_body"), 404, p.GetErrorPhrase("not_found_title"), w, r, h, &GuestUser)
} }
// ? - Add a user parameter? // ? - Add a user parameter?
func NotFoundJS(w http.ResponseWriter, r *http.Request) RouteError { func NotFoundJS(w http.ResponseWriter, r *http.Request) RouteError {
w.WriteHeader(404) w.WriteHeader(404)
writeJsonError(phrases.GetErrorPhrase("not_found_body"), w) writeJsonError(p.GetErrorPhrase("not_found_body"), w)
return HandledRouteError() return HandledRouteError()
} }
@ -373,11 +381,11 @@ func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWri
} }
// CustomErrorJSQ is a version of CustomError which lets us handle both JSON and regular pages depending on how it's being accessed // CustomErrorJSQ is a version of CustomError which lets us handle both JSON and regular pages depending on how it's being accessed
func CustomErrorJSQ(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, h *Header, user *User, js bool) RouteError { func CustomErrorJSQ(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, h *Header, u *User, js bool) RouteError {
if !js { if !js {
return CustomError(errmsg, errcode, errtitle, w, r, h, user) return CustomError(errmsg, errcode, errtitle, w, r, h, u)
} }
return CustomErrorJS(errmsg, errcode, w, r, user) return CustomErrorJS(errmsg, errcode, w, r, u)
} }
// CustomErrorJS is the pure JSON version of CustomError // CustomErrorJS is the pure JSON version of CustomError

View File

@ -12,15 +12,15 @@ import (
) )
func Forums(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError { func Forums(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "forums", "forums") bp, ferr := buildBasePage(w, r, u, "forums", "forums")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
if !u.Perms.ManageForums { if !u.Perms.ManageForums {
return c.NoPermissions(w, r, u) return c.NoPermissions(w, r, u)
} }
basePage.Header.AddScript("Sortable-1.4.0/Sortable.min.js") bp.Header.AddScript("Sortable-1.4.0/Sortable.min.js")
basePage.Header.AddScriptAsync("panel_forums.js") bp.Header.AddScriptAsync("panel_forums.js")
// TODO: Paginate this? // TODO: Paginate this?
var forumList []interface{} var forumList []interface{}
@ -41,15 +41,15 @@ func Forums(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
} }
if r.FormValue("created") == "1" { if r.FormValue("created") == "1" {
basePage.AddNotice("panel_forum_created") bp.AddNotice("panel_forum_created")
} else if r.FormValue("deleted") == "1" { } else if r.FormValue("deleted") == "1" {
basePage.AddNotice("panel_forum_deleted") bp.AddNotice("panel_forum_deleted")
} else if r.FormValue("updated") == "1" { } else if r.FormValue("updated") == "1" {
basePage.AddNotice("panel_forum_updated") bp.AddNotice("panel_forum_updated")
} }
pi := c.PanelPage{basePage, forumList, nil} pi := c.PanelPage{bp, forumList, nil}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_forums", &pi}) return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_forums", &pi})
} }
func ForumsCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError { func ForumsCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
@ -338,7 +338,7 @@ func forumPermsExtractDash(paramList string) (fid, gid int, e error) {
} }
func ForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, u *c.User, paramList string) c.RouteError { func ForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, u *c.User, paramList string) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "edit_forum", "forums") bp, ferr := buildBasePage(w, r, u, "edit_forum", "forums")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -388,11 +388,11 @@ func ForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, u *c.User, p
addToggle("MoveTopic", fp.MoveTopic) addToggle("MoveTopic", fp.MoveTopic)
if r.FormValue("updated") == "1" { if r.FormValue("updated") == "1" {
basePage.AddNotice("panel_forum_perms_updated") bp.AddNotice("panel_forum_perms_updated")
} }
pi := c.PanelEditForumGroupPage{basePage, f.ID, gid, f.Name, f.Desc, f.Active, f.Preset, formattedPermList} pi := c.PanelEditForumGroupPage{bp, f.ID, gid, f.Name, f.Desc, f.Active, f.Preset, formattedPermList}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_forum_edit_perms", &pi}) return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_forum_edit_perms", &pi})
} }
func ForumsEditPermsAdvanceSubmit(w http.ResponseWriter, r *http.Request, u *c.User, paramList string) c.RouteError { func ForumsEditPermsAdvanceSubmit(w http.ResponseWriter, r *http.Request, u *c.User, paramList string) c.RouteError {

View File

@ -13,7 +13,7 @@ import (
// TODO: Link the usernames for successful registrations to the profiles // TODO: Link the usernames for successful registrations to the profiles
func LogsRegs(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError { func LogsRegs(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "registration_logs", "logs") bp, ferr := buildBasePage(w, r, u, "registration_logs", "logs")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -32,20 +32,20 @@ func LogsRegs(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
} }
pageList := c.Paginate(page, lastPage, 5) pageList := c.Paginate(page, lastPage, 5)
pi := c.PanelRegLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}} pi := c.PanelRegLogsPage{bp, llist, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_reglogs", pi}) return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_reglogs", pi})
} }
// TODO: Log errors when something really screwy is going on? // TODO: Log errors when something really screwy is going on?
// TODO: Base the slugs on the localised usernames? // TODO: Base the slugs on the localised usernames?
func handleUnknownUser(u *c.User, err error) *c.User { func handleUnknownUser(u *c.User, e error) *c.User {
if err != nil { if e != nil {
return &c.User{Name: p.GetTmplPhrase("user_unknown"), Link: c.BuildProfileURL("unknown", 0)} return &c.User{Name: p.GetTmplPhrase("user_unknown"), Link: c.BuildProfileURL("unknown", 0)}
} }
return u return u
} }
func handleUnknownTopic(t *c.Topic, err error) *c.Topic { func handleUnknownTopic(t *c.Topic, e error) *c.Topic {
if err != nil { if e != nil {
return &c.Topic{Title: p.GetTmplPhrase("topic_unknown"), Link: c.BuildTopicURL("unknown", 0)} return &c.Topic{Title: p.GetTmplPhrase("topic_unknown"), Link: c.BuildTopicURL("unknown", 0)}
} }
return t return t
@ -169,7 +169,7 @@ func adminlogsElementType(action, elementType string, elementID int, actor *c.Us
} }
func LogsMod(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError { func LogsMod(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "mod_logs", "logs") bp, ferr := buildBasePage(w, r, u, "mod_logs", "logs")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -189,12 +189,12 @@ func LogsMod(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
} }
pageList := c.Paginate(page, lastPage, 5) pageList := c.Paginate(page, lastPage, 5)
pi := c.PanelLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}} pi := c.PanelLogsPage{bp, llist, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_modlogs", pi}) return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_modlogs", pi})
} }
func LogsAdmin(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError { func LogsAdmin(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "admin_logs", "logs") bp, ferr := buildBasePage(w, r, u, "admin_logs", "logs")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -214,6 +214,6 @@ func LogsAdmin(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
} }
pageList := c.Paginate(page, lastPage, 5) pageList := c.Paginate(page, lastPage, 5)
pi := c.PanelLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}} pi := c.PanelLogsPage{bp, llist, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_adminlogs", pi}) return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_adminlogs", pi})
} }

View File

@ -9,14 +9,14 @@ import (
) )
func Pages(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError { func Pages(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "pages", "pages") bp, ferr := buildBasePage(w, r, u, "pages", "pages")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
if r.FormValue("created") == "1" { if r.FormValue("created") == "1" {
basePage.AddNotice("panel_page_created") bp.AddNotice("panel_page_created")
} else if r.FormValue("deleted") == "1" { } else if r.FormValue("deleted") == "1" {
basePage.AddNotice("panel_page_deleted") bp.AddNotice("panel_page_deleted")
} }
// TODO: Test the pagination here // TODO: Test the pagination here
@ -31,8 +31,8 @@ func Pages(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
} }
pageList := c.Paginate(page, lastPage, 5) pageList := c.Paginate(page, lastPage, 5)
pi := c.PanelCustomPagesPage{basePage, cPages, c.Paginator{pageList, page, lastPage}} pi := c.PanelCustomPagesPage{bp, cPages, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_list", "", "panel_pages", &pi}) return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "panel_page_list", "", "panel_pages", &pi})
} }
func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError { func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
@ -72,12 +72,12 @@ func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.Rout
} }
func PagesEdit(w http.ResponseWriter, r *http.Request, u *c.User, spid string) c.RouteError { func PagesEdit(w http.ResponseWriter, r *http.Request, u *c.User, spid string) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "pages_edit", "pages") bp, ferr := buildBasePage(w, r, u, "pages_edit", "pages")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
if r.FormValue("updated") == "1" { if r.FormValue("updated") == "1" {
basePage.AddNotice("panel_page_updated") bp.AddNotice("panel_page_updated")
} }
pid, err := strconv.Atoi(spid) pid, err := strconv.Atoi(spid)
@ -86,13 +86,13 @@ func PagesEdit(w http.ResponseWriter, r *http.Request, u *c.User, spid string) c
} }
page, err := c.Pages.Get(pid) page, err := c.Pages.Get(pid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.NotFound(w, r, basePage.Header) return c.NotFound(w, r, bp.Header)
} else if err != nil { } else if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
pi := c.PanelCustomPageEditPage{basePage, page} pi := c.PanelCustomPageEditPage{bp, page}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_edit", "", "panel_pages_edit", &pi}) return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "panel_page_edit", "", "panel_pages_edit", &pi})
} }
func PagesEditSubmit(w http.ResponseWriter, r *http.Request, u *c.User, spid string) c.RouteError { func PagesEditSubmit(w http.ResponseWriter, r *http.Request, u *c.User, spid string) c.RouteError {