hoist runnables shared among all routes in a route group to the route group to reduce code duplication

rewrite router gen to make indentation maintenance easier
This commit is contained in:
Azareal 2021-03-18 10:22:28 +10:00
parent 75561508c8
commit b9d94d0888
3 changed files with 255 additions and 287 deletions

View File

@ -1529,8 +1529,6 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
return err return err
} }
switch(req.URL.Path) {
case "/report/submit/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
if err != nil { if err != nil {
return err return err
@ -1541,6 +1539,8 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
return err return err
} }
switch(req.URL.Path) {
case "/report/submit/":
err = routes.ReportSubmit(w,req,user,extraData) err = routes.ReportSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(12, cn) co.RouteViewCounter.Bump3(12, cn)
} }
@ -2459,14 +2459,14 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
co.RouteViewCounter.Bump3(125, cn) co.RouteViewCounter.Bump3(125, cn)
} }
case "/users": case "/users":
switch(req.URL.Path) { err = c.MemberOnly(w,req,user)
case "/users/ban/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil { if err != nil {
return err return err
} }
err = c.MemberOnly(w,req,user) switch(req.URL.Path) {
case "/users/ban/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil { if err != nil {
return err return err
} }
@ -2479,11 +2479,6 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
return err return err
} }
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.UnbanUser(w,req,user,extraData) err = routes.UnbanUser(w,req,user,extraData)
co.RouteViewCounter.Bump3(127, cn) co.RouteViewCounter.Bump3(127, cn)
case "/users/activate/": case "/users/activate/":
@ -2492,19 +2487,9 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
return err return err
} }
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ActivateUser(w,req,user,extraData) err = routes.ActivateUser(w,req,user,extraData)
co.RouteViewCounter.Bump3(128, cn) co.RouteViewCounter.Bump3(128, cn)
case "/users/ips/": case "/users/ips/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
h, err := c.UserCheckNano(w,req,user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
@ -2517,11 +2502,6 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
return err return err
} }
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.DeletePostsSubmit(w,req,user,extraData) err = routes.DeletePostsSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(130, cn) co.RouteViewCounter.Bump3(130, cn)
} }
@ -2702,13 +2682,13 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
co.RouteViewCounter.Bump3(143, cn) co.RouteViewCounter.Bump3(143, cn)
} }
case "/reply": case "/reply":
switch(req.URL.Path) {
case "/reply/create/":
err = c.MemberOnly(w,req,user) err = c.MemberOnly(w,req,user)
if err != nil { if err != nil {
return err return err
} }
switch(req.URL.Path) {
case "/reply/create/":
err = c.HandleUploadRoute(w,req,user,int(c.Config.MaxRequestSize)) err = c.HandleUploadRoute(w,req,user,int(c.Config.MaxRequestSize))
if err != nil { if err != nil {
return err return err
@ -2726,11 +2706,6 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
return err return err
} }
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ReplyEditSubmit(w,req,user,extraData) err = routes.ReplyEditSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(145, cn) co.RouteViewCounter.Bump3(145, cn)
case "/reply/delete/submit/": case "/reply/delete/submit/":
@ -2739,11 +2714,6 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
return err return err
} }
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ReplyDeleteSubmit(w,req,user,extraData) err = routes.ReplyDeleteSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(146, cn) co.RouteViewCounter.Bump3(146, cn)
case "/reply/like/submit/": case "/reply/like/submit/":
@ -2752,11 +2722,6 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
return err return err
} }
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ReplyLikeSubmit(w,req,user,extraData) err = routes.ReplyLikeSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(147, cn) co.RouteViewCounter.Bump3(147, cn)
case "/reply/unlike/submit/": case "/reply/unlike/submit/":
@ -2765,19 +2730,9 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
return err return err
} }
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ReplyUnlikeSubmit(w,req,user,extraData) err = routes.ReplyUnlikeSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(148, cn) co.RouteViewCounter.Bump3(148, cn)
case "/reply/attach/add/submit/": case "/reply/attach/add/submit/":
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = c.HandleUploadRoute(w,req,user,int(c.Config.MaxRequestSize)) err = c.HandleUploadRoute(w,req,user,int(c.Config.MaxRequestSize))
if err != nil { if err != nil {
return err return err
@ -2795,17 +2750,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
return err return err
} }
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData) err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(150, cn) co.RouteViewCounter.Bump3(150, cn)
} }
case "/profile": case "/profile":
switch(req.URL.Path) {
case "/profile/reply/create/":
err = c.NoSessionMismatch(w,req,user) err = c.NoSessionMismatch(w,req,user)
if err != nil { if err != nil {
return err return err
@ -2816,32 +2764,14 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *
return err return err
} }
switch(req.URL.Path) {
case "/profile/reply/create/":
err = routes.ProfileReplyCreateSubmit(w,req,user) err = routes.ProfileReplyCreateSubmit(w,req,user)
co.RouteViewCounter.Bump3(151, cn) co.RouteViewCounter.Bump3(151, cn)
case "/profile/reply/edit/submit/": case "/profile/reply/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ProfileReplyEditSubmit(w,req,user,extraData) err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(152, cn) co.RouteViewCounter.Bump3(152, cn)
case "/profile/reply/delete/submit/": case "/profile/reply/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
if err != nil {
return err
}
err = c.MemberOnly(w,req,user)
if err != nil {
return err
}
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData) err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(153, cn) co.RouteViewCounter.Bump3(153, cn)
} }

