17f85ceccf
Don't waste queries on groups without any users for the topic list. Bypass the GzipResponseWriter in RunThemeTemplate, so we get indirected through fewer layers of Write calls. Added an experimental flag for disabling fsnotify. Refactored the topic benchmarks to make them a little more flexible. Refactored a couple of benchmarks to reduce the amount of boilerplate. Fixed a bug in the forum list for Nox where topic titles broke onto multiple lines. Refactored the template transpiler to reduce the amount of boilerplate for generating template functions.
142 lines
3.4 KiB
Go
142 lines
3.4 KiB
Go
package main
|
|
|
|
import "strings"
|
|
|
|
type RouteImpl struct {
|
|
Name string
|
|
Path string
|
|
Action bool
|
|
NoHead bool
|
|
Vars []string
|
|
RunBefore []Runnable
|
|
|
|
Parent *RouteGroup
|
|
}
|
|
|
|
type Runnable struct {
|
|
Contents string
|
|
Literal bool
|
|
}
|
|
|
|
func (route *RouteImpl) Before(items ...string) *RouteImpl {
|
|
for _, item := range items {
|
|
route.RunBefore = append(route.RunBefore, Runnable{item, false})
|
|
}
|
|
return route
|
|
}
|
|
|
|
func (route *RouteImpl) LitBefore(items ...string) *RouteImpl {
|
|
for _, item := range items {
|
|
route.RunBefore = append(route.RunBefore, Runnable{item, true})
|
|
}
|
|
return route
|
|
}
|
|
|
|
func (route *RouteImpl) LitBeforeMultiline(items ...string) *RouteImpl {
|
|
for _, item := range items {
|
|
for _, line := range strings.Split(item, "\n") {
|
|
route.LitBefore(strings.TrimSpace(line))
|
|
}
|
|
}
|
|
return route
|
|
}
|
|
|
|
func (route *RouteImpl) hasBefore(items ...string) bool {
|
|
for _, item := range items {
|
|
if route.hasBeforeItem(item) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (route *RouteImpl) hasBeforeItem(item string) bool {
|
|
for _, before := range route.RunBefore {
|
|
if before.Contents == item {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (route *RouteImpl) NoGzip() *RouteImpl {
|
|
return route.LitBeforeMultiline(`gzw, ok := w.(common.GzipResponseWriter)
|
|
if ok {
|
|
w = gzw.ResponseWriter
|
|
w.Header().Del("Content-Type")
|
|
w.Header().Del("Content-Encoding")
|
|
}`)
|
|
}
|
|
|
|
func (route *RouteImpl) NoHeader() *RouteImpl {
|
|
route.NoHead = true
|
|
return route
|
|
}
|
|
|
|
func blankRoute() *RouteImpl {
|
|
return &RouteImpl{"", "", false, false, []string{}, []Runnable{}, nil}
|
|
}
|
|
|
|
func route(fname string, path string, action bool, special bool, args ...string) *RouteImpl {
|
|
return &RouteImpl{fname, path, action, special, args, []Runnable{}, nil}
|
|
}
|
|
|
|
func View(fname string, path string, args ...string) *RouteImpl {
|
|
return route(fname, path, false, false, args...)
|
|
}
|
|
|
|
func MemberView(fname string, path string, args ...string) *RouteImpl {
|
|
route := route(fname, path, false, false, args...)
|
|
if !route.hasBefore("SuperModOnly", "AdminOnly") {
|
|
route.Before("MemberOnly")
|
|
}
|
|
return route
|
|
}
|
|
|
|
func ModView(fname string, path string, args ...string) *RouteImpl {
|
|
route := route(fname, path, false, false, args...)
|
|
if !route.hasBefore("AdminOnly") {
|
|
route.Before("SuperModOnly")
|
|
}
|
|
return route
|
|
}
|
|
|
|
func Action(fname string, path string, args ...string) *RouteImpl {
|
|
route := route(fname, path, true, false, args...)
|
|
route.Before("NoSessionMismatch")
|
|
if !route.hasBefore("SuperModOnly", "AdminOnly") {
|
|
route.Before("MemberOnly")
|
|
}
|
|
return route
|
|
}
|
|
|
|
func AnonAction(fname string, path string, args ...string) *RouteImpl {
|
|
return route(fname, path, true, false, args...).Before("ParseForm")
|
|
}
|
|
|
|
func Special(fname string, path string, args ...string) *RouteImpl {
|
|
return route(fname, path, false, true, args...).LitBefore("req.URL.Path += extraData")
|
|
}
|
|
|
|
// Make this it's own type to force the user to manipulate methods on it to set parameters
|
|
type uploadAction struct {
|
|
Route *RouteImpl
|
|
}
|
|
|
|
func UploadAction(fname string, path string, args ...string) *uploadAction {
|
|
route := route(fname, path, true, false, args...)
|
|
if !route.hasBefore("SuperModOnly", "AdminOnly") {
|
|
route.Before("MemberOnly")
|
|
}
|
|
return &uploadAction{route}
|
|
}
|
|
|
|
func (action *uploadAction) MaxSizeVar(varName string) *RouteImpl {
|
|
action.Route.LitBeforeMultiline(`err = common.HandleUploadRoute(w,req,user,` + varName + `)
|
|
if err != nil {
|
|
return err
|
|
}`)
|
|
action.Route.Before("NoUploadSessionMismatch")
|
|
return action.Route
|
|
}
|