From 25074b58b2fad2dd8cd917cd8a7d6165b40c1189 Mon Sep 17 00:00:00 2001 From: Azareal Date: Wed, 10 Jan 2018 03:32:48 +0000 Subject: [PATCH] Added a time graph for individual user agents. We now have an Advanced Forum Permissions Editor providing more granular control over permissions. Tweaked the button CSS and some other bits and pieces. Added a details section to the View Count Graph. Renamed a few template files for the sake of consistency and for an upcoming refactor. Unknown user agents are now logged in debug mode. Added GetCopy() to the forum permissions store. Fixed a crash bug in the forum deletion action. Refactored the permissions list in the group permissions editor. --- common/extend.go | 1 + common/forum.go | 4 +- common/forum_perms.go | 1 + common/forum_perms_store.go | 13 + common/pages.go | 26 ++ common/template_init.go | 4 +- gen_router.go | 299 ++++++++-------- general_test.go | 4 - member_routes.go | 18 +- panel_routes.go | 336 ++++++++++++++---- public/global.js | 10 + router_gen/main.go | 3 + router_gen/routes.go | 2 + .../{account-menu.html => account_menu.html} | 0 ...nt-own-edit.html => account_own_edit.html} | 2 +- ...atar.html => account_own_edit_avatar.html} | 2 +- ...email.html => account_own_edit_email.html} | 2 +- ...me.html => account_own_edit_username.html} | 2 +- .../{are-you-sure.html => are_you_sure.html} | 0 .../{create-topic.html => create_topic.html} | 0 templates/panel-analytics-agent-views.html | 49 +++ templates/panel-analytics-agents.html | 2 +- templates/panel-analytics-views.html | 11 +- templates/panel-forum-edit-perms.html | 2 +- templates/panel-forum-edit.html | 1 + templates/panel-forums.html | 2 +- ...el-dashboard.html => panel_dashboard.html} | 0 themes/cosora/public/main.css | 7 +- themes/cosora/public/panel.css | 20 +- 29 files changed, 583 insertions(+), 240 deletions(-) rename templates/{account-menu.html => account_menu.html} (100%) rename templates/{account-own-edit.html => account_own_edit.html} (97%) rename templates/{account-own-edit-avatar.html => account_own_edit_avatar.html} (95%) rename templates/{account-own-edit-email.html => account_own_edit_email.html} (95%) rename templates/{account-own-edit-username.html => account_own_edit_username.html} (96%) rename templates/{are-you-sure.html => are_you_sure.html} (100%) rename templates/{create-topic.html => create_topic.html} (100%) create mode 100644 templates/panel-analytics-agent-views.html rename templates/{panel-dashboard.html => panel_dashboard.html} (100%) diff --git a/common/extend.go b/common/extend.go index 8700c655..2b9896ea 100644 --- a/common/extend.go +++ b/common/extend.go @@ -100,6 +100,7 @@ var PreRenderHooks = map[string][]func(http.ResponseWriter, *http.Request, *User "pre_render_panel_analytics_routes": nil, "pre_render_panel_analytics_agents": nil, "pre_render_panel_analytics_route_views": nil, + "pre_render_panel_analytics_agent_views": nil, "pre_render_panel_settings": nil, "pre_render_panel_setting": nil, "pre_render_panel_word_filters": nil, diff --git a/common/forum.go b/common/forum.go index c7a47cf2..69d9c01a 100644 --- a/common/forum.go +++ b/common/forum.go @@ -94,13 +94,13 @@ func (forum *Forum) Update(name string, desc string, active bool, preset string) func (forum *Forum) SetPreset(preset string, gid int) error { fperms, changed := GroupForumPresetToForumPerms(preset) if changed { - return forum.setPreset(fperms, preset, gid) + return forum.SetPerms(fperms, preset, gid) } return nil } // TODO: Refactor this -func (forum *Forum) setPreset(fperms *ForumPerms, preset string, gid int) (err error) { +func (forum *Forum) SetPerms(fperms *ForumPerms, preset string, gid int) (err error) { err = ReplaceForumPermsForGroup(gid, map[int]string{forum.ID: preset}, map[int]*ForumPerms{forum.ID: fperms}) if err != nil { LogError(err) diff --git a/common/forum_perms.go b/common/forum_perms.go index 60672235..a4b69c21 100644 --- a/common/forum_perms.go +++ b/common/forum_perms.go @@ -217,6 +217,7 @@ func ReplaceForumPermsForGroupTx(tx *sql.Tx, gid int, presetSets map[int]string, } // TODO: Refactor this and write tests for it +// TODO: We really need to improve the thread safety of this func ForumPermsToGroupForumPreset(fperms *ForumPerms) string { if !fperms.Overrides { return "default" diff --git a/common/forum_perms_store.go b/common/forum_perms_store.go index e0699608..7f49653f 100644 --- a/common/forum_perms_store.go +++ b/common/forum_perms_store.go @@ -14,6 +14,7 @@ var FPStore ForumPermsStore type ForumPermsStore interface { Init() error Get(fid int, gid int) (fperms *ForumPerms, err error) + GetCopy(fid int, gid int) (fperms ForumPerms, err error) Reload(id int) error ReloadGroup(fid int, gid int) error } @@ -198,6 +199,8 @@ func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[i } // TODO: Add a hook here and have plugin_guilds use it +// TODO: Check if the forum exists? +// TODO: Fix the races func (fps *MemoryForumPermsStore) Get(fid int, gid int) (fperms *ForumPerms, err error) { group, err := Groups.Get(gid) if err != nil { @@ -205,3 +208,13 @@ func (fps *MemoryForumPermsStore) Get(fid int, gid int) (fperms *ForumPerms, err } return group.Forums[fid], nil } + +// TODO: Check if the forum exists? +// TODO: Fix the races +func (fps *MemoryForumPermsStore) GetCopy(fid int, gid int) (fperms ForumPerms, err error) { + group, err := Groups.Get(gid) + if err != nil { + return fperms, ErrNoRows + } + return *group.Forums[fid], nil +} diff --git a/common/pages.go b/common/pages.go index 928b3dbe..58c74e04 100644 --- a/common/pages.go +++ b/common/pages.go @@ -209,6 +209,17 @@ type PanelAnalyticsRoutePage struct { TimeRange string } +type PanelAnalyticsAgentPage struct { + Title string + CurrentUser User + Header *HeaderVars + Stats PanelStats + Zone string + Agent string + PrimaryGraph PanelTimeGraph + TimeRange string +} + type PanelThemesPage struct { Title string CurrentUser User @@ -281,6 +292,21 @@ type NameLangToggle struct { Toggle bool } +type PanelEditForumGroupPage struct { + Title string + CurrentUser User + Header *HeaderVars + Stats PanelStats + Zone string + ForumID int + GroupID int + Name string + Desc string + Active bool + Preset string + Perms []NameLangToggle +} + type PanelEditGroupPermsPage struct { Title string CurrentUser User diff --git a/common/template_init.go b/common/template_init.go index 3607fd73..dc8ec8d7 100644 --- a/common/template_init.go +++ b/common/template_init.go @@ -73,9 +73,9 @@ var Template_profile_handle func(ProfilePage, http.ResponseWriter) error = func( // nolint var Template_create_topic_handle func(CreateTopicPage, http.ResponseWriter) error = func(pi CreateTopicPage, w http.ResponseWriter) error { - mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["create-topic"] + mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["create_topic"] if !ok { - mapping = "create-topic" + mapping = "create_topic" } return Templates.ExecuteTemplate(w, mapping+".html", pi) } diff --git a/gen_router.go b/gen_router.go index 50199111..307b6e21 100644 --- a/gen_router.go +++ b/gen_router.go @@ -33,6 +33,7 @@ var RouteMap = map[string]interface{}{ "routePanelForumsEditSubmit": routePanelForumsEditSubmit, "routePanelForumsEditPermsSubmit": routePanelForumsEditPermsSubmit, "routePanelForumsEditPermsAdvance": routePanelForumsEditPermsAdvance, + "routePanelForumsEditPermsAdvanceSubmit": routePanelForumsEditPermsAdvanceSubmit, "routePanelSettings": routePanelSettings, "routePanelSettingEdit": routePanelSettingEdit, "routePanelSettingEditSubmit": routePanelSettingEditSubmit, @@ -54,6 +55,7 @@ var RouteMap = map[string]interface{}{ "routePanelAnalyticsRoutes": routePanelAnalyticsRoutes, "routePanelAnalyticsAgents": routePanelAnalyticsAgents, "routePanelAnalyticsRouteViews": routePanelAnalyticsRouteViews, + "routePanelAnalyticsAgentViews": routePanelAnalyticsAgentViews, "routePanelGroups": routePanelGroups, "routePanelGroupsEdit": routePanelGroupsEdit, "routePanelGroupsEditPerms": routePanelGroupsEditPerms, @@ -101,52 +103,54 @@ var routeMapEnum = map[string]int{ "routePanelForumsEditSubmit": 15, "routePanelForumsEditPermsSubmit": 16, "routePanelForumsEditPermsAdvance": 17, - "routePanelSettings": 18, - "routePanelSettingEdit": 19, - "routePanelSettingEditSubmit": 20, - "routePanelWordFilters": 21, - "routePanelWordFiltersCreate": 22, - "routePanelWordFiltersEdit": 23, - "routePanelWordFiltersEditSubmit": 24, - "routePanelWordFiltersDeleteSubmit": 25, - "routePanelThemes": 26, - "routePanelThemesSetDefault": 27, - "routePanelPlugins": 28, - "routePanelPluginsActivate": 29, - "routePanelPluginsDeactivate": 30, - "routePanelPluginsInstall": 31, - "routePanelUsers": 32, - "routePanelUsersEdit": 33, - "routePanelUsersEditSubmit": 34, - "routePanelAnalyticsViews": 35, - "routePanelAnalyticsRoutes": 36, - "routePanelAnalyticsAgents": 37, - "routePanelAnalyticsRouteViews": 38, - "routePanelGroups": 39, - "routePanelGroupsEdit": 40, - "routePanelGroupsEditPerms": 41, - "routePanelGroupsEditSubmit": 42, - "routePanelGroupsEditPermsSubmit": 43, - "routePanelGroupsCreateSubmit": 44, - "routePanelBackups": 45, - "routePanelLogsMod": 46, - "routePanelDebug": 47, - "routePanel": 48, - "routeAccountEditCritical": 49, - "routeAccountEditCriticalSubmit": 50, - "routeAccountEditAvatar": 51, - "routeAccountEditAvatarSubmit": 52, - "routeAccountEditUsername": 53, - "routeAccountEditUsernameSubmit": 54, - "routeAccountEditEmail": 55, - "routeAccountEditEmailTokenSubmit": 56, - "routeProfile": 57, - "routeBanSubmit": 58, - "routeUnban": 59, - "routeActivate": 60, - "routeIps": 61, - "routeDynamic": 62, - "routeUploads": 63, + "routePanelForumsEditPermsAdvanceSubmit": 18, + "routePanelSettings": 19, + "routePanelSettingEdit": 20, + "routePanelSettingEditSubmit": 21, + "routePanelWordFilters": 22, + "routePanelWordFiltersCreate": 23, + "routePanelWordFiltersEdit": 24, + "routePanelWordFiltersEditSubmit": 25, + "routePanelWordFiltersDeleteSubmit": 26, + "routePanelThemes": 27, + "routePanelThemesSetDefault": 28, + "routePanelPlugins": 29, + "routePanelPluginsActivate": 30, + "routePanelPluginsDeactivate": 31, + "routePanelPluginsInstall": 32, + "routePanelUsers": 33, + "routePanelUsersEdit": 34, + "routePanelUsersEditSubmit": 35, + "routePanelAnalyticsViews": 36, + "routePanelAnalyticsRoutes": 37, + "routePanelAnalyticsAgents": 38, + "routePanelAnalyticsRouteViews": 39, + "routePanelAnalyticsAgentViews": 40, + "routePanelGroups": 41, + "routePanelGroupsEdit": 42, + "routePanelGroupsEditPerms": 43, + "routePanelGroupsEditSubmit": 44, + "routePanelGroupsEditPermsSubmit": 45, + "routePanelGroupsCreateSubmit": 46, + "routePanelBackups": 47, + "routePanelLogsMod": 48, + "routePanelDebug": 49, + "routePanel": 50, + "routeAccountEditCritical": 51, + "routeAccountEditCriticalSubmit": 52, + "routeAccountEditAvatar": 53, + "routeAccountEditAvatarSubmit": 54, + "routeAccountEditUsername": 55, + "routeAccountEditUsernameSubmit": 56, + "routeAccountEditEmail": 57, + "routeAccountEditEmailTokenSubmit": 58, + "routeProfile": 59, + "routeBanSubmit": 60, + "routeUnban": 61, + "routeActivate": 62, + "routeIps": 63, + "routeDynamic": 64, + "routeUploads": 65, } var reverseRouteMapEnum = map[int]string{ 0: "routeAPI", @@ -167,52 +171,54 @@ var reverseRouteMapEnum = map[int]string{ 15: "routePanelForumsEditSubmit", 16: "routePanelForumsEditPermsSubmit", 17: "routePanelForumsEditPermsAdvance", - 18: "routePanelSettings", - 19: "routePanelSettingEdit", - 20: "routePanelSettingEditSubmit", - 21: "routePanelWordFilters", - 22: "routePanelWordFiltersCreate", - 23: "routePanelWordFiltersEdit", - 24: "routePanelWordFiltersEditSubmit", - 25: "routePanelWordFiltersDeleteSubmit", - 26: "routePanelThemes", - 27: "routePanelThemesSetDefault", - 28: "routePanelPlugins", - 29: "routePanelPluginsActivate", - 30: "routePanelPluginsDeactivate", - 31: "routePanelPluginsInstall", - 32: "routePanelUsers", - 33: "routePanelUsersEdit", - 34: "routePanelUsersEditSubmit", - 35: "routePanelAnalyticsViews", - 36: "routePanelAnalyticsRoutes", - 37: "routePanelAnalyticsAgents", - 38: "routePanelAnalyticsRouteViews", - 39: "routePanelGroups", - 40: "routePanelGroupsEdit", - 41: "routePanelGroupsEditPerms", - 42: "routePanelGroupsEditSubmit", - 43: "routePanelGroupsEditPermsSubmit", - 44: "routePanelGroupsCreateSubmit", - 45: "routePanelBackups", - 46: "routePanelLogsMod", - 47: "routePanelDebug", - 48: "routePanel", - 49: "routeAccountEditCritical", - 50: "routeAccountEditCriticalSubmit", - 51: "routeAccountEditAvatar", - 52: "routeAccountEditAvatarSubmit", - 53: "routeAccountEditUsername", - 54: "routeAccountEditUsernameSubmit", - 55: "routeAccountEditEmail", - 56: "routeAccountEditEmailTokenSubmit", - 57: "routeProfile", - 58: "routeBanSubmit", - 59: "routeUnban", - 60: "routeActivate", - 61: "routeIps", - 62: "routeDynamic", - 63: "routeUploads", + 18: "routePanelForumsEditPermsAdvanceSubmit", + 19: "routePanelSettings", + 20: "routePanelSettingEdit", + 21: "routePanelSettingEditSubmit", + 22: "routePanelWordFilters", + 23: "routePanelWordFiltersCreate", + 24: "routePanelWordFiltersEdit", + 25: "routePanelWordFiltersEditSubmit", + 26: "routePanelWordFiltersDeleteSubmit", + 27: "routePanelThemes", + 28: "routePanelThemesSetDefault", + 29: "routePanelPlugins", + 30: "routePanelPluginsActivate", + 31: "routePanelPluginsDeactivate", + 32: "routePanelPluginsInstall", + 33: "routePanelUsers", + 34: "routePanelUsersEdit", + 35: "routePanelUsersEditSubmit", + 36: "routePanelAnalyticsViews", + 37: "routePanelAnalyticsRoutes", + 38: "routePanelAnalyticsAgents", + 39: "routePanelAnalyticsRouteViews", + 40: "routePanelAnalyticsAgentViews", + 41: "routePanelGroups", + 42: "routePanelGroupsEdit", + 43: "routePanelGroupsEditPerms", + 44: "routePanelGroupsEditSubmit", + 45: "routePanelGroupsEditPermsSubmit", + 46: "routePanelGroupsCreateSubmit", + 47: "routePanelBackups", + 48: "routePanelLogsMod", + 49: "routePanelDebug", + 50: "routePanel", + 51: "routeAccountEditCritical", + 52: "routeAccountEditCriticalSubmit", + 53: "routeAccountEditAvatar", + 54: "routeAccountEditAvatarSubmit", + 55: "routeAccountEditUsername", + 56: "routeAccountEditUsernameSubmit", + 57: "routeAccountEditEmail", + 58: "routeAccountEditEmailTokenSubmit", + 59: "routeProfile", + 60: "routeBanSubmit", + 61: "routeUnban", + 62: "routeActivate", + 63: "routeIps", + 64: "routeDynamic", + 65: "routeUploads", } var agentMapEnum = map[string]int{ "unknown": 0, @@ -364,6 +370,9 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { common.AgentViewCounter.Bump(11) default: common.AgentViewCounter.Bump(0) + if common.Dev.DebugMode { + log.Print("Unknown UA: ", ua) + } } // Deal with the session stuff, etc. @@ -539,11 +548,20 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { case "/panel/forums/edit/perms/": common.RouteViewCounter.Bump(17) err = routePanelForumsEditPermsAdvance(w,req,user,extraData) - case "/panel/settings/": + case "/panel/forums/edit/perms/adv/submit/": + err = common.NoSessionMismatch(w,req,user) + if err != nil { + router.handleError(err,w,req,user) + return + } + common.RouteViewCounter.Bump(18) + err = routePanelForumsEditPermsAdvanceSubmit(w,req,user,extraData) + case "/panel/settings/": + common.RouteViewCounter.Bump(19) err = routePanelSettings(w,req,user) case "/panel/settings/edit/": - common.RouteViewCounter.Bump(19) + common.RouteViewCounter.Bump(20) err = routePanelSettingEdit(w,req,user,extraData) case "/panel/settings/edit/submit/": err = common.NoSessionMismatch(w,req,user) @@ -552,10 +570,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(20) + common.RouteViewCounter.Bump(21) err = routePanelSettingEditSubmit(w,req,user,extraData) case "/panel/settings/word-filters/": - common.RouteViewCounter.Bump(21) + common.RouteViewCounter.Bump(22) err = routePanelWordFilters(w,req,user) case "/panel/settings/word-filters/create/": err = common.NoSessionMismatch(w,req,user) @@ -564,10 +582,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(22) + common.RouteViewCounter.Bump(23) err = routePanelWordFiltersCreate(w,req,user) case "/panel/settings/word-filters/edit/": - common.RouteViewCounter.Bump(23) + common.RouteViewCounter.Bump(24) err = routePanelWordFiltersEdit(w,req,user,extraData) case "/panel/settings/word-filters/edit/submit/": err = common.NoSessionMismatch(w,req,user) @@ -576,7 +594,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(24) + common.RouteViewCounter.Bump(25) err = routePanelWordFiltersEditSubmit(w,req,user,extraData) case "/panel/settings/word-filters/delete/submit/": err = common.NoSessionMismatch(w,req,user) @@ -585,10 +603,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(25) + common.RouteViewCounter.Bump(26) err = routePanelWordFiltersDeleteSubmit(w,req,user,extraData) case "/panel/themes/": - common.RouteViewCounter.Bump(26) + common.RouteViewCounter.Bump(27) err = routePanelThemes(w,req,user) case "/panel/themes/default/": err = common.NoSessionMismatch(w,req,user) @@ -597,10 +615,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(27) + common.RouteViewCounter.Bump(28) err = routePanelThemesSetDefault(w,req,user,extraData) case "/panel/plugins/": - common.RouteViewCounter.Bump(28) + common.RouteViewCounter.Bump(29) err = routePanelPlugins(w,req,user) case "/panel/plugins/activate/": err = common.NoSessionMismatch(w,req,user) @@ -609,7 +627,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(29) + common.RouteViewCounter.Bump(30) err = routePanelPluginsActivate(w,req,user,extraData) case "/panel/plugins/deactivate/": err = common.NoSessionMismatch(w,req,user) @@ -618,7 +636,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(30) + common.RouteViewCounter.Bump(31) err = routePanelPluginsDeactivate(w,req,user,extraData) case "/panel/plugins/install/": err = common.NoSessionMismatch(w,req,user) @@ -627,13 +645,13 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(31) + common.RouteViewCounter.Bump(32) err = routePanelPluginsInstall(w,req,user,extraData) case "/panel/users/": - common.RouteViewCounter.Bump(32) + common.RouteViewCounter.Bump(33) err = routePanelUsers(w,req,user) case "/panel/users/edit/": - common.RouteViewCounter.Bump(33) + common.RouteViewCounter.Bump(34) err = routePanelUsersEdit(w,req,user,extraData) case "/panel/users/edit/submit/": err = common.NoSessionMismatch(w,req,user) @@ -642,7 +660,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(34) + common.RouteViewCounter.Bump(35) err = routePanelUsersEditSubmit(w,req,user,extraData) case "/panel/analytics/views/": err = common.ParseForm(w,req,user) @@ -651,25 +669,28 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(35) + common.RouteViewCounter.Bump(36) err = routePanelAnalyticsViews(w,req,user) case "/panel/analytics/routes/": - common.RouteViewCounter.Bump(36) + common.RouteViewCounter.Bump(37) err = routePanelAnalyticsRoutes(w,req,user) case "/panel/analytics/agents/": - common.RouteViewCounter.Bump(37) + common.RouteViewCounter.Bump(38) err = routePanelAnalyticsAgents(w,req,user) case "/panel/analytics/route/": - common.RouteViewCounter.Bump(38) - err = routePanelAnalyticsRouteViews(w,req,user,extraData) - case "/panel/groups/": common.RouteViewCounter.Bump(39) + err = routePanelAnalyticsRouteViews(w,req,user,extraData) + case "/panel/analytics/agent/": + common.RouteViewCounter.Bump(40) + err = routePanelAnalyticsAgentViews(w,req,user,extraData) + case "/panel/groups/": + common.RouteViewCounter.Bump(41) err = routePanelGroups(w,req,user) case "/panel/groups/edit/": - common.RouteViewCounter.Bump(40) + common.RouteViewCounter.Bump(42) err = routePanelGroupsEdit(w,req,user,extraData) case "/panel/groups/edit/perms/": - common.RouteViewCounter.Bump(41) + common.RouteViewCounter.Bump(43) err = routePanelGroupsEditPerms(w,req,user,extraData) case "/panel/groups/edit/submit/": err = common.NoSessionMismatch(w,req,user) @@ -678,7 +699,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(42) + common.RouteViewCounter.Bump(44) err = routePanelGroupsEditSubmit(w,req,user,extraData) case "/panel/groups/edit/perms/submit/": err = common.NoSessionMismatch(w,req,user) @@ -687,7 +708,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(43) + common.RouteViewCounter.Bump(45) err = routePanelGroupsEditPermsSubmit(w,req,user,extraData) case "/panel/groups/create/": err = common.NoSessionMismatch(w,req,user) @@ -696,7 +717,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(44) + common.RouteViewCounter.Bump(46) err = routePanelGroupsCreateSubmit(w,req,user) case "/panel/backups/": err = common.SuperAdminOnly(w,req,user) @@ -705,10 +726,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(45) + common.RouteViewCounter.Bump(47) err = routePanelBackups(w,req,user,extraData) case "/panel/logs/mod/": - common.RouteViewCounter.Bump(46) + common.RouteViewCounter.Bump(48) err = routePanelLogsMod(w,req,user) case "/panel/debug/": err = common.AdminOnly(w,req,user) @@ -717,10 +738,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(47) + common.RouteViewCounter.Bump(49) err = routePanelDebug(w,req,user) default: - common.RouteViewCounter.Bump(48) + common.RouteViewCounter.Bump(50) err = routePanel(w,req,user) } if err != nil { @@ -735,7 +756,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(49) + common.RouteViewCounter.Bump(51) err = routeAccountEditCritical(w,req,user) case "/user/edit/critical/submit/": err = common.NoSessionMismatch(w,req,user) @@ -750,7 +771,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(50) + common.RouteViewCounter.Bump(52) err = routeAccountEditCriticalSubmit(w,req,user) case "/user/edit/avatar/": err = common.MemberOnly(w,req,user) @@ -759,7 +780,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(51) + common.RouteViewCounter.Bump(53) err = routeAccountEditAvatar(w,req,user) case "/user/edit/avatar/submit/": err = common.MemberOnly(w,req,user) @@ -768,7 +789,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(52) + common.RouteViewCounter.Bump(54) err = routeAccountEditAvatarSubmit(w,req,user) case "/user/edit/username/": err = common.MemberOnly(w,req,user) @@ -777,7 +798,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(53) + common.RouteViewCounter.Bump(55) err = routeAccountEditUsername(w,req,user) case "/user/edit/username/submit/": err = common.NoSessionMismatch(w,req,user) @@ -792,7 +813,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(54) + common.RouteViewCounter.Bump(56) err = routeAccountEditUsernameSubmit(w,req,user) case "/user/edit/email/": err = common.MemberOnly(w,req,user) @@ -801,7 +822,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(55) + common.RouteViewCounter.Bump(57) err = routeAccountEditEmail(w,req,user) case "/user/edit/token/": err = common.NoSessionMismatch(w,req,user) @@ -816,11 +837,11 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(56) + common.RouteViewCounter.Bump(58) err = routeAccountEditEmailTokenSubmit(w,req,user,extraData) default: req.URL.Path += extraData - common.RouteViewCounter.Bump(57) + common.RouteViewCounter.Bump(59) err = routeProfile(w,req,user) } if err != nil { @@ -841,7 +862,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(58) + common.RouteViewCounter.Bump(60) err = routeBanSubmit(w,req,user,extraData) case "/users/unban/": err = common.NoSessionMismatch(w,req,user) @@ -856,7 +877,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(59) + common.RouteViewCounter.Bump(61) err = routeUnban(w,req,user,extraData) case "/users/activate/": err = common.NoSessionMismatch(w,req,user) @@ -871,7 +892,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(60) + common.RouteViewCounter.Bump(62) err = routeActivate(w,req,user,extraData) case "/users/ips/": err = common.MemberOnly(w,req,user) @@ -880,7 +901,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - common.RouteViewCounter.Bump(61) + common.RouteViewCounter.Bump(63) err = routeIps(w,req,user) } if err != nil { @@ -897,7 +918,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { common.NotFound(w,req) return } - common.RouteViewCounter.Bump(63) + common.RouteViewCounter.Bump(65) req.URL.Path += extraData // TODO: Find a way to propagate errors up from this? router.UploadHandler(w,req) // TODO: Count these views @@ -941,7 +962,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { router.RUnlock() if ok { - common.RouteViewCounter.Bump(62) // TODO: Be more specific about *which* dynamic route it is + common.RouteViewCounter.Bump(64) // TODO: Be more specific about *which* dynamic route it is req.URL.Path += extraData err = handle(w,req,user) if err != nil { diff --git a/general_test.go b/general_test.go index 769076d7..05ef7c95 100644 --- a/general_test.go +++ b/general_test.go @@ -51,12 +51,10 @@ func gloinit() (err error) { if err != nil { return err } - err = common.InitThemes() if err != nil { return err } - common.SwitchToTestDB() var ok bool @@ -70,12 +68,10 @@ func gloinit() (err error) { if err != nil { return err } - err = InitDatabase() if err != nil { return err } - err = afterDBInit() if err != nil { return err diff --git a/member_routes.go b/member_routes.go index c5498787..d710c9f1 100644 --- a/member_routes.go +++ b/member_routes.go @@ -97,7 +97,7 @@ func routeTopicCreate(w http.ResponseWriter, r *http.Request, user common.User, } } - err = common.RunThemeTemplate(headerVars.Theme.Name, "create-topic", ctpage, w) + err = common.RunThemeTemplate(headerVars.Theme.Name, "create_topic", ctpage, w) if err != nil { return common.InternalError(err, w, r) } @@ -646,7 +646,7 @@ func routeAccountEditCritical(w http.ResponseWriter, r *http.Request, user commo return nil } } - err := common.Templates.ExecuteTemplate(w, "account-own-edit.html", pi) + err := common.Templates.ExecuteTemplate(w, "account_own_edit.html", pi) if err != nil { return common.InternalError(err, w, r) } @@ -692,7 +692,7 @@ func routeAccountEditCriticalSubmit(w http.ResponseWriter, r *http.Request, user return nil } } - err = common.Templates.ExecuteTemplate(w, "account-own-edit.html", pi) + err = common.Templates.ExecuteTemplate(w, "account_own_edit.html", pi) if err != nil { return common.InternalError(err, w, r) } @@ -711,7 +711,7 @@ func routeAccountEditAvatar(w http.ResponseWriter, r *http.Request, user common. return nil } } - err := common.Templates.ExecuteTemplate(w, "account-own-edit-avatar.html", pi) + err := common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi) if err != nil { return common.InternalError(err, w, r) } @@ -796,7 +796,7 @@ func routeAccountEditAvatarSubmit(w http.ResponseWriter, r *http.Request, user c return nil } } - err = common.Templates.ExecuteTemplate(w, "account-own-edit-avatar.html", pi) + err = common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi) if err != nil { return common.InternalError(err, w, r) } @@ -815,7 +815,7 @@ func routeAccountEditUsername(w http.ResponseWriter, r *http.Request, user commo return nil } } - err := common.Templates.ExecuteTemplate(w, "account-own-edit-username.html", pi) + err := common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi) if err != nil { return common.InternalError(err, w, r) } @@ -842,7 +842,7 @@ func routeAccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user return nil } } - err = common.Templates.ExecuteTemplate(w, "account-own-edit-username.html", pi) + err = common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi) if err != nil { return common.InternalError(err, w, r) } @@ -897,7 +897,7 @@ func routeAccountEditEmail(w http.ResponseWriter, r *http.Request, user common.U return nil } } - err = common.Templates.ExecuteTemplate(w, "account-own-edit-email.html", pi) + err = common.Templates.ExecuteTemplate(w, "account_own_edit_email.html", pi) if err != nil { return common.InternalError(err, w, r) } @@ -969,7 +969,7 @@ func routeAccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, us return nil } } - err = common.Templates.ExecuteTemplate(w, "account-own-edit-email.html", pi) + err = common.Templates.ExecuteTemplate(w, "account_own_edit_email.html", pi) if err != nil { return common.InternalError(err, w, r) } diff --git a/panel_routes.go b/panel_routes.go index 1edb7146..2607ab67 100644 --- a/panel_routes.go +++ b/panel_routes.go @@ -21,6 +21,30 @@ import ( "github.com/Azareal/gopsutil/mem" ) +// We're trying to reduce the amount of boilerplate in here, so I added these two functions, they might wind up circulating outside this file in the future +func panelSuccessRedirect(dest string, w http.ResponseWriter, r *http.Request, isJs bool) common.RouteError { + if !isJs { + http.Redirect(w, r, dest, http.StatusSeeOther) + } else { + w.Write(successJSONBytes) + } + return nil +} + +// TODO: Implement this properly +/*func panelRenderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, user common.User, pi interface{}) common.RouteError { + if common.PreRenderHooks["pre_render_"+tmplName] != nil { + if common.RunPreRenderHook("pre_render_"+tmplName, w, r, &user, &pi) { + return nil + } + } + err = common.Templates.ExecuteTemplate(w, tmplName+".html", pi) + if err != nil { + return common.InternalError(err, w, r) + } + return nil +}*/ + func routePanel(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { headerVars, stats, ferr := common.PanelUserCheck(w, r, &user) if ferr != nil { @@ -152,11 +176,12 @@ func routePanel(w http.ResponseWriter, r *http.Request, user common.User) common return nil } } - err = common.Templates.ExecuteTemplate(w, "panel-dashboard.html", pi) + err = common.Templates.ExecuteTemplate(w, "panel_dashboard.html", pi) if err != nil { return common.InternalError(err, w, r) } return nil + //return panelRenderTemplate("panel_dashboard",w,r,user,pi) } func routePanelForums(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { @@ -255,7 +280,7 @@ func routePanelForumsDelete(w http.ResponseWriter, r *http.Request, user common. return nil } } - err = common.Templates.ExecuteTemplate(w, "areyousure.html", pi) + err = common.Templates.ExecuteTemplate(w, "are_you_sure.html", pi) if err != nil { return common.InternalError(err, w, r) } @@ -322,6 +347,7 @@ func routePanelForumsEdit(w http.ResponseWriter, r *http.Request, user common.Us if gid == 0 { continue } + // TODO: Don't access the cache on the group directly gplist = append(gplist, common.GroupForumPermPreset{group, common.ForumPermsToGroupForumPreset(group.Forums[fid])}) } @@ -377,13 +403,7 @@ func routePanelForumsEditSubmit(w http.ResponseWriter, r *http.Request, user com if err != nil { return common.InternalErrorJSQ(err, w, r, isJs) } - - if !isJs { - http.Redirect(w, r, "/panel/forums/", http.StatusSeeOther) - } else { - w.Write(successJSONBytes) - } - return nil + return panelSuccessRedirect("/panel/forums/", w, r, isJs) } func routePanelForumsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user common.User, sfid string) common.RouteError { @@ -419,15 +439,30 @@ func routePanelForumsEditPermsSubmit(w http.ResponseWriter, r *http.Request, use return common.LocalErrorJSQ(err.Error(), w, r, user, isJs) } - if !isJs { - http.Redirect(w, r, "/panel/forums/edit/"+strconv.Itoa(fid), http.StatusSeeOther) - } else { - w.Write(successJSONBytes) - } - return nil + return panelSuccessRedirect("/panel/forums/edit/"+strconv.Itoa(fid), w, r, isJs) } -func routePanelForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, user common.User, sfid string) common.RouteError { +// A helper function for the Advanced portion of the Forum Perms Editor +func panelForumPermsExtractDash(paramList string) (fid int, gid int, err error) { + params := strings.Split(paramList, "-") + if len(params) != 2 { + return fid, gid, errors.New("Parameter count mismatch") + } + + fid, err = strconv.Atoi(params[0]) + if err != nil { + return fid, gid, errors.New("The provided Forum ID is not a valid number.") + } + + gid, err = strconv.Atoi(params[1]) + if err != nil { + err = errors.New("The provided Group ID is not a valid number.") + } + + return fid, gid, err +} + +func routePanelForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, user common.User, paramList string) common.RouteError { headerVars, stats, ferr := common.PanelUserCheck(w, r, &user) if ferr != nil { return ferr @@ -436,9 +471,9 @@ func routePanelForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, us return common.NoPermissions(w, r, user) } - fid, err := strconv.Atoi(sfid) + fid, gid, err := panelForumPermsExtractDash(paramList) if err != nil { - return common.LocalError("The provided Forum ID is not a valid number.", w, r, user) + return common.LocalError(err.Error(), w, r, user) } forum, err := common.Forums.Get(fid) @@ -452,20 +487,33 @@ func routePanelForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, us forum.Preset = "custom" } - glist, err := common.Groups.GetAll() - if err != nil { + forumPerms, err := common.FPStore.Get(fid, gid) + if err == ErrNoRows { + return common.LocalError("The requested group doesn't exist.", w, r, user) + } else if err != nil { return common.InternalError(err, w, r) } - var gplist []common.GroupForumPermPreset - for gid, group := range glist { - if gid == 0 { - continue - } - gplist = append(gplist, common.GroupForumPermPreset{group, common.ForumPermsToGroupForumPreset(group.Forums[fid])}) - } + var formattedPermList []common.NameLangToggle - pi := common.PanelEditForumPage{common.GetTitlePhrase("panel-edit-forum"), user, headerVars, stats, "forums", forum.ID, forum.Name, forum.Desc, forum.Active, forum.Preset, gplist} + // TODO: Load the phrases in bulk for efficiency? + // TODO: Reduce the amount of code duplication between this and the group editor. Also, can we grind this down into one line or use a code generator to stay current more easily? + var addNameLangToggle = func(permStr string, perm bool) { + formattedPermList = append(formattedPermList, common.NameLangToggle{permStr, common.GetLocalPermPhrase(permStr), perm}) + } + addNameLangToggle("ViewTopic", forumPerms.ViewTopic) + addNameLangToggle("LikeItem", forumPerms.LikeItem) + addNameLangToggle("CreateTopic", forumPerms.CreateTopic) + //<-- + addNameLangToggle("EditTopic", forumPerms.EditTopic) + addNameLangToggle("DeleteTopic", forumPerms.DeleteTopic) + addNameLangToggle("CreateReply", forumPerms.CreateReply) + addNameLangToggle("EditReply", forumPerms.EditReply) + addNameLangToggle("DeleteReply", forumPerms.DeleteReply) + addNameLangToggle("PinTopic", forumPerms.PinTopic) + addNameLangToggle("CloseTopic", forumPerms.CloseTopic) + + pi := common.PanelEditForumGroupPage{common.GetTitlePhrase("panel-edit-forum"), user, headerVars, stats, "forums", forum.ID, gid, forum.Name, forum.Desc, forum.Active, forum.Preset, formattedPermList} if common.PreRenderHooks["pre_render_panel_edit_forum"] != nil { if common.RunPreRenderHook("pre_render_panel_edit_forum", w, r, &user, &pi) { return nil @@ -479,6 +527,60 @@ func routePanelForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, us return nil } +func routePanelForumsEditPermsAdvanceSubmit(w http.ResponseWriter, r *http.Request, user common.User, paramList string) common.RouteError { + _, ferr := common.SimplePanelUserCheck(w, r, &user) + if ferr != nil { + return ferr + } + if !user.Perms.ManageForums { + return common.NoPermissions(w, r, user) + } + isJs := (r.PostFormValue("js") == "1") + + fid, gid, err := panelForumPermsExtractDash(paramList) + if err != nil { + return common.LocalError(err.Error(), w, r, user) + } + + forum, err := common.Forums.Get(fid) + if err == ErrNoRows { + return common.LocalError("The forum you're trying to edit doesn't exist.", w, r, user) + } else if err != nil { + return common.InternalError(err, w, r) + } + + forumPerms, err := common.FPStore.GetCopy(fid, gid) + if err == ErrNoRows { + return common.LocalError("The requested group doesn't exist.", w, r, user) + } else if err != nil { + return common.InternalError(err, w, r) + } + + var extractPerm = func(name string) bool { + pvalue := r.PostFormValue("forum-perm-" + name) + return (pvalue == "1") + } + + // TODO: Generate this code? + forumPerms.ViewTopic = extractPerm("ViewTopic") + forumPerms.LikeItem = extractPerm("LikeItem") + forumPerms.CreateTopic = extractPerm("CreateTopic") + forumPerms.EditTopic = extractPerm("EditTopic") + forumPerms.DeleteTopic = extractPerm("DeleteTopic") + forumPerms.CreateReply = extractPerm("CreateReply") + forumPerms.EditReply = extractPerm("EditReply") + forumPerms.DeleteReply = extractPerm("DeleteReply") + forumPerms.PinTopic = extractPerm("PinTopic") + forumPerms.CloseTopic = extractPerm("CloseTopic") + + err = forum.SetPerms(&forumPerms, "custom", gid) + if err != nil { + return common.LocalErrorJSQ(err.Error(), w, r, user, isJs) + } + + return panelSuccessRedirect("/panel/forums/edit/perms/"+strconv.Itoa(fid)+"-"+strconv.Itoa(gid), w, r, isJs) +} + func routePanelAnalyticsViews(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { headerVars, stats, ferr := common.PanelUserCheck(w, r, &user) if ferr != nil { @@ -628,6 +730,7 @@ func routePanelAnalyticsRouteViews(w http.ResponseWriter, r *http.Request, user log.Print("in routePanelAnalyticsRouteViews") acc := qgen.Builder.Accumulator() + // TODO: Validate the route is valid rows, err := acc.Select("viewchunks").Columns("count, createdAt").Where("route = ?").DateCutoff("createdAt", timeQuantity, timeUnit).Query(route) if err != nil && err != ErrNoRows { return common.InternalError(err, w, r) @@ -677,6 +780,105 @@ func routePanelAnalyticsRouteViews(w http.ResponseWriter, r *http.Request, user return nil } +func routePanelAnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user common.User, agent string) common.RouteError { + headerVars, stats, ferr := common.PanelUserCheck(w, r, &user) + if ferr != nil { + return ferr + } + headerVars.Stylesheets = append(headerVars.Stylesheets, "chartist/chartist.min.css") + headerVars.Scripts = append(headerVars.Scripts, "chartist/chartist.min.js") + + var timeQuantity = 6 + var timeUnit = "hour" + var timeSlices = 12 + var sliceWidth = 60 * 30 + var timeRange = "six-hours" + + switch r.FormValue("timeRange") { + case "one-day": + timeQuantity = 1 + timeUnit = "day" + timeSlices = 24 + sliceWidth = 60 * 60 + timeRange = "one-day" + case "twelve-hours": + timeQuantity = 12 + timeSlices = 24 + timeRange = "twelve-hours" + case "six-hours", "": + timeRange = "six-hours" + default: + return common.LocalError("Unknown time range", w, r, user) + } + + var revLabelList []int64 + var labelList []int64 + var viewMap = make(map[int64]int64) + var currentTime = time.Now().Unix() + + for i := 1; i <= timeSlices; i++ { + var label = currentTime - int64(i*sliceWidth) + revLabelList = append(revLabelList, label) + viewMap[label] = 0 + } + for _, value := range revLabelList { + labelList = append(labelList, value) + } + + var viewList []int64 + log.Print("in routePanelAnalyticsAgentViews") + + acc := qgen.Builder.Accumulator() + // TODO: Verify the agent is valid + rows, err := acc.Select("viewchunks_agents").Columns("count, createdAt").Where("browser = ?").DateCutoff("createdAt", timeQuantity, timeUnit).Query(agent) + if err != nil && err != ErrNoRows { + return common.InternalError(err, w, r) + } + defer rows.Close() + + for rows.Next() { + var count int64 + var createdAt time.Time + err := rows.Scan(&count, &createdAt) + if err != nil { + return common.InternalError(err, w, r) + } + log.Print("count: ", count) + log.Print("createdAt: ", createdAt) + + var unixCreatedAt = createdAt.Unix() + log.Print("unixCreatedAt: ", unixCreatedAt) + for _, value := range labelList { + if unixCreatedAt > value { + viewMap[value] += count + break + } + } + } + err = rows.Err() + if err != nil { + return common.InternalError(err, w, r) + } + + for _, value := range revLabelList { + viewList = append(viewList, viewMap[value]) + } + graph := common.PanelTimeGraph{Series: viewList, Labels: labelList} + log.Printf("graph: %+v\n", graph) + + pi := common.PanelAnalyticsAgentPage{common.GetTitlePhrase("panel-analytics"), user, headerVars, stats, "analytics", html.EscapeString(agent), graph, timeRange} + if common.PreRenderHooks["pre_render_panel_analytics_agent_views"] != nil { + if common.RunPreRenderHook("pre_render_panel_analytics_agent_views", w, r, &user, &pi) { + return nil + } + } + err = common.Templates.ExecuteTemplate(w, "panel-analytics-agent-views.html", pi) + if err != nil { + return common.InternalError(err, w, r) + } + return nil +} + func routePanelAnalyticsRoutes(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { headerVars, stats, ferr := common.PanelUserCheck(w, r, &user) if ferr != nil { @@ -951,13 +1153,7 @@ func routePanelWordFiltersCreate(w http.ResponseWriter, r *http.Request, user co } common.AddWordFilter(int(lastID), find, replacement) - - if !isJs { - http.Redirect(w, r, "/panel/settings/word-filters/", http.StatusSeeOther) - } else { - w.Write(successJSONBytes) - } - return nil + return panelSuccessRedirect("/panel/settings/word-filters/", w, r, isJs) } func routePanelWordFiltersEdit(w http.ResponseWriter, r *http.Request, user common.User, wfid string) common.RouteError { @@ -1586,39 +1782,48 @@ func routePanelGroupsEditPerms(w http.ResponseWriter, r *http.Request, user comm // TODO: Load the phrases in bulk for efficiency? var localPerms []common.NameLangToggle - localPerms = append(localPerms, common.NameLangToggle{"ViewTopic", common.GetLocalPermPhrase("ViewTopic"), group.Perms.ViewTopic}) - localPerms = append(localPerms, common.NameLangToggle{"LikeItem", common.GetLocalPermPhrase("LikeItem"), group.Perms.LikeItem}) - localPerms = append(localPerms, common.NameLangToggle{"CreateTopic", common.GetLocalPermPhrase("CreateTopic"), group.Perms.CreateTopic}) + + var addLocalPerm = func(permStr string, perm bool) { + localPerms = append(localPerms, common.NameLangToggle{permStr, common.GetLocalPermPhrase(permStr), perm}) + } + + addLocalPerm("ViewTopic", group.Perms.ViewTopic) + addLocalPerm("LikeItem", group.Perms.LikeItem) + addLocalPerm("CreateTopic", group.Perms.CreateTopic) //<-- - localPerms = append(localPerms, common.NameLangToggle{"EditTopic", common.GetLocalPermPhrase("EditTopic"), group.Perms.EditTopic}) - localPerms = append(localPerms, common.NameLangToggle{"DeleteTopic", common.GetLocalPermPhrase("DeleteTopic"), group.Perms.DeleteTopic}) - localPerms = append(localPerms, common.NameLangToggle{"CreateReply", common.GetLocalPermPhrase("CreateReply"), group.Perms.CreateReply}) - localPerms = append(localPerms, common.NameLangToggle{"EditReply", common.GetLocalPermPhrase("EditReply"), group.Perms.EditReply}) - localPerms = append(localPerms, common.NameLangToggle{"DeleteReply", common.GetLocalPermPhrase("DeleteReply"), group.Perms.DeleteReply}) - localPerms = append(localPerms, common.NameLangToggle{"PinTopic", common.GetLocalPermPhrase("PinTopic"), group.Perms.PinTopic}) - localPerms = append(localPerms, common.NameLangToggle{"CloseTopic", common.GetLocalPermPhrase("CloseTopic"), group.Perms.CloseTopic}) + addLocalPerm("EditTopic", group.Perms.EditTopic) + addLocalPerm("DeleteTopic", group.Perms.DeleteTopic) + addLocalPerm("CreateReply", group.Perms.CreateReply) + addLocalPerm("EditReply", group.Perms.EditReply) + addLocalPerm("DeleteReply", group.Perms.DeleteReply) + addLocalPerm("PinTopic", group.Perms.PinTopic) + addLocalPerm("CloseTopic", group.Perms.CloseTopic) var globalPerms []common.NameLangToggle - globalPerms = append(globalPerms, common.NameLangToggle{"BanUsers", common.GetGlobalPermPhrase("BanUsers"), group.Perms.BanUsers}) - globalPerms = append(globalPerms, common.NameLangToggle{"ActivateUsers", common.GetGlobalPermPhrase("ActivateUsers"), group.Perms.ActivateUsers}) - globalPerms = append(globalPerms, common.NameLangToggle{"EditUser", common.GetGlobalPermPhrase("EditUser"), group.Perms.EditUser}) - globalPerms = append(globalPerms, common.NameLangToggle{"EditUserEmail", common.GetGlobalPermPhrase("EditUserEmail"), group.Perms.EditUserEmail}) - globalPerms = append(globalPerms, common.NameLangToggle{"EditUserPassword", common.GetGlobalPermPhrase("EditUserPassword"), group.Perms.EditUserPassword}) - globalPerms = append(globalPerms, common.NameLangToggle{"EditUserGroup", common.GetGlobalPermPhrase("EditUserGroup"), group.Perms.EditUserGroup}) - globalPerms = append(globalPerms, common.NameLangToggle{"EditUserGroupSuperMod", common.GetGlobalPermPhrase("EditUserGroupSuperMod"), group.Perms.EditUserGroupSuperMod}) - globalPerms = append(globalPerms, common.NameLangToggle{"EditUserGroupAdmin", common.GetGlobalPermPhrase("EditUserGroupAdmin"), group.Perms.EditUserGroupAdmin}) - globalPerms = append(globalPerms, common.NameLangToggle{"EditGroup", common.GetGlobalPermPhrase("EditGroup"), group.Perms.EditGroup}) - globalPerms = append(globalPerms, common.NameLangToggle{"EditGroupLocalPerms", common.GetGlobalPermPhrase("EditGroupLocalPerms"), group.Perms.EditGroupLocalPerms}) - globalPerms = append(globalPerms, common.NameLangToggle{"EditGroupGlobalPerms", common.GetGlobalPermPhrase("EditGroupGlobalPerms"), group.Perms.EditGroupGlobalPerms}) - globalPerms = append(globalPerms, common.NameLangToggle{"EditGroupSuperMod", common.GetGlobalPermPhrase("EditGroupSuperMod"), group.Perms.EditGroupSuperMod}) - globalPerms = append(globalPerms, common.NameLangToggle{"EditGroupAdmin", common.GetGlobalPermPhrase("EditGroupAdmin"), group.Perms.EditGroupAdmin}) - globalPerms = append(globalPerms, common.NameLangToggle{"ManageForums", common.GetGlobalPermPhrase("ManageForums"), group.Perms.ManageForums}) - globalPerms = append(globalPerms, common.NameLangToggle{"EditSettings", common.GetGlobalPermPhrase("EditSettings"), group.Perms.EditSettings}) - globalPerms = append(globalPerms, common.NameLangToggle{"ManageThemes", common.GetGlobalPermPhrase("ManageThemes"), group.Perms.ManageThemes}) - globalPerms = append(globalPerms, common.NameLangToggle{"ManagePlugins", common.GetGlobalPermPhrase("ManagePlugins"), group.Perms.ManagePlugins}) - globalPerms = append(globalPerms, common.NameLangToggle{"ViewAdminLogs", common.GetGlobalPermPhrase("ViewAdminLogs"), group.Perms.ViewAdminLogs}) - globalPerms = append(globalPerms, common.NameLangToggle{"ViewIPs", common.GetGlobalPermPhrase("ViewIPs"), group.Perms.ViewIPs}) - globalPerms = append(globalPerms, common.NameLangToggle{"UploadFiles", common.GetGlobalPermPhrase("UploadFiles"), group.Perms.UploadFiles}) + var addGlobalPerm = func(permStr string, perm bool) { + globalPerms = append(globalPerms, common.NameLangToggle{permStr, common.GetGlobalPermPhrase(permStr), perm}) + } + + addGlobalPerm("BanUsers", group.Perms.BanUsers) + addGlobalPerm("ActivateUsers", group.Perms.ActivateUsers) + addGlobalPerm("EditUser", group.Perms.EditUser) + addGlobalPerm("EditUserEmail", group.Perms.EditUserEmail) + addGlobalPerm("EditUserPassword", group.Perms.EditUserPassword) + addGlobalPerm("EditUserGroup", group.Perms.EditUserGroup) + addGlobalPerm("EditUserGroupSuperMod", group.Perms.EditUserGroupSuperMod) + addGlobalPerm("EditUserGroupAdmin", group.Perms.EditUserGroupAdmin) + addGlobalPerm("EditGroup", group.Perms.EditGroup) + addGlobalPerm("EditGroupLocalPerms", group.Perms.EditGroupLocalPerms) + addGlobalPerm("EditGroupGlobalPerms", group.Perms.EditGroupGlobalPerms) + addGlobalPerm("EditGroupSuperMod", group.Perms.EditGroupSuperMod) + addGlobalPerm("EditGroupAdmin", group.Perms.EditGroupAdmin) + addGlobalPerm("ManageForums", group.Perms.ManageForums) + addGlobalPerm("EditSettings", group.Perms.EditSettings) + addGlobalPerm("ManageThemes", group.Perms.ManageThemes) + addGlobalPerm("ManagePlugins", group.Perms.ManagePlugins) + addGlobalPerm("ViewAdminLogs", group.Perms.ViewAdminLogs) + addGlobalPerm("ViewIPs", group.Perms.ViewIPs) + addGlobalPerm("UploadFiles", group.Perms.UploadFiles) pi := common.PanelEditGroupPermsPage{common.GetTitlePhrase("panel-edit-group"), user, headerVars, stats, "groups", group.ID, group.Name, localPerms, globalPerms} if common.PreRenderHooks["pre_render_panel_edit_group_perms"] != nil { @@ -1768,6 +1973,7 @@ func routePanelGroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, use } } + // TODO: Abstract this pjson, err := json.Marshal(pmap) if err != nil { return common.LocalError("Unable to marshal the data", w, r, user) diff --git a/public/global.js b/public/global.js index c08b9589..7f757eb4 100644 --- a/public/global.js +++ b/public/global.js @@ -546,6 +546,16 @@ $(document).ready(function(){ window.location = this.form.getAttribute("action")+"?timeRange=" + this.options[this.selectedIndex].getAttribute("val"); // Do a redirect as a form submission refuses to work properly }); + $(".unix_to_24_hour_time").each(function(){ + let unixTime = this.innerText; + let date = new Date(unixTime*1000); + console.log("date: ", date); + let minutes = "0" + date.getMinutes(); + let formattedTime = date.getHours() + ":" + minutes.substr(-2); + console.log("formattedTime:", formattedTime); + this.innerText = formattedTime; + }); + this.onkeyup = function(event) { if(event.which == 37) this.querySelectorAll("#prevFloat a")[0].click(); if(event.which == 39) this.querySelectorAll("#nextFloat a")[0].click(); diff --git a/router_gen/main.go b/router_gen/main.go index 784dd27b..0ac9818c 100644 --- a/router_gen/main.go +++ b/router_gen/main.go @@ -333,6 +333,9 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { common.AgentViewCounter.Bump({{.AllAgentMap.duckduckgo}}) default: common.AgentViewCounter.Bump({{.AllAgentMap.unknown}}) + if common.Dev.DebugMode { + log.Print("Unknown UA: ", ua) + } } // Deal with the session stuff, etc. diff --git a/router_gen/routes.go b/router_gen/routes.go index 6a4be933..222a1e68 100644 --- a/router_gen/routes.go +++ b/router_gen/routes.go @@ -67,6 +67,7 @@ func buildPanelRoutes() { Action("routePanelForumsEditSubmit", "/panel/forums/edit/submit/", "extraData"), Action("routePanelForumsEditPermsSubmit", "/panel/forums/edit/perms/submit/", "extraData"), View("routePanelForumsEditPermsAdvance", "/panel/forums/edit/perms/", "extraData"), + Action("routePanelForumsEditPermsAdvanceSubmit", "/panel/forums/edit/perms/adv/submit/", "extraData"), View("routePanelSettings", "/panel/settings/"), View("routePanelSettingEdit", "/panel/settings/edit/", "extraData"), @@ -94,6 +95,7 @@ func buildPanelRoutes() { View("routePanelAnalyticsRoutes", "/panel/analytics/routes/"), View("routePanelAnalyticsAgents", "/panel/analytics/agents/"), View("routePanelAnalyticsRouteViews", "/panel/analytics/route/", "extraData"), + View("routePanelAnalyticsAgentViews", "/panel/analytics/agent/", "extraData"), View("routePanelGroups", "/panel/groups/"), View("routePanelGroupsEdit", "/panel/groups/edit/", "extraData"), diff --git a/templates/account-menu.html b/templates/account_menu.html similarity index 100% rename from templates/account-menu.html rename to templates/account_menu.html diff --git a/templates/account-own-edit.html b/templates/account_own_edit.html similarity index 97% rename from templates/account-own-edit.html rename to templates/account_own_edit.html index 0adde078..f74f8fb8 100644 --- a/templates/account-own-edit.html +++ b/templates/account_own_edit.html @@ -1,6 +1,6 @@ {{template "header.html" . }}
- {{template "account-menu.html" . }} + {{template "account_menu.html" . }}

Edit Password

diff --git a/templates/account-own-edit-avatar.html b/templates/account_own_edit_avatar.html similarity index 95% rename from templates/account-own-edit-avatar.html rename to templates/account_own_edit_avatar.html index 965e3a04..31d484d1 100644 --- a/templates/account-own-edit-avatar.html +++ b/templates/account_own_edit_avatar.html @@ -1,6 +1,6 @@ {{template "header.html" . }}