View File

@ -49,65 +49,119 @@ func main() {
allRouteMap[name] = len(allRouteNames) - 1 allRouteMap[name] = len(allRouteNames) - 1
} }
mapIt("routes.Error") mapIt("routes.Error")
countToIndents := func(indent int) (indentor string) {
for i := 0; i < indent; i++ { var indentCache [20]string
indentor += "\t" countToIndents := func(ind int) string {
out := indentCache[ind]
if out != "" {
return out
} }
return indentor for i := 0; i < ind; i++ {
out += "\t"
} }
if ind < 20 {
indentCache[ind] = out
}
return out
}
/*o := func(indent int, str string) {
out += countToIndents(indent) + str
}*/
on := func(indent int, str string) {
out += "\n" + countToIndents(indent) + str
}
iferrn := func(indent int) {
ind := countToIndents(indent)
ind2 := countToIndents(indent + 1)
out += "\n" + ind + "if err != nil {"
out += "\n" + ind2 + "return err\n" + ind + "}"
}
runBefore := func(runnables []Runnable, indentCount int) (out string) { runBefore := func(runnables []Runnable, indentCount int) (out string) {
indent := countToIndents(indentCount) ind := countToIndents(indentCount)
if len(runnables) > 0 { if len(runnables) > 0 {
for _, runnable := range runnables { for _, runnable := range runnables {
if runnable.Literal { if runnable.Literal {
out += "\n\t" + indent + runnable.Contents out += "\n\t" + ind + runnable.Contents
} else { } else {
out += "\n" + indent + "err = c." + runnable.Contents + "(w,req,user)\n" + out += "\n" + ind + "err = c." + runnable.Contents + "(w,req,user)\n" +
indent + "if err != nil {\n" + ind + "if err != nil {\n" +
indent + "\treturn err\n" + ind + "\treturn err\n" +
indent + "}\n" + indent ind + "}\n" + ind
} }
} }
} }
return out return out
} }
userCheckNano := func(indent int, route *RouteImpl) {
on(indent, "h, err := c.UserCheckNano(w,req,user,cn)")
iferrn(indent)
vcpy := route.Vars
route.Vars = []string{"h"}
route.Vars = append(route.Vars, vcpy...)
}
writeRoute := func(indent int, r *RouteImpl) {
on(indent, "err = "+strings.Replace(r.Name, "common.", "c.", -1)+"(w,req,user")
for _, item := range r.Vars {
out += "," + item
}
out += `)`
}
for _, route := range r.routeList { for _, route := range r.routeList {
mapIt(route.Name) mapIt(route.Name)
end := len(route.Path) - 1 end := len(route.Path) - 1
out += "\n\t\tcase \"" + route.Path[0:end] + "\":" on(2, "case \""+route.Path[0:end]+"\":")
//out += "\n\t\t\tid = " + strconv.Itoa(allRouteMap[route.Name]) //on(3,"id = " + strconv.Itoa(allRouteMap[route.Name]))
out += runBefore(route.RunBefore, 4) out += runBefore(route.RunBefore, 3)
if !route.Action && !route.NoHead { if !route.Action && !route.NoHead {
//out += "\n\t\t\th, err := c.UserCheck(w,req,user)" //on(3,"h, err := c.UserCheck(w,req,user)")
out += "\n\t\t\th, err := c.UserCheckNano(w,req,user,cn)" userCheckNano(3, route)
out += "\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}"
vcpy := route.Vars
route.Vars = []string{"h"}
route.Vars = append(route.Vars, vcpy...)
} /* else if route.Name != "common.RouteWebsockets" { } /* else if route.Name != "common.RouteWebsockets" {
//out += "\n\t\t\tsa := time.Now()" //on(3,"sa := time.Now()")
//out += "\n\t\t\tcn := uutils.Nanotime()" //on(3,"cn := uutils.Nanotime()")
}*/ }*/
out += "\n\t\t\terr = " + strings.Replace(route.Name, "common.", "c.", -1) + "(w,req,user" writeRoute(3, route)
for _, item := range route.Vars {
out += "," + item
}
out += `)`
/*if !route.Action && !route.NoHead { /*if !route.Action && !route.NoHead {
out += "\n\t\t\tco.RouteViewCounter.Bump2(" + strconv.Itoa(allRouteMap[route.Name]) + ", h.StartedAt)" on(3,"co.RouteViewCounter.Bump2(" + strconv.Itoa(allRouteMap[route.Name]) + ", h.StartedAt)")
} else */if route.Name != "common.RouteWebsockets" { } else */if route.Name != "common.RouteWebsockets" {
//out += "\n\t\t\tco.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[route.Name]) + ")" //on(3,"co.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[route.Name]) + ")")
//out += "\n\t\t\tco.RouteViewCounter.Bump2(" + strconv.Itoa(allRouteMap[route.Name]) + ", sa)" //on(3,"co.RouteViewCounter.Bump2(" + strconv.Itoa(allRouteMap[route.Name]) + ", sa)")
out += "\n\t\t\tco.RouteViewCounter.Bump3(" + strconv.Itoa(allRouteMap[route.Name]) + ", cn)" on(3, "co.RouteViewCounter.Bump3("+strconv.Itoa(allRouteMap[route.Name])+", cn)")
}
}
// Hoist runnables which appear on every route to the route group to avoid code duplication
skipRunnableAntiDupe:
for _, g := range r.routeGroups {
dupeMap := make(map[string]int)
for _, route := range g.RouteList {
if len(route.RunBefore) == 0 {
continue skipRunnableAntiDupe
}
// TODO: What if there are duplicates of the same runnable on this route?
for _, runnable := range route.RunBefore {
dupeMap[runnable.Contents] += 1
}
}
// Unset entries which are already set on the route group
for _, gRunnable := range g.RunBefore {
delete(dupeMap, gRunnable.Contents)
}
for runnable, count := range dupeMap {
if count == len(g.RouteList) {
g.Before(runnable)
}
} }
} }
for _, group := range r.routeGroups { for _, group := range r.routeGroups {
end := len(group.Path) - 1 end := len(group.Path) - 1
out += "\n\t\tcase \"" + group.Path[0:end] + "\":" on(2, "case \""+group.Path[0:end]+"\":")
out += runBefore(group.RunBefore, 3) out += runBefore(group.RunBefore, 3)
out += "\n\t\t\tswitch(req.URL.Path) {" on(3, "switch(req.URL.Path) {")
defaultRoute := blankRoute() defaultRoute := blankRoute()
for _, route := range group.RouteList { for _, route := range group.RouteList {
@ -117,89 +171,72 @@ func main() {
} }
mapIt(route.Name) mapIt(route.Name)
out += "\n\t\t\t\tcase \"" + route.Path + "\":" on(4, "case \""+route.Path+"\":")
//out += "\n\t\t\t\t\tid = " + strconv.Itoa(allRouteMap[route.Name]) //on(5,"id = " + strconv.Itoa(allRouteMap[route.Name]))
if len(route.RunBefore) > 0 { if len(route.RunBefore) > 0 {
skipRunnable: skipRunnable:
for _, runnable := range route.RunBefore { for _, runnable := range route.RunBefore {
for _, gRunnable := range group.RunBefore { for _, gRunnable := range group.RunBefore {
if gRunnable.Contents == runnable.Contents { if gRunnable.Contents == runnable.Contents {
continue continue skipRunnable
}
f := func(e1, e2 string) bool {
return gRunnable.Contents == e1 && runnable.Contents == e2
} }
// TODO: Stop hard-coding these // TODO: Stop hard-coding these
if gRunnable.Contents == "AdminOnly" && runnable.Contents == "MemberOnly" { if f("AdminOnly", "MemberOnly") {
continue skipRunnable continue skipRunnable
} }
if gRunnable.Contents == "AdminOnly" && runnable.Contents == "SuperModOnly" { if f("AdminOnly", "SuperModOnly") {
continue skipRunnable continue skipRunnable
} }
if gRunnable.Contents == "SuperModOnly" && runnable.Contents == "MemberOnly" { if f("SuperModOnly", "MemberOnly") {
continue skipRunnable continue skipRunnable
} }
} }
if runnable.Literal { if runnable.Literal {
out += "\n\t\t\t\t\t" + runnable.Contents on(5, runnable.Contents)
} else { } else {
out += ` on(5, "err = c."+runnable.Contents+"(w,req,user)")
err = c.` + runnable.Contents + `(w,req,user) iferrn(5)
if err != nil { on(5, "")
return err
}
`
} }
} }
} }
if !route.Action && !route.NoHead && !group.NoHead { if !route.Action && !route.NoHead && !group.NoHead {
//out += "\n\t\t\t\th, err := c.UserCheck(w,req,user)" //on(5,"h, err := c.UserCheck(w,req,user)")
out += "\n\t\t\t\th, err := c.UserCheckNano(w,req,user,cn)" userCheckNano(5, route)
out += "\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}"
vcpy := route.Vars
route.Vars = []string{"h"}
route.Vars = append(route.Vars, vcpy...)
} else { } else {
//out += "\n\t\t\t\t\tcn := uutils.Nanotime()" //on(5, "cn := uutils.Nanotime()")
} }
out += "\n\t\t\t\t\terr = " + strings.Replace(route.Name, "common.", "c.", -1) + "(w,req,user" writeRoute(5, route)
for _, item := range route.Vars {
out += "," + item
}
out += ")"
/*if !route.Action && !route.NoHead && !group.NoHead { /*if !route.Action && !route.NoHead && !group.NoHead {
out += "\n\t\t\t\t\tco.RouteViewCounter.Bump2(" + strconv.Itoa(allRouteMap[route.Name]) + ", h.StartedAt)" on(5,"co.RouteViewCounter.Bump2(" + strconv.Itoa(allRouteMap[route.Name]) + ", h.StartedAt)")
} else {*/ } else {*/
//out += "\n\t\t\t\t\tco.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[route.Name]) + ")" //on(5,"co.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[route.Name]) + ")")
out += "\n\t\t\t\t\tco.RouteViewCounter.Bump3(" + strconv.Itoa(allRouteMap[route.Name]) + ", cn)" on(5, "co.RouteViewCounter.Bump3("+strconv.Itoa(allRouteMap[route.Name])+", cn)")
//} //}
} }
if defaultRoute.Name != "" { if defaultRoute.Name != "" {
mapIt(defaultRoute.Name) mapIt(defaultRoute.Name)
out += "\n\t\t\t\tdefault:" on(4, "default:")
//out += "\n\t\t\t\t\tid = " + strconv.Itoa(allRouteMap[defaultRoute.Name]) //on(5,"id = " + strconv.Itoa(allRouteMap[defaultRoute.Name]))
out += runBefore(defaultRoute.RunBefore, 4) out += runBefore(defaultRoute.RunBefore, 4)
if !defaultRoute.Action && !defaultRoute.NoHead && !group.NoHead { if !defaultRoute.Action && !defaultRoute.NoHead && !group.NoHead {
//out += "\n\t\t\t\t\th, err := c.UserCheck(w,req,user)" //on(5, "h, err := c.UserCheck(w,req,user)"
out += "\n\t\t\t\t\th, err := c.UserCheckNano(w,req,user,cn)" userCheckNano(5, defaultRoute)
out += "\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}"
vcpy := defaultRoute.Vars
defaultRoute.Vars = []string{"h"}
defaultRoute.Vars = append(defaultRoute.Vars, vcpy...)
} }
out += "\n\t\t\t\t\terr = " + strings.Replace(defaultRoute.Name, "common.", "c.", -1) + "(w,req,user" writeRoute(5, defaultRoute)
for _, item := range defaultRoute.Vars {
out += ", " + item
}
out += ")"
/*if !defaultRoute.Action && !defaultRoute.NoHead && !group.NoHead { /*if !defaultRoute.Action && !defaultRoute.NoHead && !group.NoHead {
out += "\n\t\t\t\t\tco.RouteViewCounter.Bump2(" + strconv.Itoa(allRouteMap[defaultRoute.Name]) + ", h.StartedAt)" on(5,"co.RouteViewCounter.Bump2(" + strconv.Itoa(allRouteMap[defaultRoute.Name]) + ", h.StartedAt)")
} else {*/ } else {*/
//out += "\n\t\t\t\t\tco.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[defaultRoute.Name]) + ")" //on(5,co.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[defaultRoute.Name]) + ")")
out += "\n\t\t\tco.RouteViewCounter.Bump3(" + strconv.Itoa(allRouteMap[defaultRoute.Name]) + ", cn)" on(5, "co.RouteViewCounter.Bump3("+strconv.Itoa(allRouteMap[defaultRoute.Name])+", cn)")
//} //}
} }
out += ` on(3, "}")
}`
} }
// Stubs for us to refer to these routes through // Stubs for us to refer to these routes through

View File

@ -184,6 +184,7 @@ func accountRoutes() *RouteGroup {
} }
func panelRoutes() *RouteGroup { func panelRoutes() *RouteGroup {
// TODO: Implement subgroups
return newRouteGroup("/panel/").Before("SuperModOnly").NoHeader().Routes( return newRouteGroup("/panel/").Before("SuperModOnly").NoHeader().Routes(
View("panel.Dashboard", "/panel/"), View("panel.Dashboard", "/panel/"),
//View("panel.StatsDisk", "/panel/stats/disk/"), //View("panel.StatsDisk", "/panel/stats/disk/"),