implement HooksNoRet and HooksSkip
use hookgen for route_forum_list_start use hookgen for forums_frow_assign change forums_frow_assign to a noret hook save bytes and reduce boilerplate
This commit is contained in:
parent
67772f2f9a
commit
07d478179d
|
@ -19,11 +19,15 @@ type Hook struct {
|
||||||
Ret string
|
Ret string
|
||||||
Type string
|
Type string
|
||||||
Any bool
|
Any bool
|
||||||
|
MultiHook bool
|
||||||
|
Skip bool
|
||||||
|
DefaultRet string
|
||||||
|
Pure string
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddHooks(add func(name, params, ret, htype string)) {
|
func AddHooks(add func(name, params, ret, htype string, multiHook, skip bool, defaultRet, pure string)) {
|
||||||
vhookskip := func(name, params string) {
|
vhookskip := func(name, params string) {
|
||||||
add(name,params,"(bool, RouteError)","VhookSkippable_")
|
add(name,params,"(bool,RouteError)","VhookSkippable_",false,true,"false,nil","")
|
||||||
}
|
}
|
||||||
vhookskip("forum_check_pre_perms","w http.ResponseWriter,r *http.Request,u *User,fid *int,h *Header")
|
vhookskip("forum_check_pre_perms","w http.ResponseWriter,r *http.Request,u *User,fid *int,h *Header")
|
||||||
vhookskip("router_after_filters","w http.ResponseWriter,r *http.Request,prefix string")
|
vhookskip("router_after_filters","w http.ResponseWriter,r *http.Request,prefix string")
|
||||||
|
@ -31,10 +35,24 @@ func AddHooks(add func(name, params, ret, htype string)) {
|
||||||
vhookskip("route_forum_list_start","w http.ResponseWriter,r *http.Request,u *User,h *Header")
|
vhookskip("route_forum_list_start","w http.ResponseWriter,r *http.Request,u *User,h *Header")
|
||||||
vhookskip("route_topic_list_start","w http.ResponseWriter,r *http.Request,u *User,h *Header")
|
vhookskip("route_topic_list_start","w http.ResponseWriter,r *http.Request,u *User,h *Header")
|
||||||
vhooknoret := func(name, params string) {
|
vhooknoret := func(name, params string) {
|
||||||
add(name,params,"","Vhooks")
|
add(name,params,"","Vhooks",false,false,"false,nil","")
|
||||||
}
|
}
|
||||||
vhooknoret("router_end","w http.ResponseWriter,r *http.Request,u *User,prefix string, extraData string")
|
vhooknoret("router_end","w http.ResponseWriter,r *http.Request,u *User,prefix string, extraData string")
|
||||||
vhooknoret("topic_reply_row_assign","r *ReplyUser")
|
vhooknoret("topic_reply_row_assign","r *ReplyUser")
|
||||||
|
//forums_frow_assign
|
||||||
|
//Hook(name string, data interface{}) interface{}
|
||||||
|
/*hook := func(name, params, ret, pure string) {
|
||||||
|
add(name,params,ret,"Hooks",true,false,ret,pure)
|
||||||
|
}*/
|
||||||
|
hooknoret := func(name, params string) {
|
||||||
|
add(name,params,"","HooksNoRet",true,false,"","")
|
||||||
|
}
|
||||||
|
hooknoret("forums_frow_assign","f *Forum")
|
||||||
|
hookskip := func(name, params string) {
|
||||||
|
add(name,params,"(skip bool)","HooksSkip",true,true,"","")
|
||||||
|
}
|
||||||
|
//hookskip("forums_frow_assign","f *Forum")
|
||||||
|
hookskip("topic_create_frow_assign","f *Forum")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Write(hookVars HookVars) {
|
func Write(hookVars HookVars) {
|
||||||
|
@ -45,12 +63,17 @@ import ({{range .Imports}}
|
||||||
"{{.}}"{{end}}
|
"{{.}}"{{end}}
|
||||||
)
|
)
|
||||||
{{range .Hooks}}
|
{{range .Hooks}}
|
||||||
func H_{{.Name}}_hook(t *HookTable, {{.Params}}) {{.Ret}} { {{if .Any}}
|
func H_{{.Name}}_hook(t *HookTable,{{.Params}}) {{.Ret}} { {{if .Any}}
|
||||||
hook := t.{{.Type}}["{{.Name}}"]
|
{{if .MultiHook}}for _, hook := range t.{{.Type}}["{{.Name}}"] {
|
||||||
|
{{if .Skip}}if skip = hook({{.Params2}}); skip {
|
||||||
|
break
|
||||||
|
}{{else}}{{if .Pure}}{{.Pure}} = {{else if .Ret}}return {{end}}hook({{.Params2}}){{end}}
|
||||||
|
}{{else}}hook := t.{{.Type}}["{{.Name}}"]
|
||||||
if hook != nil {
|
if hook != nil {
|
||||||
{{if .Ret}}return {{end}}hook({{.Params2}})
|
{{if .Ret}}return {{end}}hook({{.Params2}})
|
||||||
} {{end}}
|
} {{end}}{{end}}{{if .Pure}}
|
||||||
{{if .Ret}}return false, nil{{end}}
|
return {{.Pure}}{{else if .Ret}}
|
||||||
|
return {{.DefaultRet}}{{end}}
|
||||||
}{{end}}
|
}{{end}}
|
||||||
`
|
`
|
||||||
tmpl := template.Must(template.New("hooks").Parse(fileData))
|
tmpl := template.Must(template.New("hooks").Parse(fileData))
|
||||||
|
|
|
@ -20,7 +20,6 @@ func main() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
fmt.Println(r)
|
fmt.Println(r)
|
||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -49,7 +48,7 @@ func main() {
|
||||||
|
|
||||||
imports := []string{"net/http"}
|
imports := []string{"net/http"}
|
||||||
hookVars := h.HookVars{imports,nil}
|
hookVars := h.HookVars{imports,nil}
|
||||||
add := func(name, params, ret, htype string) {
|
add := func(name, params, ret, htype string, multiHook, skip bool, defaultRet, pure string) {
|
||||||
var params2 string
|
var params2 string
|
||||||
first := true
|
first := true
|
||||||
for _, param := range strings.Split(params,",") {
|
for _, param := range strings.Split(params,",") {
|
||||||
|
@ -60,7 +59,7 @@ func main() {
|
||||||
params2 += pspl[0]
|
params2 += pspl[0]
|
||||||
first = false
|
first = false
|
||||||
}
|
}
|
||||||
hookVars.Hooks = append(hookVars.Hooks, h.Hook{name, params, params2, ret, htype, hooks[name] > 0})
|
hookVars.Hooks = append(hookVars.Hooks, h.Hook{name, params, params2, ret, htype, hooks[name] > 0, multiHook, skip, defaultRet, pure})
|
||||||
}
|
}
|
||||||
|
|
||||||
h.AddHooks(add)
|
h.AddHooks(add)
|
||||||
|
|
|
@ -16,13 +16,12 @@ func main() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
fmt.Println(r)
|
fmt.Println(r)
|
||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
imports := []string{"net/http"}
|
imports := []string{"net/http"}
|
||||||
hookVars := h.HookVars{imports,nil}
|
hookVars := h.HookVars{imports,nil}
|
||||||
add := func(name, params, ret, htype string) {
|
add := func(name, params, ret, htype string, multiHook, skip bool, defaultRet, pure string) {
|
||||||
var params2 string
|
var params2 string
|
||||||
first := true
|
first := true
|
||||||
for _, param := range strings.Split(params,",") {
|
for _, param := range strings.Split(params,",") {
|
||||||
|
@ -33,7 +32,7 @@ func main() {
|
||||||
params2 += pspl[0]
|
params2 += pspl[0]
|
||||||
first = false
|
first = false
|
||||||
}
|
}
|
||||||
hookVars.Hooks = append(hookVars.Hooks, h.Hook{name, params, params2, ret, htype, true})
|
hookVars.Hooks = append(hookVars.Hooks, h.Hook{name, params, params2, ret, htype, true, multiHook, skip, defaultRet,pure})
|
||||||
}
|
}
|
||||||
|
|
||||||
h.AddHooks(add)
|
h.AddHooks(add)
|
||||||
|
|
106
common/extend.go
106
common/extend.go
|
@ -49,14 +49,16 @@ var hookTableBox atomic.Value
|
||||||
// TODO: Make the RunXHook functions methods on HookTable
|
// TODO: Make the RunXHook functions methods on HookTable
|
||||||
// TODO: Have plugins update hooks on a mutex guarded map and create a copy of that map in a serial global goroutine which gets thrown in the atomic.Value
|
// TODO: Have plugins update hooks on a mutex guarded map and create a copy of that map in a serial global goroutine which gets thrown in the atomic.Value
|
||||||
type HookTable struct {
|
type HookTable struct {
|
||||||
Hooks map[string][]func(interface{}) interface{}
|
//Hooks map[string][]func(interface{}) interface{}
|
||||||
|
HooksNoRet map[string][]func(interface{})
|
||||||
|
HooksSkip map[string][]func(interface{}) bool
|
||||||
Vhooks map[string]func(...interface{}) interface{}
|
Vhooks map[string]func(...interface{}) interface{}
|
||||||
VhookSkippable_ map[string]func(...interface{}) (bool, RouteError)
|
VhookSkippable_ map[string]func(...interface{}) (bool, RouteError)
|
||||||
Sshooks map[string][]func(string) string
|
Sshooks map[string][]func(string) string
|
||||||
PreRenderHooks map[string][]func(http.ResponseWriter, *http.Request, *User, interface{}) bool
|
PreRenderHooks map[string][]func(http.ResponseWriter, *http.Request, *User, interface{}) bool
|
||||||
|
|
||||||
// For future use:
|
// For future use:
|
||||||
messageHooks map[string][]func(Message, PageInt, ...interface{}) interface{}
|
//messageHooks map[string][]func(Message, PageInt, ...interface{}) interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -65,15 +67,18 @@ func init() {
|
||||||
|
|
||||||
// For extend.go use only, access this via GetHookTable() elsewhere
|
// For extend.go use only, access this via GetHookTable() elsewhere
|
||||||
var hookTable = &HookTable{
|
var hookTable = &HookTable{
|
||||||
map[string][]func(interface{}) interface{}{
|
//map[string][]func(interface{}) interface{}{},
|
||||||
"forums_frow_assign": nil,
|
map[string][]func(interface{}){
|
||||||
"topic_create_frow_assign": nil,
|
"forums_frow_assign": nil, //hg
|
||||||
|
},
|
||||||
|
map[string][]func(interface{}) bool{
|
||||||
|
"topic_create_frow_assign": nil, //hg
|
||||||
},
|
},
|
||||||
map[string]func(...interface{}) interface{}{
|
map[string]func(...interface{}) interface{}{
|
||||||
//"convo_post_update":nil,
|
//"convo_post_update":nil,
|
||||||
//"convo_post_create":nil,
|
//"convo_post_create":nil,
|
||||||
|
|
||||||
"forum_trow_assign": nil,
|
///"forum_trow_assign": nil,
|
||||||
"topics_topic_row_assign": nil,
|
"topics_topic_row_assign": nil,
|
||||||
//"topics_user_row_assign": nil,
|
//"topics_user_row_assign": nil,
|
||||||
"topic_reply_row_assign": nil,
|
"topic_reply_row_assign": nil,
|
||||||
|
@ -83,8 +88,8 @@ var hookTable = &HookTable{
|
||||||
"router_end": nil,
|
"router_end": nil,
|
||||||
},
|
},
|
||||||
map[string]func(...interface{}) (bool, RouteError){
|
map[string]func(...interface{}) (bool, RouteError){
|
||||||
"simple_forum_check_pre_perms": nil,
|
"simple_forum_check_pre_perms": nil, //hg
|
||||||
"forum_check_pre_perms": nil,
|
"forum_check_pre_perms": nil, //hg
|
||||||
|
|
||||||
"route_topic_list_start": nil,
|
"route_topic_list_start": nil,
|
||||||
"route_topic_list_mostviewed_start": nil,
|
"route_topic_list_mostviewed_start": nil,
|
||||||
|
@ -125,7 +130,7 @@ var hookTable = &HookTable{
|
||||||
"parse_assign": nil,
|
"parse_assign": nil,
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
nil,
|
//nil,
|
||||||
}
|
}
|
||||||
var hookTableUpdateMutex sync.Mutex
|
var hookTableUpdateMutex sync.Mutex
|
||||||
|
|
||||||
|
@ -146,51 +151,47 @@ func GetHookTable() *HookTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hooks with a single argument. Is this redundant? Might be useful for inlining, as variadics aren't inlined? Are closures even inlined to begin with?
|
// Hooks with a single argument. Is this redundant? Might be useful for inlining, as variadics aren't inlined? Are closures even inlined to begin with?
|
||||||
func (t *HookTable) Hook(name string, data interface{}) interface{} {
|
/*func (t *HookTable) Hook(name string, data interface{}) interface{} {
|
||||||
hooks, ok := t.Hooks[name]
|
for _, hook := range t.Hooks[name] {
|
||||||
if ok {
|
|
||||||
for _, hook := range hooks {
|
|
||||||
data = hook(data)
|
data = hook(data)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return data
|
return data
|
||||||
|
}*/
|
||||||
|
|
||||||
|
func (t *HookTable) HookNoRet(name string, data interface{}) {
|
||||||
|
for _, hook := range t.HooksNoRet[name] {
|
||||||
|
hook(data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// To cover the case in routes/topic.go's CreateTopic route, we could probably obsolete this use and replace it
|
// To cover the case in routes/topic.go's CreateTopic route, we could probably obsolete this use and replace it
|
||||||
func (t *HookTable) HookSkippable(name string, data interface{}) (skip bool) {
|
func (t *HookTable) HookSkip(name string, data interface{}) (skip bool) {
|
||||||
hooks, ok := t.Hooks[name]
|
for _, hook := range t.HooksSkip[name] {
|
||||||
if ok {
|
if skip = hook(data); skip {
|
||||||
for _, hook := range hooks {
|
|
||||||
skip = hook(data).(bool)
|
|
||||||
if skip {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return skip
|
return skip
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hooks with a variable number of arguments
|
// Hooks with a variable number of arguments
|
||||||
// TODO: Use RunHook semantics to allow multiple lined up plugins / modules their turn?
|
// TODO: Use RunHook semantics to allow multiple lined up plugins / modules their turn?
|
||||||
func (t *HookTable) Vhook(name string, data ...interface{}) interface{} {
|
func (t *HookTable) Vhook(name string, data ...interface{}) interface{} {
|
||||||
hook := t.Vhooks[name]
|
if hook := t.Vhooks[name]; hook != nil {
|
||||||
if hook != nil {
|
|
||||||
return hook(data...)
|
return hook(data...)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *HookTable) VhookNoRet(name string, data ...interface{}) {
|
func (t *HookTable) VhookNoRet(name string, data ...interface{}) {
|
||||||
hook := t.Vhooks[name]
|
if hook := t.Vhooks[name]; hook != nil {
|
||||||
if hook != nil {
|
|
||||||
_ = hook(data...)
|
_ = hook(data...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Find a better way of doing this
|
// TODO: Find a better way of doing this
|
||||||
func (t *HookTable) VhookNeedHook(name string, data ...interface{}) (ret interface{}, hasHook bool) {
|
func (t *HookTable) VhookNeedHook(name string, data ...interface{}) (ret interface{}, hasHook bool) {
|
||||||
hook := t.Vhooks[name]
|
if hook := t.Vhooks[name]; hook != nil {
|
||||||
if hook != nil {
|
|
||||||
return hook(data...), true
|
return hook(data...), true
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
|
@ -198,16 +199,14 @@ func (t *HookTable) VhookNeedHook(name string, data ...interface{}) (ret interfa
|
||||||
|
|
||||||
// Hooks with a variable number of arguments and return values for skipping the parent function and propagating an error upwards
|
// Hooks with a variable number of arguments and return values for skipping the parent function and propagating an error upwards
|
||||||
func (t *HookTable) VhookSkippable(name string, data ...interface{}) (bool, RouteError) {
|
func (t *HookTable) VhookSkippable(name string, data ...interface{}) (bool, RouteError) {
|
||||||
hook := t.VhookSkippable_[name]
|
if hook := t.VhookSkippable_[name]; hook != nil {
|
||||||
if hook != nil {
|
|
||||||
return hook(data...)
|
return hook(data...)
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*func VhookSkippableTest(t *HookTable, name string, data ...interface{}) (bool, RouteError) {
|
/*func VhookSkippableTest(t *HookTable, name string, data ...interface{}) (bool, RouteError) {
|
||||||
hook := t.VhookSkippable_[name]
|
if hook := t.VhookSkippable_[name]; hook != nil {
|
||||||
if hook != nil {
|
|
||||||
return hook(data...)
|
return hook(data...)
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
|
@ -224,12 +223,9 @@ func forum_check_pre_perms_hook(t *HookTable, w http.ResponseWriter, r *http.Req
|
||||||
// Hooks which take in and spit out a string. This is usually used for parser components
|
// Hooks which take in and spit out a string. This is usually used for parser components
|
||||||
// Trying to get a teeny bit of type-safety where-ever possible, especially for such a critical set of hooks
|
// Trying to get a teeny bit of type-safety where-ever possible, especially for such a critical set of hooks
|
||||||
func (t *HookTable) Sshook(name, data string) string {
|
func (t *HookTable) Sshook(name, data string) string {
|
||||||
ssHooks, ok := t.Sshooks[name]
|
for _, hook := range t.Sshooks[name] {
|
||||||
if ok {
|
|
||||||
for _, hook := range ssHooks {
|
|
||||||
data = hook(data)
|
data = hook(data)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,12 +468,24 @@ func (pl *Plugin) AddHook(name string, hInt interface{}) {
|
||||||
defer hookTableUpdateMutex.Unlock()
|
defer hookTableUpdateMutex.Unlock()
|
||||||
|
|
||||||
switch h := hInt.(type) {
|
switch h := hInt.(type) {
|
||||||
case func(interface{}) interface{}:
|
/*case func(interface{}) interface{}:
|
||||||
if len(hookTable.Hooks[name]) == 0 {
|
if len(hookTable.Hooks[name]) == 0 {
|
||||||
hookTable.Hooks[name] = []func(interface{}) interface{}{}
|
hookTable.Hooks[name] = []func(interface{}) interface{}{}
|
||||||
}
|
}
|
||||||
hookTable.Hooks[name] = append(hookTable.Hooks[name], h)
|
hookTable.Hooks[name] = append(hookTable.Hooks[name], h)
|
||||||
pl.Hooks[name] = len(hookTable.Hooks[name]) - 1
|
pl.Hooks[name] = len(hookTable.Hooks[name]) - 1*/
|
||||||
|
case func(interface{}):
|
||||||
|
if len(hookTable.HooksNoRet[name]) == 0 {
|
||||||
|
hookTable.HooksNoRet[name] = []func(interface{}){}
|
||||||
|
}
|
||||||
|
hookTable.HooksNoRet[name] = append(hookTable.HooksNoRet[name], h)
|
||||||
|
pl.Hooks[name] = len(hookTable.HooksNoRet[name]) - 1
|
||||||
|
case func(interface{}) bool:
|
||||||
|
if len(hookTable.HooksSkip[name]) == 0 {
|
||||||
|
hookTable.HooksSkip[name] = []func(interface{}) bool{}
|
||||||
|
}
|
||||||
|
hookTable.HooksSkip[name] = append(hookTable.HooksSkip[name], h)
|
||||||
|
pl.Hooks[name] = len(hookTable.HooksSkip[name]) - 1
|
||||||
case func(string) string:
|
case func(string) string:
|
||||||
if len(hookTable.Sshooks[name]) == 0 {
|
if len(hookTable.Sshooks[name]) == 0 {
|
||||||
hookTable.Sshooks[name] = []func(string) string{}
|
hookTable.Sshooks[name] = []func(string) string{}
|
||||||
|
@ -521,14 +529,30 @@ func (pl *Plugin) RemoveHook(name string, hInt interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch hInt.(type) {
|
switch hInt.(type) {
|
||||||
case func(interface{}) interface{}:
|
/*case func(interface{}) interface{}:
|
||||||
hook := hookTable.Hooks[name]
|
hook := hookTable.Hooks[name]
|
||||||
if len(hook) == 1 {
|
if len(hook) == 1 {
|
||||||
hook = []func(interface{}) interface{}{}
|
hook = []func(interface{}) interface{}{}
|
||||||
} else {
|
} else {
|
||||||
hook = append(hook[:key], hook[key+1:]...)
|
hook = append(hook[:key], hook[key+1:]...)
|
||||||
}
|
}
|
||||||
hookTable.Hooks[name] = hook
|
hookTable.Hooks[name] = hook*/
|
||||||
|
case func(interface{}):
|
||||||
|
hook := hookTable.HooksNoRet[name]
|
||||||
|
if len(hook) == 1 {
|
||||||
|
hook = []func(interface{}){}
|
||||||
|
} else {
|
||||||
|
hook = append(hook[:key], hook[key+1:]...)
|
||||||
|
}
|
||||||
|
hookTable.HooksNoRet[name] = hook
|
||||||
|
case func(interface{}) bool:
|
||||||
|
hook := hookTable.HooksSkip[name]
|
||||||
|
if len(hook) == 1 {
|
||||||
|
hook = []func(interface{}) bool{}
|
||||||
|
} else {
|
||||||
|
hook = append(hook[:key], hook[key+1:]...)
|
||||||
|
}
|
||||||
|
hookTable.HooksSkip[name] = hook
|
||||||
case func(string) string:
|
case func(string) string:
|
||||||
hook := hookTable.Sshooks[name]
|
hook := hookTable.Sshooks[name]
|
||||||
if len(hook) == 1 {
|
if len(hook) == 1 {
|
||||||
|
@ -589,8 +613,8 @@ func InitPlugins() {
|
||||||
// ? - Are the following functions racey?
|
// ? - Are the following functions racey?
|
||||||
func RunTaskHook(name string) error {
|
func RunTaskHook(name string) error {
|
||||||
for _, hook := range taskHooks[name] {
|
for _, hook := range taskHooks[name] {
|
||||||
if err := hook(); err != nil {
|
if e := hook(); e != nil {
|
||||||
return err
|
return e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -162,7 +162,7 @@ func GuildWidgets(header *c.Header, guildItem *Guild) (success bool) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func RouteGuildList(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
|
func RouteGuildList(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
|
||||||
h, ferr := c.UserCheck(w, r, &user)
|
h, ferr := c.UserCheck(w, r, user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user *c.User) c.Rou
|
||||||
}
|
}
|
||||||
|
|
||||||
func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
|
func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
|
||||||
h, ferr := c.UserCheck(w, r, &user)
|
h, ferr := c.UserCheck(w, r, user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
|
@ -334,7 +334,7 @@ func RouteMemberList(w http.ResponseWriter, r *http.Request, user *c.User) c.Rou
|
||||||
|
|
||||||
pi := MemberListPage{"Guild Member List", user, header, gMembers, guild, 0, 0}
|
pi := MemberListPage{"Guild Member List", user, header, gMembers, guild, 0, 0}
|
||||||
// A plugin with plugins. Pluginception!
|
// A plugin with plugins. Pluginception!
|
||||||
if c.RunPreRenderHook("pre_render_guilds_member_list", w, r, &user, &pi) {
|
if c.RunPreRenderHook("pre_render_guilds_member_list", w, r, user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err = c.RunThemeTemplate(header.Theme.Name, "guilds_member_list", pi, w)
|
err = c.RunThemeTemplate(header.Theme.Name, "guilds_member_list", pi, w)
|
||||||
|
@ -373,7 +373,7 @@ func PreRenderViewForum(w http.ResponseWriter, r *http.Request, user *c.User, da
|
||||||
guildItem := guildData.(*Guild)
|
guildItem := guildData.(*Guild)
|
||||||
|
|
||||||
guildpi := Page{pi.Title, pi.Header, pi.ItemList, pi.Forum, guildItem, pi.Page, pi.LastPage}
|
guildpi := Page{pi.Title, pi.Header, pi.ItemList, pi.Forum, guildItem, pi.Page, pi.LastPage}
|
||||||
err := routes.RenderTemplate("guilds_view_guild", w, r, header, guildpi)
|
err := routes.RenderTemplate("guilds_view_guild", w, r, pi.Header, guildpi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.LogError(err)
|
c.LogError(err)
|
||||||
return false
|
return false
|
||||||
|
@ -442,13 +442,13 @@ func ForumCheck(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||||
return true, c.InternalError(err, w, r)
|
return true, c.InternalError(err, w, r)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
// TODO: Should we let admins / guests into public groups?
|
// TODO: Should we let admins / guests into public groups?
|
||||||
return true, c.LocalError("You're not part of this group!", w, r, *user)
|
return true, c.LocalError("You're not part of this group!", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement bans properly by adding the Local Ban API in the next commit
|
// TODO: Implement bans properly by adding the Local Ban API in the next commit
|
||||||
// TODO: How does this even work? Refactor it along with the rest of this plugin!
|
// TODO: How does this even work? Refactor it along with the rest of this plugin!
|
||||||
if rank < 0 {
|
if rank < 0 {
|
||||||
return true, c.LocalError("You've been banned from this group!", w, r, *user)
|
return true, c.LocalError("You've been banned from this group!", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basic permissions for members, more complicated permissions coming in the next commit!
|
// Basic permissions for members, more complicated permissions coming in the next commit!
|
||||||
|
|
|
@ -2,7 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
c "github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/extend/guilds/lib"
|
guilds "github.com/Azareal/Gosora/extend/guilds/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Add a better way of splitting up giant plugins like this
|
// TODO: Add a better way of splitting up giant plugins like this
|
||||||
|
@ -54,7 +54,7 @@ func initGuilds(pl *c.Plugin) (err error) {
|
||||||
return acc.FirstError()
|
return acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
func deactivateGuilds(pl *common.Plugin) {
|
func deactivateGuilds(pl *c.Plugin) {
|
||||||
pl.RemoveHook("intercept_build_widgets", guilds.Widgets)
|
pl.RemoveHook("intercept_build_widgets", guilds.Widgets)
|
||||||
pl.RemoveHook("trow_assign", guilds.TrowAssign)
|
pl.RemoveHook("trow_assign", guilds.TrowAssign)
|
||||||
pl.RemoveHook("topic_create_pre_loop", guilds.TopicCreatePreLoop)
|
pl.RemoveHook("topic_create_pre_loop", guilds.TopicCreatePreLoop)
|
||||||
|
@ -77,7 +77,8 @@ func deactivateGuilds(pl *common.Plugin) {
|
||||||
|
|
||||||
// TODO: Stop accessing the query builder directly and add a feature in Gosora which is more easily reversed, if an error comes up during the installation process
|
// TODO: Stop accessing the query builder directly and add a feature in Gosora which is more easily reversed, if an error comes up during the installation process
|
||||||
type tC = qgen.DBTableColumn
|
type tC = qgen.DBTableColumn
|
||||||
func installGuilds(plugin *common.Plugin) error {
|
|
||||||
|
func installGuilds(plugin *c.Plugin) error {
|
||||||
guildTableStmt, err := qgen.Builder.CreateTable("guilds", "utf8mb4", "utf8mb4_general_ci",
|
guildTableStmt, err := qgen.Builder.CreateTable("guilds", "utf8mb4", "utf8mb4_general_ci",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"guildID", "int", 0, false, true, ""},
|
tC{"guildID", "int", 0, false, true, ""},
|
||||||
|
|
|
@ -9,7 +9,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func ForumList(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
|
func ForumList(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
|
||||||
skip, rerr := h.Hooks.VhookSkippable("route_forum_list_start", w, r, user, h)
|
/*skip, rerr := h.Hooks.VhookSkippable("route_forum_list_start", w, r, user, h)
|
||||||
|
if skip || rerr != nil {
|
||||||
|
return rerr
|
||||||
|
}*/
|
||||||
|
skip, rerr := c.H_route_forum_list_start_hook(h.Hooks, w, r, user, h)
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
|
@ -44,7 +48,8 @@ func ForumList(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header
|
||||||
f.LastTopicTime = c.RelativeTime(f.LastTopic.LastReplyAt)
|
f.LastTopicTime = c.RelativeTime(f.LastTopic.LastReplyAt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.Hooks.Hook("forums_frow_assign", &f)
|
//h.Hooks.Hook("forums_frow_assign", &f)
|
||||||
|
c.H_forums_frow_assign_hook(h.Hooks, &f)
|
||||||
forumList = append(forumList, f)
|
forumList = append(forumList, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
{{if .Avatar}}<div class='alertItem withAvatar'style='background-image:url("{{.Avatar}}");'><img src='{{.Avatar}}'class='bgsub'><a class='text'data-asid='{{.ASID}}'href="{{.Path}}">{{.Message}}</a></div>{{else}}
|
{{if .Avatar}}<div class='alertItem withAvatar'style='background-image:url("{{.Avatar}}");'><img src='{{.Avatar}}'class='bgsub'><a class='text'data-asid='{{.ASID}}'href="{{.Path}}">{{.Message}}</a></div>{{else}}<div class='alertItem'><a href="{{.Path}}"class='text'>{{.Message}}</a></div>{{end}}
|
||||||
<div class='alertItem'><a href="{{.Path}}"class='text'>{{.Message}}</a></div>{{end}}
|
|
|
@ -13,7 +13,7 @@
|
||||||
<div class="formitem"><textarea name="body"></textarea></div>
|
<div class="formitem"><textarea name="body"></textarea></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem"><button name="panel-button" class="formbutton form_middle_button">{{lang "create_convo_button"}}</button></div>
|
<div class="formitem"><button name="panel-button"class="formbutton form_middle_button">{{lang "create_convo_button"}}</button></div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
|
@ -13,7 +13,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "create_topic_name"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "create_topic_name"}}</a></div>
|
||||||
<div class="formitem"><input form="quick_post_form" name="name" type="text" placeholder="{{lang "create_topic_name"}}" required /></div>
|
<div class="formitem"><input form="quick_post_form" name="name" type="text" placeholder="{{lang "create_topic_name"}}" required></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "create_topic_content"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "create_topic_content"}}</a></div>
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<button form="quick_post_form" name="topic-button" class="formbutton">{{lang "create_topic_create_button"}}</button>
|
<button form="quick_post_form" name="topic-button" class="formbutton">{{lang "create_topic_create_button"}}</button>
|
||||||
{{if .CurrentUser.Perms.UploadFiles}}
|
{{if .CurrentUser.Perms.UploadFiles}}
|
||||||
<input name="quick_topic_upload_files" form="quick_post_form" id="quick_topic_upload_files" multiple type="file" style="display:none;" />
|
<input name="quick_topic_upload_files" form="quick_post_form" id="quick_topic_upload_files" multiple type="file" class="auto_hide">
|
||||||
<label for="quick_topic_upload_files" class="formbutton add_file_button">{{lang "create_topic_add_file_button"}}</label>{{end}}
|
<label for="quick_topic_upload_files" class="formbutton add_file_button">{{lang "create_topic_add_file_button"}}</label>{{end}}
|
||||||
<div id="upload_file_dock"></div>
|
<div id="upload_file_dock"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<div class="rowitem"><h1 itemprop="name">{{lang "forums_head"}}</h1></div>
|
<div class="rowitem"><h1 itemprop="name">{{lang "forums_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rowblock forum_list">
|
<div class="rowblock forum_list">
|
||||||
{{range .ItemList}}<div id="forum_{{.ID}}"class="rowitem{{if (.Desc) or (.LastTopic.Title)}} datarow{{end}}"itemprop="itemListElement" itemscope
|
{{range .ItemList}}<div id="forum_{{.ID}}"class="rowitem{{if (.Desc) or (.LastTopic.Title)}} datarow{{end}}"itemprop="itemListElement"itemscope
|
||||||
itemtype="http://schema.org/ListItem">
|
itemtype="http://schema.org/ListItem">
|
||||||
<span class="forum_left shift_left">
|
<span class="forum_left shift_left">
|
||||||
<a href="{{.Link}}"itemprop="item">{{.Name}}</a><br>
|
<a href="{{.Link}}"itemprop="item">{{.Name}}</a><br>
|
||||||
|
|
|
@ -4,17 +4,17 @@
|
||||||
<div class="rowitem"><h1>{{lang "login_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "login_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rowblock the_form">
|
<div class="rowblock the_form">
|
||||||
<form action="/accounts/login/submit/" method="post">
|
<form action="/accounts/login/submit/"method="post">
|
||||||
<div class="formrow login_name_row">
|
<div class="formrow login_name_row">
|
||||||
<div class="formitem formlabel"><a id="login_name_label">{{lang "login_account_name"}}</a></div>
|
<div class="formitem formlabel"><a id="login_name_label">{{lang "login_account_name"}}</a></div>
|
||||||
<div class="formitem"><input name="username"type="text"placeholder="{{lang "login_account_name"}}" aria-labelledby="login_name_label" required></div>
|
<div class="formitem"><input name="username"type="text"placeholder="{{lang "login_account_name"}}"aria-labelledby="login_name_label"required></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow login_password_row">
|
<div class="formrow login_password_row">
|
||||||
<div class="formitem formlabel"><a id="login_password_label">{{lang "login_account_password"}}</a></div>
|
<div class="formitem formlabel"><a id="login_password_label">{{lang "login_account_password"}}</a></div>
|
||||||
<div class="formitem"><input name="password"type="password"autocomplete="current-password"placeholder="*****"aria-labelledby="login_password_label" required></div>
|
<div class="formitem"><input name="password"type="password"autocomplete="current-password"placeholder="*****"aria-labelledby="login_password_label" required></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow login_button_row form_button_row">
|
<div class="formrow login_button_row form_button_row">
|
||||||
<div class="formitem"><button name="login-button" class="formbutton">{{lang "login_submit_button"}}</button></div>
|
<div class="formitem"><button name="login-button"class="formbutton">{{lang "login_submit_button"}}</button></div>
|
||||||
<div class="formitem dont_have_account">
|
<div class="formitem dont_have_account">
|
||||||
<a href="/accounts/create/">{{lang "login_no_account"}}
|
<a href="/accounts/create/">{{lang "login_no_account"}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_logs_reg_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_logs_reg_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_reglogs" class="colstack_item rowlist loglist">
|
<div id="panel_reglogs"class="colstack_item rowlist loglist">
|
||||||
{{range .Logs}}
|
{{range .Logs}}
|
||||||
<div class="rowitem panel_compactrow{{if not .Success}} bg_red{{end}}">
|
<div class="rowitem panel_compactrow{{if not .Success}} bg_red{{end}}">
|
||||||
<span>{{if not .Success}}{{lang "panel_logs_reg_attempt"}}{{end}}{{.Username}}{{if .Email}} ({{lang "panel_logs_reg_email"}}{{.Email}}){{end}}{{if .ParsedReason}} ({{lang "panel_logs_reg_reason"}}{{.ParsedReason}}){{end}}</span>
|
<span>{{if not .Success}}{{lang "panel_logs_reg_attempt"}}{{end}}{{.Username}}{{if .Email}} ({{lang "panel_logs_reg_email"}}{{.Email}}){{end}}{{if .ParsedReason}} ({{lang "panel_logs_reg_reason"}}{{.ParsedReason}}){{end}}</span>
|
||||||
<div class="logdetail">
|
<div class="logdetail">
|
||||||
{{if $.CurrentUser.Perms.ViewIPs}}<small class="to_left" title="{{.IP}}">{{.IP}}</small>{{end}}
|
{{if $.CurrentUser.Perms.ViewIPs}}<small class="to_left"title="{{.IP}}">{{.IP}}</small>{{end}}
|
||||||
<span class="to_right"><small title="{{.DoneAt}}">{{.DoneAt}}</small></span>
|
<span class="to_right"><small title="{{.DoneAt}}">{{.DoneAt}}</small></span>
|
||||||
<div style="clear:both;"></div>
|
<div style="clear:both;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -28,14 +28,14 @@
|
||||||
<a class="profile_menu_item">{{lang "profile.login_for_options"}}</a>
|
<a class="profile_menu_item">{{lang "profile.login_for_options"}}</a>
|
||||||
</div>{{else}}
|
</div>{{else}}
|
||||||
{{if .CanMessage}}<div class="rowitem passive">
|
{{if .CanMessage}}<div class="rowitem passive">
|
||||||
<a href="/user/convos/create/?with={{.ProfileOwner.ID}}" class="profile_menu_item">{{lang "profile.send_message"}}</a>
|
<a href="/user/convos/create/?with={{.ProfileOwner.ID}}"class="profile_menu_item">{{lang "profile.send_message"}}</a>
|
||||||
</div>{{end}}
|
</div>{{end}}
|
||||||
<!--<div class="rowitem passive">
|
<!--<div class="rowitem passive">
|
||||||
<a class="profile_menu_item">{{lang "profile.add_friend"}}</a>
|
<a class="profile_menu_item">{{lang "profile.add_friend"}}</a>
|
||||||
</div>-->
|
</div>-->
|
||||||
|
|
||||||
{{if (.CurrentUser.IsSuperMod) and not (.ProfileOwner.IsSuperMod)}}<div class="rowitem passive">
|
{{if (.CurrentUser.IsSuperMod) and not (.ProfileOwner.IsSuperMod)}}<div class="rowitem passive">
|
||||||
{{if .ProfileOwner.IsBanned}}<a href="/users/unban/{{.ProfileOwner.ID}}?s={{.CurrentUser.Session}}" class="profile_menu_item">{{lang "profile.unban"}}</a>
|
{{if .ProfileOwner.IsBanned}}<a href="/users/unban/{{.ProfileOwner.ID}}?s={{.CurrentUser.Session}}"class="profile_menu_item">{{lang "profile.unban"}}</a>
|
||||||
{{else}}<a href="#ban_user"class="profile_menu_item">{{lang "profile.ban"}}</a>{{end}}
|
{{else}}<a href="#ban_user"class="profile_menu_item">{{lang "profile.ban"}}</a>{{end}}
|
||||||
</div>
|
</div>
|
||||||
<div class="rowitem passive">
|
<div class="rowitem passive">
|
||||||
|
@ -58,10 +58,10 @@
|
||||||
{{if .CurrentUser.Loggedin}}
|
{{if .CurrentUser.Loggedin}}
|
||||||
{{if .CurrentUser.Perms.BanUsers}}
|
{{if .CurrentUser.Perms.BanUsers}}
|
||||||
<!-- TODO: Inline the display:none; CSS -->
|
<!-- TODO: Inline the display:none; CSS -->
|
||||||
<div id="ban_user_head" class="colstack_item colstack_head hash_hide ban_user_hash" style="display:none;">
|
<div id="ban_user_head"class="colstack_item colstack_head hash_hide ban_user_hash" style="display:none;">
|
||||||
<div class="rowitem"><h1><a>{{lang "profile.ban_user_head"}}</a></h1></div>
|
<div class="rowitem"><h1><a>{{lang "profile.ban_user_head"}}</a></h1></div>
|
||||||
</div>
|
</div>
|
||||||
<form id="ban_user_form" class="hash_hide ban_user_hash" action="/users/ban/submit/{{.ProfileOwner.ID}}?s={{.CurrentUser.Session}}" method="post" style="display:none;">
|
<form id="ban_user_form"class="hash_hide ban_user_hash"action="/users/ban/submit/{{.ProfileOwner.ID}}?s={{.CurrentUser.Session}}"method="post"style="display:none;">
|
||||||
<div class="the_form">
|
<div class="the_form">
|
||||||
{{/** TODO: Put a JS duration calculator here instead of this text? **/}}
|
{{/** TODO: Put a JS duration calculator here instead of this text? **/}}
|
||||||
<div class="colline">{{lang "profile.ban_user_notice"}}</div>
|
<div class="colline">{{lang "profile.ban_user_notice"}}</div>
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
<div id="delete_posts_head"class="colstack_item colstack_head hash_hide delete_posts_hash"style="display:none;">
|
<div id="delete_posts_head"class="colstack_item colstack_head hash_hide delete_posts_hash"style="display:none;">
|
||||||
<div class="rowitem"><h1><a>{{lang "profile.delete_posts_head"}}</a></h1></div>
|
<div class="rowitem"><h1><a>{{lang "profile.delete_posts_head"}}</a></h1></div>
|
||||||
</div>
|
</div>
|
||||||
<form id="delete_posts_form" class="hash_hide delete_posts_hash" action="/users/delete-posts/submit/{{.ProfileOwner.ID}}?s={{.CurrentUser.Session}}" method="post" style="display:none;">
|
<form id="delete_posts_form"class="hash_hide delete_posts_hash"action="/users/delete-posts/submit/{{.ProfileOwner.ID}}?s={{.CurrentUser.Session}}"method="post"style="display:none;">
|
||||||
<div class="the_form">
|
<div class="the_form">
|
||||||
<div class="colline">{{langf "profile.delete_posts_notice" .ProfileOwner.Posts}}</div>
|
<div class="colline">{{langf "profile.delete_posts_notice" .ProfileOwner.Posts}}</div>
|
||||||
<div class="colstack_item">
|
<div class="colstack_item">
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
<div class="rowitem"><h1>{{lang "register_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "register_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rowblock the_form">
|
<div class="rowblock the_form">
|
||||||
<form action="/accounts/create/submit/" method="post">
|
<form action="/accounts/create/submit/"method="post">
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a id="name_label">{{lang "register_account_name"}}</a></div>
|
<div class="formitem formlabel"><a id="name_label">{{lang "register_account_name"}}</a></div>
|
||||||
<div class="formitem"><input name="name"type="text"placeholder="{{lang "register_account_name"}}" aria-labelledby="name_label"required></div>
|
<div class="formitem"><input name="name"type="text"placeholder="{{lang "register_account_name"}}"aria-labelledby="name_label"required></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a id="email_label">{{if not .Something}}{{lang "register_account_email"}}{{else}}{{lang "register_account_email_optional"}}{{end}}</a></div>
|
<div class="formitem formlabel"><a id="email_label">{{if not .Something}}{{lang "register_account_email"}}{{else}}{{lang "register_account_email_optional"}}{{end}}</a></div>
|
||||||
|
|
Loading…
Reference in New Issue