Added the active memory analytics pane. More to come here.
Added the meta store. Added the panel_menu_statistics_active_memory phrase. Added the panel_statistics_active_memory_head phrase. Added the panel_analytics_time_range_month template. Added Go 1.12 to the Travis list. Added the stack and heap columns to the memchunks table. Added the createdAt column to the activity_stream table. Added the meta table. You will need to run the patcher / updater for this commit.
This commit is contained in:
parent
e76223224a
commit
f10fdcb40c
|
@ -4,6 +4,7 @@ env:
|
||||||
language: go
|
language: go
|
||||||
go:
|
go:
|
||||||
- "1.11"
|
- "1.11"
|
||||||
|
- "1.12"
|
||||||
- master
|
- master
|
||||||
before_install:
|
before_install:
|
||||||
- cd $HOME
|
- cd $HOME
|
||||||
|
|
|
@ -377,6 +377,7 @@ func createTables(adapter qgen.Adapter) error {
|
||||||
tblColumn{"event", "varchar", 50, false, false, ""}, /* mention, like, reply (as in the act of replying to an item, not the reply item type, you can "reply" to a forum by making a topic in it), friend_invite */
|
tblColumn{"event", "varchar", 50, false, false, ""}, /* mention, like, reply (as in the act of replying to an item, not the reply item type, you can "reply" to a forum by making a topic in it), friend_invite */
|
||||||
tblColumn{"elementType", "varchar", 50, false, false, ""}, /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */
|
tblColumn{"elementType", "varchar", 50, false, false, ""}, /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */
|
||||||
tblColumn{"elementID", "int", 0, false, false, ""}, /* the ID of the element being acted upon */
|
tblColumn{"elementID", "int", 0, false, false, ""}, /* the ID of the element being acted upon */
|
||||||
|
tblColumn{"createdAt", "createdAt", 0, false, false, ""},
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
tblKey{"asid", "primary","",false},
|
tblKey{"asid", "primary","",false},
|
||||||
|
@ -620,6 +621,8 @@ func createTables(adapter qgen.Adapter) error {
|
||||||
qgen.Install.CreateTable("memchunks", "", "",
|
qgen.Install.CreateTable("memchunks", "", "",
|
||||||
[]tblColumn{
|
[]tblColumn{
|
||||||
tblColumn{"count", "int", 0, false, false, "0"},
|
tblColumn{"count", "int", 0, false, false, "0"},
|
||||||
|
tblColumn{"stack", "int", 0, false, false, "0"},
|
||||||
|
tblColumn{"heap", "int", 0, false, false, "0"},
|
||||||
tblColumn{"createdAt", "datetime", 0, false, false, ""},
|
tblColumn{"createdAt", "datetime", 0, false, false, ""},
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
@ -636,5 +639,12 @@ func createTables(adapter qgen.Adapter) error {
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
qgen.Install.CreateTable("meta", "", "",
|
||||||
|
[]tblColumn{
|
||||||
|
tblColumn{"name", "varchar", 200, false, false, ""},
|
||||||
|
tblColumn{"value", "varchar", 200, false, false, ""},
|
||||||
|
}, nil,
|
||||||
|
)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,20 @@ var MemoryCounter *DefaultMemoryCounter
|
||||||
|
|
||||||
type DefaultMemoryCounter struct {
|
type DefaultMemoryCounter struct {
|
||||||
insert *sql.Stmt
|
insert *sql.Stmt
|
||||||
|
|
||||||
totMem uint64
|
totMem uint64
|
||||||
totCount uint64
|
totCount uint64
|
||||||
|
stackMem uint64
|
||||||
|
stackCount uint64
|
||||||
|
heapMem uint64
|
||||||
|
heapCount uint64
|
||||||
|
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMemoryCounter(acc *qgen.Accumulator) (*DefaultMemoryCounter, error) {
|
func NewMemoryCounter(acc *qgen.Accumulator) (*DefaultMemoryCounter, error) {
|
||||||
co := &DefaultMemoryCounter{
|
co := &DefaultMemoryCounter{
|
||||||
insert: acc.Insert("memchunks").Columns("count, createdAt").Fields("?,UTC_TIMESTAMP()").Prepare(),
|
insert: acc.Insert("memchunks").Columns("count, stack, heap, createdAt").Fields("?,?,?,UTC_TIMESTAMP()").Prepare(),
|
||||||
}
|
}
|
||||||
c.AddScheduledFifteenMinuteTask(co.Tick)
|
c.AddScheduledFifteenMinuteTask(co.Tick)
|
||||||
//c.AddScheduledSecondTask(co.Tick)
|
//c.AddScheduledSecondTask(co.Tick)
|
||||||
|
@ -36,6 +42,10 @@ func NewMemoryCounter(acc *qgen.Accumulator) (*DefaultMemoryCounter, error) {
|
||||||
co.Lock()
|
co.Lock()
|
||||||
co.totCount++
|
co.totCount++
|
||||||
co.totMem += m.Sys
|
co.totMem += m.Sys
|
||||||
|
co.stackCount++
|
||||||
|
co.stackMem += m.StackInuse
|
||||||
|
co.heapCount++
|
||||||
|
co.heapMem += m.HeapAlloc
|
||||||
co.Unlock()
|
co.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,15 +56,30 @@ func NewMemoryCounter(acc *qgen.Accumulator) (*DefaultMemoryCounter, error) {
|
||||||
func (co *DefaultMemoryCounter) Tick() (err error) {
|
func (co *DefaultMemoryCounter) Tick() (err error) {
|
||||||
var m runtime.MemStats
|
var m runtime.MemStats
|
||||||
runtime.ReadMemStats(&m)
|
runtime.ReadMemStats(&m)
|
||||||
var avgMem uint64
|
var avgMem, avgStack, avgHeap uint64
|
||||||
co.Lock()
|
co.Lock()
|
||||||
|
|
||||||
co.totCount++
|
co.totCount++
|
||||||
co.totMem += m.Sys
|
co.totMem += m.Sys
|
||||||
|
co.stackCount++
|
||||||
|
co.stackMem += m.StackInuse
|
||||||
|
co.heapCount++
|
||||||
|
co.heapMem += m.HeapAlloc
|
||||||
|
|
||||||
avgMem = co.totMem / co.totCount
|
avgMem = co.totMem / co.totCount
|
||||||
|
avgStack = co.stackMem / co.stackCount
|
||||||
|
avgHeap = co.heapMem / co.heapCount
|
||||||
|
|
||||||
co.totMem = 0
|
co.totMem = 0
|
||||||
co.totCount = 0
|
co.totCount = 0
|
||||||
|
co.stackMem = 0
|
||||||
|
co.stackCount = 0
|
||||||
|
co.heapMem = 0
|
||||||
|
co.heapCount = 0
|
||||||
|
|
||||||
co.Unlock()
|
co.Unlock()
|
||||||
c.DebugLogf("Inserting a memchunk with a value of %d", avgMem)
|
|
||||||
_, err = co.insert.Exec(avgMem)
|
c.DebugLogf("Inserting a memchunk with a value of %d - %d - %d", avgMem, avgStack, avgHeap)
|
||||||
|
_, err = co.insert.Exec(avgMem, avgStack, avgHeap)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import "database/sql"
|
||||||
|
import "github.com/Azareal/Gosora/query_gen"
|
||||||
|
|
||||||
|
var Meta MetaStore
|
||||||
|
|
||||||
|
// MetaStore is a simple key-value store for the system to stash things in when needed
|
||||||
|
type MetaStore interface {
|
||||||
|
Get(name string) (val string, err error)
|
||||||
|
Set(name string, val string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type DefaultMetaStore struct {
|
||||||
|
get *sql.Stmt
|
||||||
|
set *sql.Stmt
|
||||||
|
add *sql.Stmt
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultMetaStore(acc *qgen.Accumulator) (*DefaultMetaStore, error) {
|
||||||
|
m := &DefaultMetaStore{
|
||||||
|
get: acc.Select("meta").Columns("value").Where("name = ?").Prepare(),
|
||||||
|
set: acc.Update("meta").Set("value = ?").Where("name = ?").Prepare(),
|
||||||
|
add: acc.Insert("meta").Columns("name,value").Fields("?,''").Prepare(),
|
||||||
|
}
|
||||||
|
return m, acc.FirstError()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DefaultMetaStore) Get(name string) (val string, err error) {
|
||||||
|
err = s.get.QueryRow(name).Scan(&val)
|
||||||
|
return val, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Use timestamped rows as a more robust method of ensuring data integrity
|
||||||
|
func (s *DefaultMetaStore) Set(name string, val string) error {
|
||||||
|
_, err := s.Get(name)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
_, err := s.add.Exec(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err = s.set.Exec(val, name)
|
||||||
|
return err
|
||||||
|
}
|
|
@ -334,6 +334,7 @@ type PanelPage struct {
|
||||||
|
|
||||||
type GridElement struct {
|
type GridElement struct {
|
||||||
ID string
|
ID string
|
||||||
|
Href string
|
||||||
Body string
|
Body string
|
||||||
Order int // For future use
|
Order int // For future use
|
||||||
Class string
|
Class string
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Gosora Topic Store
|
* Gosora Topic Store
|
||||||
* Copyright Azareal 2017 - 2019
|
* Copyright Azareal 2017 - 2020
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package common
|
package common
|
||||||
|
|
|
@ -41,6 +41,7 @@ func init() {
|
||||||
type WsTopicList struct {
|
type WsTopicList struct {
|
||||||
Topics []*WsTopicsRow
|
Topics []*WsTopicsRow
|
||||||
LastPage int // Not for WebSockets, but for the JSON endpoint for /topics/ to keep the paginator functional
|
LastPage int // Not for WebSockets, but for the JSON endpoint for /topics/ to keep the paginator functional
|
||||||
|
LastUpdate int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: How should we handle errors for this?
|
// TODO: How should we handle errors for this?
|
||||||
|
@ -78,8 +79,7 @@ func RouteWebsockets(w http.ResponseWriter, r *http.Request, user User) RouteErr
|
||||||
panic("conn must not be nil")
|
panic("conn must not be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
messages := bytes.Split(message, []byte("\r"))
|
for _, msg := range bytes.Split(message, []byte("\r")) {
|
||||||
for _, msg := range messages {
|
|
||||||
//StoppedServer("Profile end") // A bit of code for me to profile the software
|
//StoppedServer("Profile end") // A bit of code for me to profile the software
|
||||||
if bytes.HasPrefix(msg, []byte("page ")) {
|
if bytes.HasPrefix(msg, []byte("page ")) {
|
||||||
msgblocks := bytes.SplitN(msg, []byte(" "), 2)
|
msgblocks := bytes.SplitN(msg, []byte(" "), 2)
|
||||||
|
@ -93,11 +93,22 @@ func RouteWebsockets(w http.ResponseWriter, r *http.Request, user User) RouteErr
|
||||||
wsPageResponses(wsUser, conn, currentPage)
|
wsPageResponses(wsUser, conn, currentPage)
|
||||||
}
|
}
|
||||||
} else if bytes.HasPrefix(msg, []byte("resume ")) {
|
} else if bytes.HasPrefix(msg, []byte("resume ")) {
|
||||||
msgblocks := bytes.SplitN(msg, []byte(" "), 2)
|
msgblocks := bytes.SplitN(msg, []byte(" "), 3)
|
||||||
if len(msgblocks) < 2 {
|
if len(msgblocks) < 3 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//log.Print("resuming on " + string(msgblocks[1]))
|
//log.Print("resuming on " + string(msgblocks[1]) + " at " + string(msgblocks[2]))
|
||||||
|
|
||||||
|
if !bytes.Equal(msgblocks[1], []byte(currentPage)) {
|
||||||
|
wsLeavePage(wsUser, conn, currentPage) // Avoid clients abusing late resumes
|
||||||
|
currentPage = string(msgblocks[1])
|
||||||
|
// TODO: Synchronise this better?
|
||||||
|
resume, err := strconv.ParseInt(string(msgblocks[2]), 10, 64)
|
||||||
|
wsPageResponses(wsUser, conn, currentPage)
|
||||||
|
if err != nil {
|
||||||
|
wsPageResume(wsUser, conn, currentPage, resume)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*if bytes.Equal(message,[]byte(`start-view`)) {
|
/*if bytes.Equal(message,[]byte(`start-view`)) {
|
||||||
} else if bytes.Equal(message,[]byte(`end-view`)) {
|
} else if bytes.Equal(message,[]byte(`end-view`)) {
|
||||||
|
@ -197,6 +208,26 @@ func wsPageResponses(wsUser *WSUser, conn *websocket.Conn, page string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Use a map instead of a switch to make this more modular?
|
||||||
|
// TODO: Implement this
|
||||||
|
func wsPageResume(wsUser *WSUser, conn *websocket.Conn, page string, resume int64) {
|
||||||
|
if page == "/" {
|
||||||
|
page = Config.DefaultPath
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
// TODO: Synchronise this bit of resume with tick updating lastTopicList?
|
||||||
|
case page == "/topics/":
|
||||||
|
/*if resume >= hub.lastTick.Unix() {
|
||||||
|
conn.Write([]byte("resume tooslow"))
|
||||||
|
} else {
|
||||||
|
conn.Write([]byte("resume success"))
|
||||||
|
}*/
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Use a map instead of a switch to make this more modular?
|
// TODO: Use a map instead of a switch to make this more modular?
|
||||||
func wsLeavePage(wsUser *WSUser, conn *websocket.Conn, page string) {
|
func wsLeavePage(wsUser *WSUser, conn *websocket.Conn, page string) {
|
||||||
if page == "/" {
|
if page == "/" {
|
||||||
|
|
|
@ -77,16 +77,17 @@ func wsTopicListTick(hub *WsHubImpl) error {
|
||||||
if !TopicListThaw.Thawed() && hub.lastTopicList != nil {
|
if !TopicListThaw.Thawed() && hub.lastTopicList != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
tickStart := time.Now()
|
||||||
|
|
||||||
// Don't waste CPU time if nothing has happened
|
// Don't waste CPU time if nothing has happened
|
||||||
// TODO: Get a topic list method which strips stickies?
|
// TODO: Get a topic list method which strips stickies?
|
||||||
tList, _, _, err := TopicList.GetList(1, "", nil)
|
tList, _, _, err := TopicList.GetList(1, "", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hub.lastTick = time.Now()
|
hub.lastTick = tickStart
|
||||||
return err // TODO: Do we get ErrNoRows here?
|
return err // TODO: Do we get ErrNoRows here?
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
hub.lastTick = time.Now()
|
hub.lastTick = tickStart
|
||||||
hub.lastTopicList = tList
|
hub.lastTopicList = tList
|
||||||
}()
|
}()
|
||||||
if len(tList) == 0 {
|
if len(tList) == 0 {
|
||||||
|
@ -177,7 +178,7 @@ func wsTopicListTick(hub *WsHubImpl) error {
|
||||||
wsTopicList[i] = topicRow.WebSockets()
|
wsTopicList[i] = topicRow.WebSockets()
|
||||||
}
|
}
|
||||||
|
|
||||||
outBytes, err := json.Marshal(&WsTopicList{wsTopicList, 0})
|
outBytes, err := json.Marshal(&WsTopicList{wsTopicList, 0, tickStart.Unix()})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
449
gen_router.go
449
gen_router.go
|
@ -95,6 +95,7 @@ var RouteMap = map[string]interface{}{
|
||||||
"panel.AnalyticsReferrerViews": panel.AnalyticsReferrerViews,
|
"panel.AnalyticsReferrerViews": panel.AnalyticsReferrerViews,
|
||||||
"panel.AnalyticsPosts": panel.AnalyticsPosts,
|
"panel.AnalyticsPosts": panel.AnalyticsPosts,
|
||||||
"panel.AnalyticsMemory": panel.AnalyticsMemory,
|
"panel.AnalyticsMemory": panel.AnalyticsMemory,
|
||||||
|
"panel.AnalyticsActiveMemory": panel.AnalyticsActiveMemory,
|
||||||
"panel.AnalyticsTopics": panel.AnalyticsTopics,
|
"panel.AnalyticsTopics": panel.AnalyticsTopics,
|
||||||
"panel.AnalyticsForums": panel.AnalyticsForums,
|
"panel.AnalyticsForums": panel.AnalyticsForums,
|
||||||
"panel.Groups": panel.Groups,
|
"panel.Groups": panel.Groups,
|
||||||
|
@ -244,79 +245,80 @@ var routeMapEnum = map[string]int{
|
||||||
"panel.AnalyticsReferrerViews": 69,
|
"panel.AnalyticsReferrerViews": 69,
|
||||||
"panel.AnalyticsPosts": 70,
|
"panel.AnalyticsPosts": 70,
|
||||||
"panel.AnalyticsMemory": 71,
|
"panel.AnalyticsMemory": 71,
|
||||||
"panel.AnalyticsTopics": 72,
|
"panel.AnalyticsActiveMemory": 72,
|
||||||
"panel.AnalyticsForums": 73,
|
"panel.AnalyticsTopics": 73,
|
||||||
"panel.Groups": 74,
|
"panel.AnalyticsForums": 74,
|
||||||
"panel.GroupsEdit": 75,
|
"panel.Groups": 75,
|
||||||
"panel.GroupsEditPerms": 76,
|
"panel.GroupsEdit": 76,
|
||||||
"panel.GroupsEditSubmit": 77,
|
"panel.GroupsEditPerms": 77,
|
||||||
"panel.GroupsEditPermsSubmit": 78,
|
"panel.GroupsEditSubmit": 78,
|
||||||
"panel.GroupsCreateSubmit": 79,
|
"panel.GroupsEditPermsSubmit": 79,
|
||||||
"panel.Backups": 80,
|
"panel.GroupsCreateSubmit": 80,
|
||||||
"panel.LogsRegs": 81,
|
"panel.Backups": 81,
|
||||||
"panel.LogsMod": 82,
|
"panel.LogsRegs": 82,
|
||||||
"panel.Debug": 83,
|
"panel.LogsMod": 83,
|
||||||
"panel.Dashboard": 84,
|
"panel.Debug": 84,
|
||||||
"routes.AccountEdit": 85,
|
"panel.Dashboard": 85,
|
||||||
"routes.AccountEditPassword": 86,
|
"routes.AccountEdit": 86,
|
||||||
"routes.AccountEditPasswordSubmit": 87,
|
"routes.AccountEditPassword": 87,
|
||||||
"routes.AccountEditAvatarSubmit": 88,
|
"routes.AccountEditPasswordSubmit": 88,
|
||||||
"routes.AccountEditUsernameSubmit": 89,
|
"routes.AccountEditAvatarSubmit": 89,
|
||||||
"routes.AccountEditMFA": 90,
|
"routes.AccountEditUsernameSubmit": 90,
|
||||||
"routes.AccountEditMFASetup": 91,
|
"routes.AccountEditMFA": 91,
|
||||||
"routes.AccountEditMFASetupSubmit": 92,
|
"routes.AccountEditMFASetup": 92,
|
||||||
"routes.AccountEditMFADisableSubmit": 93,
|
"routes.AccountEditMFASetupSubmit": 93,
|
||||||
"routes.AccountEditEmail": 94,
|
"routes.AccountEditMFADisableSubmit": 94,
|
||||||
"routes.AccountEditEmailTokenSubmit": 95,
|
"routes.AccountEditEmail": 95,
|
||||||
"routes.AccountLogins": 96,
|
"routes.AccountEditEmailTokenSubmit": 96,
|
||||||
"routes.LevelList": 97,
|
"routes.AccountLogins": 97,
|
||||||
"routes.ViewProfile": 98,
|
"routes.LevelList": 98,
|
||||||
"routes.BanUserSubmit": 99,
|
"routes.ViewProfile": 99,
|
||||||
"routes.UnbanUser": 100,
|
"routes.BanUserSubmit": 100,
|
||||||
"routes.ActivateUser": 101,
|
"routes.UnbanUser": 101,
|
||||||
"routes.IPSearch": 102,
|
"routes.ActivateUser": 102,
|
||||||
"routes.CreateTopicSubmit": 103,
|
"routes.IPSearch": 103,
|
||||||
"routes.EditTopicSubmit": 104,
|
"routes.CreateTopicSubmit": 104,
|
||||||
"routes.DeleteTopicSubmit": 105,
|
"routes.EditTopicSubmit": 105,
|
||||||
"routes.StickTopicSubmit": 106,
|
"routes.DeleteTopicSubmit": 106,
|
||||||
"routes.UnstickTopicSubmit": 107,
|
"routes.StickTopicSubmit": 107,
|
||||||
"routes.LockTopicSubmit": 108,
|
"routes.UnstickTopicSubmit": 108,
|
||||||
"routes.UnlockTopicSubmit": 109,
|
"routes.LockTopicSubmit": 109,
|
||||||
"routes.MoveTopicSubmit": 110,
|
"routes.UnlockTopicSubmit": 110,
|
||||||
"routes.LikeTopicSubmit": 111,
|
"routes.MoveTopicSubmit": 111,
|
||||||
"routes.AddAttachToTopicSubmit": 112,
|
"routes.LikeTopicSubmit": 112,
|
||||||
"routes.RemoveAttachFromTopicSubmit": 113,
|
"routes.AddAttachToTopicSubmit": 113,
|
||||||
"routes.ViewTopic": 114,
|
"routes.RemoveAttachFromTopicSubmit": 114,
|
||||||
"routes.CreateReplySubmit": 115,
|
"routes.ViewTopic": 115,
|
||||||
"routes.ReplyEditSubmit": 116,
|
"routes.CreateReplySubmit": 116,
|
||||||
"routes.ReplyDeleteSubmit": 117,
|
"routes.ReplyEditSubmit": 117,
|
||||||
"routes.ReplyLikeSubmit": 118,
|
"routes.ReplyDeleteSubmit": 118,
|
||||||
"routes.AddAttachToReplySubmit": 119,
|
"routes.ReplyLikeSubmit": 119,
|
||||||
"routes.RemoveAttachFromReplySubmit": 120,
|
"routes.AddAttachToReplySubmit": 120,
|
||||||
"routes.ProfileReplyCreateSubmit": 121,
|
"routes.RemoveAttachFromReplySubmit": 121,
|
||||||
"routes.ProfileReplyEditSubmit": 122,
|
"routes.ProfileReplyCreateSubmit": 122,
|
||||||
"routes.ProfileReplyDeleteSubmit": 123,
|
"routes.ProfileReplyEditSubmit": 123,
|
||||||
"routes.PollVote": 124,
|
"routes.ProfileReplyDeleteSubmit": 124,
|
||||||
"routes.PollResults": 125,
|
"routes.PollVote": 125,
|
||||||
"routes.AccountLogin": 126,
|
"routes.PollResults": 126,
|
||||||
"routes.AccountRegister": 127,
|
"routes.AccountLogin": 127,
|
||||||
"routes.AccountLogout": 128,
|
"routes.AccountRegister": 128,
|
||||||
"routes.AccountLoginSubmit": 129,
|
"routes.AccountLogout": 129,
|
||||||
"routes.AccountLoginMFAVerify": 130,
|
"routes.AccountLoginSubmit": 130,
|
||||||
"routes.AccountLoginMFAVerifySubmit": 131,
|
"routes.AccountLoginMFAVerify": 131,
|
||||||
"routes.AccountRegisterSubmit": 132,
|
"routes.AccountLoginMFAVerifySubmit": 132,
|
||||||
"routes.AccountPasswordReset": 133,
|
"routes.AccountRegisterSubmit": 133,
|
||||||
"routes.AccountPasswordResetSubmit": 134,
|
"routes.AccountPasswordReset": 134,
|
||||||
"routes.AccountPasswordResetToken": 135,
|
"routes.AccountPasswordResetSubmit": 135,
|
||||||
"routes.AccountPasswordResetTokenSubmit": 136,
|
"routes.AccountPasswordResetToken": 136,
|
||||||
"routes.DynamicRoute": 137,
|
"routes.AccountPasswordResetTokenSubmit": 137,
|
||||||
"routes.UploadedFile": 138,
|
"routes.DynamicRoute": 138,
|
||||||
"routes.StaticFile": 139,
|
"routes.UploadedFile": 139,
|
||||||
"routes.RobotsTxt": 140,
|
"routes.StaticFile": 140,
|
||||||
"routes.SitemapXml": 141,
|
"routes.RobotsTxt": 141,
|
||||||
"routes.OpenSearchXml": 142,
|
"routes.SitemapXml": 142,
|
||||||
"routes.BadRoute": 143,
|
"routes.OpenSearchXml": 143,
|
||||||
"routes.HTTPSRedirect": 144,
|
"routes.BadRoute": 144,
|
||||||
|
"routes.HTTPSRedirect": 145,
|
||||||
}
|
}
|
||||||
var reverseRouteMapEnum = map[int]string{
|
var reverseRouteMapEnum = map[int]string{
|
||||||
0: "routes.Overview",
|
0: "routes.Overview",
|
||||||
|
@ -391,79 +393,80 @@ var reverseRouteMapEnum = map[int]string{
|
||||||
69: "panel.AnalyticsReferrerViews",
|
69: "panel.AnalyticsReferrerViews",
|
||||||
70: "panel.AnalyticsPosts",
|
70: "panel.AnalyticsPosts",
|
||||||
71: "panel.AnalyticsMemory",
|
71: "panel.AnalyticsMemory",
|
||||||
72: "panel.AnalyticsTopics",
|
72: "panel.AnalyticsActiveMemory",
|
||||||
73: "panel.AnalyticsForums",
|
73: "panel.AnalyticsTopics",
|
||||||
74: "panel.Groups",
|
74: "panel.AnalyticsForums",
|
||||||
75: "panel.GroupsEdit",
|
75: "panel.Groups",
|
||||||
76: "panel.GroupsEditPerms",
|
76: "panel.GroupsEdit",
|
||||||
77: "panel.GroupsEditSubmit",
|
77: "panel.GroupsEditPerms",
|
||||||
78: "panel.GroupsEditPermsSubmit",
|
78: "panel.GroupsEditSubmit",
|
||||||
79: "panel.GroupsCreateSubmit",
|
79: "panel.GroupsEditPermsSubmit",
|
||||||
80: "panel.Backups",
|
80: "panel.GroupsCreateSubmit",
|
||||||
81: "panel.LogsRegs",
|
81: "panel.Backups",
|
||||||
82: "panel.LogsMod",
|
82: "panel.LogsRegs",
|
||||||
83: "panel.Debug",
|
83: "panel.LogsMod",
|
||||||
84: "panel.Dashboard",
|
84: "panel.Debug",
|
||||||
85: "routes.AccountEdit",
|
85: "panel.Dashboard",
|
||||||
86: "routes.AccountEditPassword",
|
86: "routes.AccountEdit",
|
||||||
87: "routes.AccountEditPasswordSubmit",
|
87: "routes.AccountEditPassword",
|
||||||
88: "routes.AccountEditAvatarSubmit",
|
88: "routes.AccountEditPasswordSubmit",
|
||||||
89: "routes.AccountEditUsernameSubmit",
|
89: "routes.AccountEditAvatarSubmit",
|
||||||
90: "routes.AccountEditMFA",
|
90: "routes.AccountEditUsernameSubmit",
|
||||||
91: "routes.AccountEditMFASetup",
|
91: "routes.AccountEditMFA",
|
||||||
92: "routes.AccountEditMFASetupSubmit",
|
92: "routes.AccountEditMFASetup",
|
||||||
93: "routes.AccountEditMFADisableSubmit",
|
93: "routes.AccountEditMFASetupSubmit",
|
||||||
94: "routes.AccountEditEmail",
|
94: "routes.AccountEditMFADisableSubmit",
|
||||||
95: "routes.AccountEditEmailTokenSubmit",
|
95: "routes.AccountEditEmail",
|
||||||
96: "routes.AccountLogins",
|
96: "routes.AccountEditEmailTokenSubmit",
|
||||||
97: "routes.LevelList",
|
97: "routes.AccountLogins",
|
||||||
98: "routes.ViewProfile",
|
98: "routes.LevelList",
|
||||||
99: "routes.BanUserSubmit",
|
99: "routes.ViewProfile",
|
||||||
100: "routes.UnbanUser",
|
100: "routes.BanUserSubmit",
|
||||||
101: "routes.ActivateUser",
|
101: "routes.UnbanUser",
|
||||||
102: "routes.IPSearch",
|
102: "routes.ActivateUser",
|
||||||
103: "routes.CreateTopicSubmit",
|
103: "routes.IPSearch",
|
||||||
104: "routes.EditTopicSubmit",
|
104: "routes.CreateTopicSubmit",
|
||||||
105: "routes.DeleteTopicSubmit",
|
105: "routes.EditTopicSubmit",
|
||||||
106: "routes.StickTopicSubmit",
|
106: "routes.DeleteTopicSubmit",
|
||||||
107: "routes.UnstickTopicSubmit",
|
107: "routes.StickTopicSubmit",
|
||||||
108: "routes.LockTopicSubmit",
|
108: "routes.UnstickTopicSubmit",
|
||||||
109: "routes.UnlockTopicSubmit",
|
109: "routes.LockTopicSubmit",
|
||||||
110: "routes.MoveTopicSubmit",
|
110: "routes.UnlockTopicSubmit",
|
||||||
111: "routes.LikeTopicSubmit",
|
111: "routes.MoveTopicSubmit",
|
||||||
112: "routes.AddAttachToTopicSubmit",
|
112: "routes.LikeTopicSubmit",
|
||||||
113: "routes.RemoveAttachFromTopicSubmit",
|
113: "routes.AddAttachToTopicSubmit",
|
||||||
114: "routes.ViewTopic",
|
114: "routes.RemoveAttachFromTopicSubmit",
|
||||||
115: "routes.CreateReplySubmit",
|
115: "routes.ViewTopic",
|
||||||
116: "routes.ReplyEditSubmit",
|
116: "routes.CreateReplySubmit",
|
||||||
117: "routes.ReplyDeleteSubmit",
|
117: "routes.ReplyEditSubmit",
|
||||||
118: "routes.ReplyLikeSubmit",
|
118: "routes.ReplyDeleteSubmit",
|
||||||
119: "routes.AddAttachToReplySubmit",
|
119: "routes.ReplyLikeSubmit",
|
||||||
120: "routes.RemoveAttachFromReplySubmit",
|
120: "routes.AddAttachToReplySubmit",
|
||||||
121: "routes.ProfileReplyCreateSubmit",
|
121: "routes.RemoveAttachFromReplySubmit",
|
||||||
122: "routes.ProfileReplyEditSubmit",
|
122: "routes.ProfileReplyCreateSubmit",
|
||||||
123: "routes.ProfileReplyDeleteSubmit",
|
123: "routes.ProfileReplyEditSubmit",
|
||||||
124: "routes.PollVote",
|
124: "routes.ProfileReplyDeleteSubmit",
|
||||||
125: "routes.PollResults",
|
125: "routes.PollVote",
|
||||||
126: "routes.AccountLogin",
|
126: "routes.PollResults",
|
||||||
127: "routes.AccountRegister",
|
127: "routes.AccountLogin",
|
||||||
128: "routes.AccountLogout",
|
128: "routes.AccountRegister",
|
||||||
129: "routes.AccountLoginSubmit",
|
129: "routes.AccountLogout",
|
||||||
130: "routes.AccountLoginMFAVerify",
|
130: "routes.AccountLoginSubmit",
|
||||||
131: "routes.AccountLoginMFAVerifySubmit",
|
131: "routes.AccountLoginMFAVerify",
|
||||||
132: "routes.AccountRegisterSubmit",
|
132: "routes.AccountLoginMFAVerifySubmit",
|
||||||
133: "routes.AccountPasswordReset",
|
133: "routes.AccountRegisterSubmit",
|
||||||
134: "routes.AccountPasswordResetSubmit",
|
134: "routes.AccountPasswordReset",
|
||||||
135: "routes.AccountPasswordResetToken",
|
135: "routes.AccountPasswordResetSubmit",
|
||||||
136: "routes.AccountPasswordResetTokenSubmit",
|
136: "routes.AccountPasswordResetToken",
|
||||||
137: "routes.DynamicRoute",
|
137: "routes.AccountPasswordResetTokenSubmit",
|
||||||
138: "routes.UploadedFile",
|
138: "routes.DynamicRoute",
|
||||||
139: "routes.StaticFile",
|
139: "routes.UploadedFile",
|
||||||
140: "routes.RobotsTxt",
|
140: "routes.StaticFile",
|
||||||
141: "routes.SitemapXml",
|
141: "routes.RobotsTxt",
|
||||||
142: "routes.OpenSearchXml",
|
142: "routes.SitemapXml",
|
||||||
143: "routes.BadRoute",
|
143: "routes.OpenSearchXml",
|
||||||
144: "routes.HTTPSRedirect",
|
144: "routes.BadRoute",
|
||||||
|
145: "routes.HTTPSRedirect",
|
||||||
}
|
}
|
||||||
var osMapEnum = map[string]int{
|
var osMapEnum = map[string]int{
|
||||||
"unknown": 0,
|
"unknown": 0,
|
||||||
|
@ -618,7 +621,7 @@ type HTTPSRedirect struct {
|
||||||
|
|
||||||
func (red *HTTPSRedirect) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (red *HTTPSRedirect) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
w.Header().Set("Connection", "close")
|
w.Header().Set("Connection", "close")
|
||||||
counters.RouteViewCounter.Bump(144)
|
counters.RouteViewCounter.Bump(145)
|
||||||
dest := "https://" + req.Host + req.URL.String()
|
dest := "https://" + req.Host + req.URL.String()
|
||||||
http.Redirect(w, req, dest, http.StatusTemporaryRedirect)
|
http.Redirect(w, req, dest, http.StatusTemporaryRedirect)
|
||||||
}
|
}
|
||||||
|
@ -822,7 +825,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
counters.GlobalViewCounter.Bump()
|
counters.GlobalViewCounter.Bump()
|
||||||
|
|
||||||
if prefix == "/static" {
|
if prefix == "/static" {
|
||||||
counters.RouteViewCounter.Bump(139)
|
counters.RouteViewCounter.Bump(140)
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
routes.StaticFile(w, req)
|
routes.StaticFile(w, req)
|
||||||
return
|
return
|
||||||
|
@ -1518,13 +1521,21 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(71)
|
counters.RouteViewCounter.Bump(71)
|
||||||
err = panel.AnalyticsMemory(w,req,user)
|
err = panel.AnalyticsMemory(w,req,user)
|
||||||
case "/panel/analytics/topics/":
|
case "/panel/analytics/active-memory/":
|
||||||
err = c.ParseForm(w,req,user)
|
err = c.ParseForm(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(72)
|
counters.RouteViewCounter.Bump(72)
|
||||||
|
err = panel.AnalyticsActiveMemory(w,req,user)
|
||||||
|
case "/panel/analytics/topics/":
|
||||||
|
err = c.ParseForm(w,req,user)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
counters.RouteViewCounter.Bump(73)
|
||||||
err = panel.AnalyticsTopics(w,req,user)
|
err = panel.AnalyticsTopics(w,req,user)
|
||||||
case "/panel/analytics/forums/":
|
case "/panel/analytics/forums/":
|
||||||
err = c.ParseForm(w,req,user)
|
err = c.ParseForm(w,req,user)
|
||||||
|
@ -1532,16 +1543,16 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(73)
|
counters.RouteViewCounter.Bump(74)
|
||||||
err = panel.AnalyticsForums(w,req,user)
|
err = panel.AnalyticsForums(w,req,user)
|
||||||
case "/panel/groups/":
|
case "/panel/groups/":
|
||||||
counters.RouteViewCounter.Bump(74)
|
counters.RouteViewCounter.Bump(75)
|
||||||
err = panel.Groups(w,req,user)
|
err = panel.Groups(w,req,user)
|
||||||
case "/panel/groups/edit/":
|
case "/panel/groups/edit/":
|
||||||
counters.RouteViewCounter.Bump(75)
|
counters.RouteViewCounter.Bump(76)
|
||||||
err = panel.GroupsEdit(w,req,user,extraData)
|
err = panel.GroupsEdit(w,req,user,extraData)
|
||||||
case "/panel/groups/edit/perms/":
|
case "/panel/groups/edit/perms/":
|
||||||
counters.RouteViewCounter.Bump(76)
|
counters.RouteViewCounter.Bump(77)
|
||||||
err = panel.GroupsEditPerms(w,req,user,extraData)
|
err = panel.GroupsEditPerms(w,req,user,extraData)
|
||||||
case "/panel/groups/edit/submit/":
|
case "/panel/groups/edit/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1549,7 +1560,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(77)
|
counters.RouteViewCounter.Bump(78)
|
||||||
err = panel.GroupsEditSubmit(w,req,user,extraData)
|
err = panel.GroupsEditSubmit(w,req,user,extraData)
|
||||||
case "/panel/groups/edit/perms/submit/":
|
case "/panel/groups/edit/perms/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1557,7 +1568,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(78)
|
counters.RouteViewCounter.Bump(79)
|
||||||
err = panel.GroupsEditPermsSubmit(w,req,user,extraData)
|
err = panel.GroupsEditPermsSubmit(w,req,user,extraData)
|
||||||
case "/panel/groups/create/":
|
case "/panel/groups/create/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1565,7 +1576,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(79)
|
counters.RouteViewCounter.Bump(80)
|
||||||
err = panel.GroupsCreateSubmit(w,req,user)
|
err = panel.GroupsCreateSubmit(w,req,user)
|
||||||
case "/panel/backups/":
|
case "/panel/backups/":
|
||||||
err = c.SuperAdminOnly(w,req,user)
|
err = c.SuperAdminOnly(w,req,user)
|
||||||
|
@ -1579,13 +1590,13 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
w.Header().Del("Content-Type")
|
w.Header().Del("Content-Type")
|
||||||
w.Header().Del("Content-Encoding")
|
w.Header().Del("Content-Encoding")
|
||||||
}
|
}
|
||||||
counters.RouteViewCounter.Bump(80)
|
counters.RouteViewCounter.Bump(81)
|
||||||
err = panel.Backups(w,req,user,extraData)
|
err = panel.Backups(w,req,user,extraData)
|
||||||
case "/panel/logs/regs/":
|
case "/panel/logs/regs/":
|
||||||
counters.RouteViewCounter.Bump(81)
|
counters.RouteViewCounter.Bump(82)
|
||||||
err = panel.LogsRegs(w,req,user)
|
err = panel.LogsRegs(w,req,user)
|
||||||
case "/panel/logs/mod/":
|
case "/panel/logs/mod/":
|
||||||
counters.RouteViewCounter.Bump(82)
|
counters.RouteViewCounter.Bump(83)
|
||||||
err = panel.LogsMod(w,req,user)
|
err = panel.LogsMod(w,req,user)
|
||||||
case "/panel/debug/":
|
case "/panel/debug/":
|
||||||
err = c.AdminOnly(w,req,user)
|
err = c.AdminOnly(w,req,user)
|
||||||
|
@ -1593,10 +1604,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(83)
|
counters.RouteViewCounter.Bump(84)
|
||||||
err = panel.Debug(w,req,user)
|
err = panel.Debug(w,req,user)
|
||||||
default:
|
default:
|
||||||
counters.RouteViewCounter.Bump(84)
|
counters.RouteViewCounter.Bump(85)
|
||||||
err = panel.Dashboard(w,req,user)
|
err = panel.Dashboard(w,req,user)
|
||||||
}
|
}
|
||||||
case "/user":
|
case "/user":
|
||||||
|
@ -1607,7 +1618,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(85)
|
counters.RouteViewCounter.Bump(86)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1619,7 +1630,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(86)
|
counters.RouteViewCounter.Bump(87)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1636,7 +1647,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(87)
|
counters.RouteViewCounter.Bump(88)
|
||||||
err = routes.AccountEditPasswordSubmit(w,req,user)
|
err = routes.AccountEditPasswordSubmit(w,req,user)
|
||||||
case "/user/edit/avatar/submit/":
|
case "/user/edit/avatar/submit/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -1653,7 +1664,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(88)
|
counters.RouteViewCounter.Bump(89)
|
||||||
err = routes.AccountEditAvatarSubmit(w,req,user)
|
err = routes.AccountEditAvatarSubmit(w,req,user)
|
||||||
case "/user/edit/username/submit/":
|
case "/user/edit/username/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1666,7 +1677,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(89)
|
counters.RouteViewCounter.Bump(90)
|
||||||
err = routes.AccountEditUsernameSubmit(w,req,user)
|
err = routes.AccountEditUsernameSubmit(w,req,user)
|
||||||
case "/user/edit/mfa/":
|
case "/user/edit/mfa/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -1674,7 +1685,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(90)
|
counters.RouteViewCounter.Bump(91)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1686,7 +1697,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(91)
|
counters.RouteViewCounter.Bump(92)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1703,7 +1714,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(92)
|
counters.RouteViewCounter.Bump(93)
|
||||||
err = routes.AccountEditMFASetupSubmit(w,req,user)
|
err = routes.AccountEditMFASetupSubmit(w,req,user)
|
||||||
case "/user/edit/mfa/disable/submit/":
|
case "/user/edit/mfa/disable/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1716,7 +1727,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(93)
|
counters.RouteViewCounter.Bump(94)
|
||||||
err = routes.AccountEditMFADisableSubmit(w,req,user)
|
err = routes.AccountEditMFADisableSubmit(w,req,user)
|
||||||
case "/user/edit/email/":
|
case "/user/edit/email/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -1724,14 +1735,14 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(94)
|
counters.RouteViewCounter.Bump(95)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = routes.AccountEditEmail(w,req,user,head)
|
err = routes.AccountEditEmail(w,req,user,head)
|
||||||
case "/user/edit/token/":
|
case "/user/edit/token/":
|
||||||
counters.RouteViewCounter.Bump(95)
|
counters.RouteViewCounter.Bump(96)
|
||||||
err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData)
|
err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData)
|
||||||
case "/user/edit/logins/":
|
case "/user/edit/logins/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -1739,7 +1750,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(96)
|
counters.RouteViewCounter.Bump(97)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1751,7 +1762,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(97)
|
counters.RouteViewCounter.Bump(98)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1759,7 +1770,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
err = routes.LevelList(w,req,user,head)
|
err = routes.LevelList(w,req,user,head)
|
||||||
default:
|
default:
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
counters.RouteViewCounter.Bump(98)
|
counters.RouteViewCounter.Bump(99)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1779,7 +1790,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(99)
|
counters.RouteViewCounter.Bump(100)
|
||||||
err = routes.BanUserSubmit(w,req,user,extraData)
|
err = routes.BanUserSubmit(w,req,user,extraData)
|
||||||
case "/users/unban/":
|
case "/users/unban/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1792,7 +1803,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(100)
|
counters.RouteViewCounter.Bump(101)
|
||||||
err = routes.UnbanUser(w,req,user,extraData)
|
err = routes.UnbanUser(w,req,user,extraData)
|
||||||
case "/users/activate/":
|
case "/users/activate/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1805,7 +1816,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(101)
|
counters.RouteViewCounter.Bump(102)
|
||||||
err = routes.ActivateUser(w,req,user,extraData)
|
err = routes.ActivateUser(w,req,user,extraData)
|
||||||
case "/users/ips/":
|
case "/users/ips/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -1813,7 +1824,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(102)
|
counters.RouteViewCounter.Bump(103)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1837,7 +1848,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(103)
|
counters.RouteViewCounter.Bump(104)
|
||||||
err = routes.CreateTopicSubmit(w,req,user)
|
err = routes.CreateTopicSubmit(w,req,user)
|
||||||
case "/topic/edit/submit/":
|
case "/topic/edit/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1850,7 +1861,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(104)
|
counters.RouteViewCounter.Bump(105)
|
||||||
err = routes.EditTopicSubmit(w,req,user,extraData)
|
err = routes.EditTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/delete/submit/":
|
case "/topic/delete/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1864,7 +1875,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
}
|
}
|
||||||
|
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
counters.RouteViewCounter.Bump(105)
|
counters.RouteViewCounter.Bump(106)
|
||||||
err = routes.DeleteTopicSubmit(w,req,user)
|
err = routes.DeleteTopicSubmit(w,req,user)
|
||||||
case "/topic/stick/submit/":
|
case "/topic/stick/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1877,7 +1888,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(106)
|
counters.RouteViewCounter.Bump(107)
|
||||||
err = routes.StickTopicSubmit(w,req,user,extraData)
|
err = routes.StickTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/unstick/submit/":
|
case "/topic/unstick/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1890,7 +1901,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(107)
|
counters.RouteViewCounter.Bump(108)
|
||||||
err = routes.UnstickTopicSubmit(w,req,user,extraData)
|
err = routes.UnstickTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/lock/submit/":
|
case "/topic/lock/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1904,7 +1915,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
}
|
}
|
||||||
|
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
counters.RouteViewCounter.Bump(108)
|
counters.RouteViewCounter.Bump(109)
|
||||||
err = routes.LockTopicSubmit(w,req,user)
|
err = routes.LockTopicSubmit(w,req,user)
|
||||||
case "/topic/unlock/submit/":
|
case "/topic/unlock/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1917,7 +1928,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(109)
|
counters.RouteViewCounter.Bump(110)
|
||||||
err = routes.UnlockTopicSubmit(w,req,user,extraData)
|
err = routes.UnlockTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/move/submit/":
|
case "/topic/move/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1930,7 +1941,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(110)
|
counters.RouteViewCounter.Bump(111)
|
||||||
err = routes.MoveTopicSubmit(w,req,user,extraData)
|
err = routes.MoveTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/like/submit/":
|
case "/topic/like/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1943,7 +1954,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(111)
|
counters.RouteViewCounter.Bump(112)
|
||||||
err = routes.LikeTopicSubmit(w,req,user,extraData)
|
err = routes.LikeTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/attach/add/submit/":
|
case "/topic/attach/add/submit/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -1960,7 +1971,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(112)
|
counters.RouteViewCounter.Bump(113)
|
||||||
err = routes.AddAttachToTopicSubmit(w,req,user,extraData)
|
err = routes.AddAttachToTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/attach/remove/submit/":
|
case "/topic/attach/remove/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1973,10 +1984,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(113)
|
counters.RouteViewCounter.Bump(114)
|
||||||
err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData)
|
err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData)
|
||||||
default:
|
default:
|
||||||
counters.RouteViewCounter.Bump(114)
|
counters.RouteViewCounter.Bump(115)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2000,7 +2011,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(115)
|
counters.RouteViewCounter.Bump(116)
|
||||||
err = routes.CreateReplySubmit(w,req,user)
|
err = routes.CreateReplySubmit(w,req,user)
|
||||||
case "/reply/edit/submit/":
|
case "/reply/edit/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2013,7 +2024,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(116)
|
counters.RouteViewCounter.Bump(117)
|
||||||
err = routes.ReplyEditSubmit(w,req,user,extraData)
|
err = routes.ReplyEditSubmit(w,req,user,extraData)
|
||||||
case "/reply/delete/submit/":
|
case "/reply/delete/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2026,7 +2037,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(117)
|
counters.RouteViewCounter.Bump(118)
|
||||||
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
|
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
|
||||||
case "/reply/like/submit/":
|
case "/reply/like/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2039,7 +2050,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(118)
|
counters.RouteViewCounter.Bump(119)
|
||||||
err = routes.ReplyLikeSubmit(w,req,user,extraData)
|
err = routes.ReplyLikeSubmit(w,req,user,extraData)
|
||||||
case "/reply/attach/add/submit/":
|
case "/reply/attach/add/submit/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -2056,7 +2067,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(119)
|
counters.RouteViewCounter.Bump(120)
|
||||||
err = routes.AddAttachToReplySubmit(w,req,user,extraData)
|
err = routes.AddAttachToReplySubmit(w,req,user,extraData)
|
||||||
case "/reply/attach/remove/submit/":
|
case "/reply/attach/remove/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2069,7 +2080,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(120)
|
counters.RouteViewCounter.Bump(121)
|
||||||
err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData)
|
err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
case "/profile":
|
case "/profile":
|
||||||
|
@ -2085,7 +2096,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(121)
|
counters.RouteViewCounter.Bump(122)
|
||||||
err = routes.ProfileReplyCreateSubmit(w,req,user)
|
err = routes.ProfileReplyCreateSubmit(w,req,user)
|
||||||
case "/profile/reply/edit/submit/":
|
case "/profile/reply/edit/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2098,7 +2109,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(122)
|
counters.RouteViewCounter.Bump(123)
|
||||||
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
|
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
|
||||||
case "/profile/reply/delete/submit/":
|
case "/profile/reply/delete/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2111,7 +2122,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(123)
|
counters.RouteViewCounter.Bump(124)
|
||||||
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
|
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
case "/poll":
|
case "/poll":
|
||||||
|
@ -2127,23 +2138,23 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(124)
|
counters.RouteViewCounter.Bump(125)
|
||||||
err = routes.PollVote(w,req,user,extraData)
|
err = routes.PollVote(w,req,user,extraData)
|
||||||
case "/poll/results/":
|
case "/poll/results/":
|
||||||
counters.RouteViewCounter.Bump(125)
|
counters.RouteViewCounter.Bump(126)
|
||||||
err = routes.PollResults(w,req,user,extraData)
|
err = routes.PollResults(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
case "/accounts":
|
case "/accounts":
|
||||||
switch(req.URL.Path) {
|
switch(req.URL.Path) {
|
||||||
case "/accounts/login/":
|
case "/accounts/login/":
|
||||||
counters.RouteViewCounter.Bump(126)
|
counters.RouteViewCounter.Bump(127)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = routes.AccountLogin(w,req,user,head)
|
err = routes.AccountLogin(w,req,user,head)
|
||||||
case "/accounts/create/":
|
case "/accounts/create/":
|
||||||
counters.RouteViewCounter.Bump(127)
|
counters.RouteViewCounter.Bump(128)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2160,7 +2171,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(128)
|
counters.RouteViewCounter.Bump(129)
|
||||||
err = routes.AccountLogout(w,req,user)
|
err = routes.AccountLogout(w,req,user)
|
||||||
case "/accounts/login/submit/":
|
case "/accounts/login/submit/":
|
||||||
err = c.ParseForm(w,req,user)
|
err = c.ParseForm(w,req,user)
|
||||||
|
@ -2168,10 +2179,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(129)
|
counters.RouteViewCounter.Bump(130)
|
||||||
err = routes.AccountLoginSubmit(w,req,user)
|
err = routes.AccountLoginSubmit(w,req,user)
|
||||||
case "/accounts/mfa_verify/":
|
case "/accounts/mfa_verify/":
|
||||||
counters.RouteViewCounter.Bump(130)
|
counters.RouteViewCounter.Bump(131)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2183,7 +2194,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(131)
|
counters.RouteViewCounter.Bump(132)
|
||||||
err = routes.AccountLoginMFAVerifySubmit(w,req,user)
|
err = routes.AccountLoginMFAVerifySubmit(w,req,user)
|
||||||
case "/accounts/create/submit/":
|
case "/accounts/create/submit/":
|
||||||
err = c.ParseForm(w,req,user)
|
err = c.ParseForm(w,req,user)
|
||||||
|
@ -2191,10 +2202,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(132)
|
counters.RouteViewCounter.Bump(133)
|
||||||
err = routes.AccountRegisterSubmit(w,req,user)
|
err = routes.AccountRegisterSubmit(w,req,user)
|
||||||
case "/accounts/password-reset/":
|
case "/accounts/password-reset/":
|
||||||
counters.RouteViewCounter.Bump(133)
|
counters.RouteViewCounter.Bump(134)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2206,10 +2217,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(134)
|
counters.RouteViewCounter.Bump(135)
|
||||||
err = routes.AccountPasswordResetSubmit(w,req,user)
|
err = routes.AccountPasswordResetSubmit(w,req,user)
|
||||||
case "/accounts/password-reset/token/":
|
case "/accounts/password-reset/token/":
|
||||||
counters.RouteViewCounter.Bump(135)
|
counters.RouteViewCounter.Bump(136)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2221,7 +2232,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(136)
|
counters.RouteViewCounter.Bump(137)
|
||||||
err = routes.AccountPasswordResetTokenSubmit(w,req,user)
|
err = routes.AccountPasswordResetTokenSubmit(w,req,user)
|
||||||
}
|
}
|
||||||
/*case "/sitemaps": // TODO: Count these views
|
/*case "/sitemaps": // TODO: Count these views
|
||||||
|
@ -2237,7 +2248,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
w.Header().Del("Content-Type")
|
w.Header().Del("Content-Type")
|
||||||
w.Header().Del("Content-Encoding")
|
w.Header().Del("Content-Encoding")
|
||||||
}
|
}
|
||||||
counters.RouteViewCounter.Bump(138)
|
counters.RouteViewCounter.Bump(139)
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
// TODO: Find a way to propagate errors up from this?
|
// TODO: Find a way to propagate errors up from this?
|
||||||
r.UploadHandler(w,req) // TODO: Count these views
|
r.UploadHandler(w,req) // TODO: Count these views
|
||||||
|
@ -2247,7 +2258,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
// TODO: Add support for favicons and robots.txt files
|
// TODO: Add support for favicons and robots.txt files
|
||||||
switch(extraData) {
|
switch(extraData) {
|
||||||
case "robots.txt":
|
case "robots.txt":
|
||||||
counters.RouteViewCounter.Bump(140)
|
counters.RouteViewCounter.Bump(141)
|
||||||
return routes.RobotsTxt(w,req)
|
return routes.RobotsTxt(w,req)
|
||||||
case "favicon.ico":
|
case "favicon.ico":
|
||||||
req.URL.Path = "/static"+req.URL.Path+extraData
|
req.URL.Path = "/static"+req.URL.Path+extraData
|
||||||
|
@ -2255,10 +2266,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
routes.StaticFile(w,req)
|
routes.StaticFile(w,req)
|
||||||
return nil
|
return nil
|
||||||
case "opensearch.xml":
|
case "opensearch.xml":
|
||||||
counters.RouteViewCounter.Bump(142)
|
counters.RouteViewCounter.Bump(143)
|
||||||
return routes.OpenSearchXml(w,req)
|
return routes.OpenSearchXml(w,req)
|
||||||
/*case "sitemap.xml":
|
/*case "sitemap.xml":
|
||||||
counters.RouteViewCounter.Bump(141)
|
counters.RouteViewCounter.Bump(142)
|
||||||
return routes.SitemapXml(w,req)*/
|
return routes.SitemapXml(w,req)*/
|
||||||
}
|
}
|
||||||
return c.NotFound(w,req,nil)
|
return c.NotFound(w,req,nil)
|
||||||
|
@ -2269,7 +2280,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
r.RUnlock()
|
r.RUnlock()
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
counters.RouteViewCounter.Bump(137) // TODO: Be more specific about *which* dynamic route it is
|
counters.RouteViewCounter.Bump(138) // TODO: Be more specific about *which* dynamic route it is
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
return handle(w,req,user)
|
return handle(w,req,user)
|
||||||
}
|
}
|
||||||
|
@ -2280,7 +2291,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
} else {
|
} else {
|
||||||
r.DumpRequest(req,"Bad Route")
|
r.DumpRequest(req,"Bad Route")
|
||||||
}
|
}
|
||||||
counters.RouteViewCounter.Bump(143)
|
counters.RouteViewCounter.Bump(144)
|
||||||
return c.NotFound(w,req,nil)
|
return c.NotFound(w,req,nil)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -741,6 +741,7 @@
|
||||||
"panel_menu_statistics_languages":"Languages",
|
"panel_menu_statistics_languages":"Languages",
|
||||||
"panel_menu_statistics_referrers":"Referrers",
|
"panel_menu_statistics_referrers":"Referrers",
|
||||||
"panel_menu_statistics_memory":"Memory",
|
"panel_menu_statistics_memory":"Memory",
|
||||||
|
"panel_menu_statistics_active_memory":"Active Memory",
|
||||||
"panel_menu_reports":"Reports",
|
"panel_menu_reports":"Reports",
|
||||||
"panel_menu_logs":"Logs",
|
"panel_menu_logs":"Logs",
|
||||||
"panel_menu_logs_registrations":"Registrations",
|
"panel_menu_logs_registrations":"Registrations",
|
||||||
|
@ -884,6 +885,7 @@
|
||||||
"panel_statistics_topic_counts_head":"Topic Counts",
|
"panel_statistics_topic_counts_head":"Topic Counts",
|
||||||
"panel_statistics_requests_head":"Requests",
|
"panel_statistics_requests_head":"Requests",
|
||||||
"panel_statistics_memory_head":"Memory Usage",
|
"panel_statistics_memory_head":"Memory Usage",
|
||||||
|
"panel_statistics_active_memory_head":"Active Memory",
|
||||||
|
|
||||||
"panel_statistics_time_range_one_year":"1 year",
|
"panel_statistics_time_range_one_year":"1 year",
|
||||||
"panel_statistics_time_range_three_months":"3 months",
|
"panel_statistics_time_range_three_months":"3 months",
|
||||||
|
|
4
main.go
4
main.go
|
@ -222,6 +222,10 @@ func afterDBInit() (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.WithStack(err)
|
return errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
c.Meta, err = c.NewDefaultMetaStore(acc)
|
||||||
|
if err != nil {
|
||||||
|
return errors.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ func init() {
|
||||||
addPatch(18, patch18)
|
addPatch(18, patch18)
|
||||||
addPatch(19, patch19)
|
addPatch(19, patch19)
|
||||||
addPatch(20, patch20)
|
addPatch(20, patch20)
|
||||||
|
addPatch(21, patch21)
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch0(scanner *bufio.Scanner) (err error) {
|
func patch0(scanner *bufio.Scanner) (err error) {
|
||||||
|
@ -627,3 +628,27 @@ func patch20(scanner *bufio.Scanner) error {
|
||||||
|
|
||||||
return execStmt(qgen.Builder.AddForeignKey("activity_stream_matches", "asid","activity_stream","asid",true))
|
return execStmt(qgen.Builder.AddForeignKey("activity_stream_matches", "asid","activity_stream","asid",true))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func patch21(scanner *bufio.Scanner) error {
|
||||||
|
err := execStmt(qgen.Builder.AddColumn("memchunks", tblColumn{"stack", "int", 0, false, false, "0"}, nil))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = execStmt(qgen.Builder.AddColumn("memchunks", tblColumn{"heap", "int", 0, false, false, "0"}, nil))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = execStmt(qgen.Builder.CreateTable("meta", "", "",
|
||||||
|
[]tblColumn{
|
||||||
|
tblColumn{"name", "varchar", 200, false, false, ""},
|
||||||
|
tblColumn{"value", "varchar", 200, false, false, ""},
|
||||||
|
}, nil,
|
||||||
|
))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return execStmt(qgen.Builder.AddColumn("activity_stream", tblColumn{"createdAt", "createdAt", 0, false, false, ""}, nil))
|
||||||
|
}
|
|
@ -215,8 +215,8 @@ function runWebSockets(resume = false) {
|
||||||
// TODO: Sync alerts, topic list, etc.
|
// TODO: Sync alerts, topic list, etc.
|
||||||
conn.onopen = () => {
|
conn.onopen = () => {
|
||||||
console.log("The WebSockets connection was opened");
|
console.log("The WebSockets connection was opened");
|
||||||
conn.send("page " + document.location.pathname + '\r');
|
if(resume) conn.send("resume " + document.location.pathname + " " + Math.round((new Date()).getTime() / 1000) + '\r');
|
||||||
if(resume) conn.send("resume " + Math.round((new Date()).getTime() / 1000) + '\r');
|
else conn.send("page " + document.location.pathname + '\r');
|
||||||
// TODO: Don't ask again, if it's denied. We could have a setting in the UCP which automatically requests this when someone flips desktop notifications on
|
// TODO: Don't ask again, if it's denied. We could have a setting in the UCP which automatically requests this when someone flips desktop notifications on
|
||||||
if(me.User.ID > 0) Notification.requestPermission();
|
if(me.User.ID > 0) Notification.requestPermission();
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,6 +213,7 @@ func panelRoutes() *RouteGroup {
|
||||||
View("panel.AnalyticsReferrerViews", "/panel/analytics/referrer/", "extraData"),
|
View("panel.AnalyticsReferrerViews", "/panel/analytics/referrer/", "extraData"),
|
||||||
View("panel.AnalyticsPosts", "/panel/analytics/posts/").Before("ParseForm"),
|
View("panel.AnalyticsPosts", "/panel/analytics/posts/").Before("ParseForm"),
|
||||||
View("panel.AnalyticsMemory", "/panel/analytics/memory/").Before("ParseForm"),
|
View("panel.AnalyticsMemory", "/panel/analytics/memory/").Before("ParseForm"),
|
||||||
|
View("panel.AnalyticsActiveMemory", "/panel/analytics/active-memory/").Before("ParseForm"),
|
||||||
View("panel.AnalyticsTopics", "/panel/analytics/topics/").Before("ParseForm"),
|
View("panel.AnalyticsTopics", "/panel/analytics/topics/").Before("ParseForm"),
|
||||||
View("panel.AnalyticsForums", "/panel/analytics/forums/").Before("ParseForm"),
|
View("panel.AnalyticsForums", "/panel/analytics/forums/").Before("ParseForm"),
|
||||||
|
|
||||||
|
|
|
@ -157,6 +157,40 @@ func analyticsRowsToAverageMap(rows *sql.Rows, labelList []int64, avgMap map[int
|
||||||
return avgMap, rows.Err()
|
return avgMap, rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func analyticsRowsToAverageMap2(rows *sql.Rows, labelList []int64, avgMap map[int64]int64) (map[int64]int64, error) {
|
||||||
|
defer rows.Close()
|
||||||
|
for rows.Next() {
|
||||||
|
var stack, heap int64
|
||||||
|
var createdAt time.Time
|
||||||
|
err := rows.Scan(&stack, &heap, &createdAt)
|
||||||
|
if err != nil {
|
||||||
|
return avgMap, err
|
||||||
|
}
|
||||||
|
var unixCreatedAt = createdAt.Unix()
|
||||||
|
// TODO: Bulk log this
|
||||||
|
if c.Dev.SuperDebug {
|
||||||
|
log.Print("stack: ", stack)
|
||||||
|
log.Print("heap: ", heap)
|
||||||
|
log.Print("createdAt: ", createdAt)
|
||||||
|
log.Print("unixCreatedAt: ", unixCreatedAt)
|
||||||
|
}
|
||||||
|
var pAvgMap = make(map[int64]pAvg)
|
||||||
|
for _, value := range labelList {
|
||||||
|
if unixCreatedAt > value {
|
||||||
|
prev := pAvgMap[value]
|
||||||
|
prev.Avg += stack + heap
|
||||||
|
prev.Tot++
|
||||||
|
pAvgMap[value] = prev
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for key, pAvg := range pAvgMap {
|
||||||
|
avgMap[key] = pAvg.Avg / pAvg.Tot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return avgMap, rows.Err()
|
||||||
|
}
|
||||||
|
|
||||||
func PreAnalyticsDetail(w http.ResponseWriter, r *http.Request, user *c.User) (*c.BasePanelPage, c.RouteError) {
|
func PreAnalyticsDetail(w http.ResponseWriter, r *http.Request, user *c.User) (*c.BasePanelPage, c.RouteError) {
|
||||||
basePage, ferr := buildBasePage(w, r, user, "analytics", "analytics")
|
basePage, ferr := buildBasePage(w, r, user, "analytics", "analytics")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
|
@ -537,6 +571,42 @@ func AnalyticsMemory(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
|
||||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right","analytics","panel_analytics_memory", pi})
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right","analytics","panel_analytics_memory", pi})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Show stack and heap memory separately on the chart
|
||||||
|
func AnalyticsActiveMemory(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
|
if ferr != nil {
|
||||||
|
return ferr
|
||||||
|
}
|
||||||
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
|
if err != nil {
|
||||||
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
|
}
|
||||||
|
revLabelList, labelList, avgMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
|
c.DebugLog("in panel.AnalyticsActiveMemory")
|
||||||
|
rows, err := qgen.NewAcc().Select("memchunks").Columns("stack, heap, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
||||||
|
if err != nil && err != sql.ErrNoRows {
|
||||||
|
return c.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
avgMap, err = analyticsRowsToAverageMap2(rows, labelList, avgMap)
|
||||||
|
if err != nil {
|
||||||
|
return c.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Adjust for the missing chunks in week and month
|
||||||
|
var avgList []int64
|
||||||
|
var avgItems []c.PanelAnalyticsItemUnit
|
||||||
|
for _, value := range revLabelList {
|
||||||
|
avgList = append(avgList, avgMap[value])
|
||||||
|
cv, cu := c.ConvertByteUnit(float64(avgMap[value]))
|
||||||
|
avgItems = append(avgItems, c.PanelAnalyticsItemUnit{Time: value, Unit: cu, Count: int64(cv)})
|
||||||
|
}
|
||||||
|
graph := c.PanelTimeGraph{Series: [][]int64{avgList}, Labels: labelList}
|
||||||
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
|
pi := c.PanelAnalyticsStdUnit{graph, avgItems, timeRange.Range, timeRange.Unit, "time"}
|
||||||
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right","analytics","panel_analytics_active_memory", pi})
|
||||||
|
}
|
||||||
|
|
||||||
func analyticsRowsToNameMap(rows *sql.Rows) (map[string]int, error) {
|
func analyticsRowsToNameMap(rows *sql.Rows) (map[string]int, error) {
|
||||||
nameMap := make(map[string]int)
|
nameMap := make(map[string]int)
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
|
@ -171,21 +171,20 @@ func Dashboard(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
|
||||||
return c.InternalError(intErr, w, r)
|
return c.InternalError(intErr, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var gridElements = []GE{
|
var gridElements = []GE{}
|
||||||
// TODO: Implement a check for new versions of Gosora
|
var addElem = func(id string, href string, body string, order int, class string, back string, textColour string, tooltip string) {
|
||||||
// TODO: Localise this
|
gridElements = append(gridElements, GE{id,href,body,order,class,back,textColour,tooltip})
|
||||||
//GE{"dash-version", "v" + version.String(), 0, "grid_istat stat_green", "", "", "Gosora is up-to-date :)"},
|
|
||||||
GE{"dash-version", "v" + c.SoftwareVersion.String(), 0, "grid_istat", "", "", ""},
|
|
||||||
|
|
||||||
GE{"dash-cpu", p.GetTmplPhrasef("panel_dashboard_cpu",cpustr), 1, "grid_istat " + cpuColour, "", "", p.GetTmplPhrase("panel_dashboard_cpu_desc")},
|
|
||||||
GE{"dash-ram", p.GetTmplPhrasef("panel_dashboard_ram",ramstr), 2, "grid_istat " + ramColour, "", "", p.GetTmplPhrase("panel_dashboard_ram_desc")},
|
|
||||||
|
|
||||||
GE{"dash-memused", p.GetTmplPhrasef("panel_dashboard_memused",memCount, memUnit), 2, "grid_istat", "", "", p.GetTmplPhrase("panel_dashboard_memused_desc")},
|
|
||||||
}
|
|
||||||
var addElement = func(element GE) {
|
|
||||||
gridElements = append(gridElements, element)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Implement a check for new versions of Gosora
|
||||||
|
// TODO: Localise this
|
||||||
|
//addElem("dash-version", "", "v" + version.String(), 0, "grid_istat stat_green", "", "", "Gosora is up-to-date :)")
|
||||||
|
addElem("dash-version", "","v" + c.SoftwareVersion.String(), 0, "grid_istat", "", "", "")
|
||||||
|
|
||||||
|
addElem("dash-cpu","", p.GetTmplPhrasef("panel_dashboard_cpu",cpustr), 1, "grid_istat " + cpuColour, "", "", p.GetTmplPhrase("panel_dashboard_cpu_desc"))
|
||||||
|
addElem("dash-ram","", p.GetTmplPhrasef("panel_dashboard_ram",ramstr), 2, "grid_istat " + ramColour, "", "", p.GetTmplPhrase("panel_dashboard_ram_desc"))
|
||||||
|
addElem("dash-memused","/panel/analytics/memory/", p.GetTmplPhrasef("panel_dashboard_memused",memCount, memUnit), 2, "grid_istat", "", "", p.GetTmplPhrase("panel_dashboard_memused_desc"))
|
||||||
|
|
||||||
if c.EnableWebsockets {
|
if c.EnableWebsockets {
|
||||||
uonline := c.WsHub.UserCount()
|
uonline := c.WsHub.UserCount()
|
||||||
gonline := c.WsHub.GuestCount()
|
gonline := c.WsHub.GuestCount()
|
||||||
|
@ -200,24 +199,24 @@ func Dashboard(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
|
||||||
uonline, uunit := c.ConvertFriendlyUnit(uonline)
|
uonline, uunit := c.ConvertFriendlyUnit(uonline)
|
||||||
gonline, gunit := c.ConvertFriendlyUnit(gonline)
|
gonline, gunit := c.ConvertFriendlyUnit(gonline)
|
||||||
|
|
||||||
addElement(GE{"dash-totonline", p.GetTmplPhrasef("panel_dashboard_online", totonline, totunit), 3, "grid_stat " + onlineColour, "", "", p.GetTmplPhrase("panel_dashboard_online_desc")})
|
addElem("dash-totonline", "",p.GetTmplPhrasef("panel_dashboard_online", totonline, totunit), 3, "grid_stat " + onlineColour, "", "", p.GetTmplPhrase("panel_dashboard_online_desc"))
|
||||||
addElement(GE{"dash-gonline", p.GetTmplPhrasef("panel_dashboard_guests_online", gonline, gunit), 4, "grid_stat " + onlineGuestsColour, "", "", p.GetTmplPhrase("panel_dashboard_guests_online_desc")})
|
addElem("dash-gonline","", p.GetTmplPhrasef("panel_dashboard_guests_online", gonline, gunit), 4, "grid_stat " + onlineGuestsColour, "", "", p.GetTmplPhrase("panel_dashboard_guests_online_desc"))
|
||||||
addElement(GE{"dash-uonline", p.GetTmplPhrasef("panel_dashboard_users_online", uonline, uunit), 5, "grid_stat " + onlineUsersColour, "", "", p.GetTmplPhrase("panel_dashboard_users_online_desc")})
|
addElem("dash-uonline","", p.GetTmplPhrasef("panel_dashboard_users_online", uonline, uunit), 5, "grid_stat " + onlineUsersColour, "", "", p.GetTmplPhrase("panel_dashboard_users_online_desc"))
|
||||||
//addElement(GE{"dash-reqs", strconv.Itoa(reqCount) + " reqs / second", 7, "grid_stat grid_end_group " + topicColour, "", "", "The number of requests over the last 24 hours"})
|
//addElem("dash-reqs","", strconv.Itoa(reqCount) + " reqs / second", 7, "grid_stat grid_end_group " + topicColour, "", "", "The number of requests over the last 24 hours")
|
||||||
}
|
}
|
||||||
|
|
||||||
addElement(GE{"dash-postsperday", strconv.Itoa(postCount) + " posts" + postInterval, 6, "grid_stat " + postColour, "", "", "The number of new posts over the last 24 hours"})
|
addElem("dash-postsperday", "",strconv.Itoa(postCount) + " posts" + postInterval, 6, "grid_stat " + postColour, "", "", "The number of new posts over the last 24 hours")
|
||||||
addElement(GE{"dash-topicsperday", strconv.Itoa(topicCount) + " topics" + topicInterval, 7, "grid_stat " + topicColour, "", "", "The number of new topics over the last 24 hours"})
|
addElem("dash-topicsperday", "",strconv.Itoa(topicCount) + " topics" + topicInterval, 7, "grid_stat " + topicColour, "", "", "The number of new topics over the last 24 hours")
|
||||||
addElement(GE{"dash-totonlineperday", "?? online / day", 8, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*, "The people online over the last 24 hours"*/})
|
addElem("dash-totonlineperday","", "?? online / day", 8, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*, "The people online over the last 24 hours"*/)
|
||||||
|
|
||||||
addElement(GE{"dash-searches", "?? searches / week", 9, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The number of searches over the last 7 days"*/})
|
addElem("dash-searches","", "?? searches / week", 9, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The number of searches over the last 7 days"*/)
|
||||||
addElement(GE{"dash-newusers", strconv.Itoa(newUserCount) + " new users" + newUserInterval, 10, "grid_stat", "", "", "The number of new users over the last 7 days"})
|
addElem("dash-newusers","", strconv.Itoa(newUserCount) + " new users" + newUserInterval, 10, "grid_stat", "", "", "The number of new users over the last 7 days")
|
||||||
addElement(GE{"dash-reports", strconv.Itoa(reportCount) + " reports" + reportInterval, 11, "grid_stat", "", "", "The number of reports over the last 7 days"})
|
addElem("dash-reports","", strconv.Itoa(reportCount) + " reports" + reportInterval, 11, "grid_stat", "", "", "The number of reports over the last 7 days")
|
||||||
|
|
||||||
if false {
|
if false {
|
||||||
addElement(GE{"dash-minperuser", "?? minutes / user / week", 12, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The average number of number of minutes spent by each active user over the last 7 days"*/})
|
addElem("dash-minperuser","", "?? minutes / user / week", 12, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The average number of number of minutes spent by each active user over the last 7 days"*/)
|
||||||
addElement(GE{"dash-visitorsperweek", "?? visitors / week", 13, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The number of unique visitors we've had over the last 7 days"*/})
|
addElem("dash-visitorsperweek","", "?? visitors / week", 13, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The number of unique visitors we've had over the last 7 days"*/)
|
||||||
addElement(GE{"dash-postsperuser", "?? posts / user / week", 14, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The average number of posts made by each active user over the past week"*/})
|
addElem("dash-postsperuser","", "?? posts / user / week", 14, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The average number of posts made by each active user over the past week"*/)
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_dashboard_right","","panel_dashboard", gridElements})
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_dashboard_right","","panel_dashboard", gridElements})
|
||||||
|
|
|
@ -16,7 +16,7 @@ func wsTopicList(topicList []*c.TopicsRow, lastPage int) *c.WsTopicList {
|
||||||
for i, topicRow := range topicList {
|
for i, topicRow := range topicList {
|
||||||
wsTopicList[i] = topicRow.WebSockets()
|
wsTopicList[i] = topicRow.WebSockets()
|
||||||
}
|
}
|
||||||
return &c.WsTopicList{wsTopicList, lastPage}
|
return &c.WsTopicList{wsTopicList, lastPage, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TopicList(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
|
func TopicList(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
|
||||||
|
|
|
@ -5,5 +5,6 @@ CREATE TABLE [activity_stream] (
|
||||||
[event] nvarchar (50) not null,
|
[event] nvarchar (50) not null,
|
||||||
[elementType] nvarchar (50) not null,
|
[elementType] nvarchar (50) not null,
|
||||||
[elementID] int not null,
|
[elementID] int not null,
|
||||||
|
[createdAt] datetime not null,
|
||||||
primary key([asid])
|
primary key([asid])
|
||||||
);
|
);
|
|
@ -1,4 +1,6 @@
|
||||||
CREATE TABLE [memchunks] (
|
CREATE TABLE [memchunks] (
|
||||||
[count] int DEFAULT 0 not null,
|
[count] int DEFAULT 0 not null,
|
||||||
|
[stack] int DEFAULT 0 not null,
|
||||||
|
[heap] int DEFAULT 0 not null,
|
||||||
[createdAt] datetime not null
|
[createdAt] datetime not null
|
||||||
);
|
);
|
|
@ -0,0 +1,4 @@
|
||||||
|
CREATE TABLE [meta] (
|
||||||
|
[name] nvarchar (200) not null,
|
||||||
|
[value] nvarchar (200) not null
|
||||||
|
);
|
|
@ -5,5 +5,6 @@ CREATE TABLE `activity_stream` (
|
||||||
`event` varchar(50) not null,
|
`event` varchar(50) not null,
|
||||||
`elementType` varchar(50) not null,
|
`elementType` varchar(50) not null,
|
||||||
`elementID` int not null,
|
`elementID` int not null,
|
||||||
|
`createdAt` datetime not null,
|
||||||
primary key(`asid`)
|
primary key(`asid`)
|
||||||
);
|
);
|
|
@ -1,4 +1,6 @@
|
||||||
CREATE TABLE `memchunks` (
|
CREATE TABLE `memchunks` (
|
||||||
`count` int DEFAULT 0 not null,
|
`count` int DEFAULT 0 not null,
|
||||||
|
`stack` int DEFAULT 0 not null,
|
||||||
|
`heap` int DEFAULT 0 not null,
|
||||||
`createdAt` datetime not null
|
`createdAt` datetime not null
|
||||||
);
|
);
|
|
@ -0,0 +1,4 @@
|
||||||
|
CREATE TABLE `meta` (
|
||||||
|
`name` varchar(200) not null,
|
||||||
|
`value` varchar(200) not null
|
||||||
|
);
|
|
@ -5,5 +5,6 @@ CREATE TABLE "activity_stream" (
|
||||||
`event` varchar (50) not null,
|
`event` varchar (50) not null,
|
||||||
`elementType` varchar (50) not null,
|
`elementType` varchar (50) not null,
|
||||||
`elementID` int not null,
|
`elementID` int not null,
|
||||||
|
`createdAt` timestamp not null,
|
||||||
primary key(`asid`)
|
primary key(`asid`)
|
||||||
);
|
);
|
|
@ -1,4 +1,6 @@
|
||||||
CREATE TABLE "memchunks" (
|
CREATE TABLE "memchunks" (
|
||||||
`count` int DEFAULT 0 not null,
|
`count` int DEFAULT 0 not null,
|
||||||
|
`stack` int DEFAULT 0 not null,
|
||||||
|
`heap` int DEFAULT 0 not null,
|
||||||
`createdAt` timestamp not null
|
`createdAt` timestamp not null
|
||||||
);
|
);
|
|
@ -0,0 +1,4 @@
|
||||||
|
CREATE TABLE "meta" (
|
||||||
|
`name` varchar (200) not null,
|
||||||
|
`value` varchar (200) not null
|
||||||
|
);
|
|
@ -0,0 +1,96 @@
|
||||||
|
<div class="colstack_item colstack_head">
|
||||||
|
<div class="rowitem">
|
||||||
|
<h1>{{lang "panel_statistics_active_memory_head"}}</h1>
|
||||||
|
{{template "panel_analytics_time_range_month.html" . }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/active-memory/" method="get"></form>
|
||||||
|
<div id="panel_analytics_memory" class="colstack_graph_holder">
|
||||||
|
<div class="ct_chart" aria-label="{{lang "panel_statistics_memory_chart_aria"}}"></div>
|
||||||
|
</div>
|
||||||
|
<div class="colstack_item colstack_head">
|
||||||
|
<div class="rowitem">
|
||||||
|
<h1>{{lang "panel_statistics_details_head"}}</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="panel_analytics_memory_table" class="colstack_item rowlist" aria-label="{{lang "panel_statistics_memory_table_aria"}}">
|
||||||
|
{{range .ViewItems}}
|
||||||
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
|
<a class="panel_upshift unix_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}to_24_hour_time{{else}}to_date{{end}}">{{.Time}}</a>
|
||||||
|
<span class="panel_compacttext to_right">{{.Count}}{{.Unit}}</span>
|
||||||
|
</div>
|
||||||
|
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_statistics_memory_no_memory"}}</div>{{end}}
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
let rawLabels = [{{range .Graph.Labels}}
|
||||||
|
{{.}},{{end}}
|
||||||
|
];
|
||||||
|
let seriesData = [{{range .Graph.Series}}[{{range .}}
|
||||||
|
{{.}},{{end}}
|
||||||
|
],{{end}}
|
||||||
|
];
|
||||||
|
let legendNames = [{{range .Graph.Legends}}
|
||||||
|
{{.}},{{end}}
|
||||||
|
];
|
||||||
|
|
||||||
|
(function(window, document, Chartist) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
Chartist.plugins = Chartist.plugins || {};
|
||||||
|
Chartist.plugins.byteUnits = function(options) {
|
||||||
|
options = Chartist.extend({}, {}, options);
|
||||||
|
|
||||||
|
return function byteUnits(chart) {
|
||||||
|
if(!chart instanceof Chartist.Line) return;
|
||||||
|
|
||||||
|
chart.on('created', function() {
|
||||||
|
console.log("running created")
|
||||||
|
const vbits = document.getElementsByClassName("ct-vertical");
|
||||||
|
if(vbits==null) return;
|
||||||
|
|
||||||
|
let tbits = [];
|
||||||
|
for(let i = 0; i < vbits.length; i++) {
|
||||||
|
tbits[i] = vbits[i].innerHTML;
|
||||||
|
}
|
||||||
|
console.log("tbits:",tbits);
|
||||||
|
|
||||||
|
const calc = (places) => {
|
||||||
|
if(places==3) return;
|
||||||
|
|
||||||
|
const matcher = vbits[0].innerHTML;
|
||||||
|
let allMatch = true;
|
||||||
|
for(let i = 0; i < tbits.length; i++) {
|
||||||
|
let val = convertByteUnit(tbits[i], places);
|
||||||
|
if(val!=matcher) allMatch = false;
|
||||||
|
vbits[i].innerHTML = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(allMatch) calc(places + 1);
|
||||||
|
}
|
||||||
|
calc(0);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}(window, document, Chartist));
|
||||||
|
const noPre = ["twelve-hours","one-day","two-days","one-week","one-month"];
|
||||||
|
const preStats = () => {
|
||||||
|
if((!"{{.TimeRange}}" in noPre) && seriesData.length > 0 && seriesData[0].length > 12) {
|
||||||
|
let elem = document.getElementsByClassName("colstack_graph_holder")[0];
|
||||||
|
let w = elem.clientWidth;
|
||||||
|
console.log("w:",w);
|
||||||
|
elem.classList.add("scrolly");
|
||||||
|
console.log("elem.clientWidth:",elem.clientWidth);
|
||||||
|
elem.setAttribute("style","width:"+w+"px;");
|
||||||
|
console.log("elem.clientWidth:",elem.clientWidth);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addInitHook("after_phrases", () => {
|
||||||
|
addInitHook("end_init", () => {
|
||||||
|
addInitHook("analytics_loaded", () => {
|
||||||
|
preStats();
|
||||||
|
buildStatsChart(rawLabels, seriesData, "{{.TimeRange}}",legendNames,true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -1,14 +1,7 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_statistics_memory_head"}}</h1>
|
<h1>{{lang "panel_statistics_memory_head"}}</h1>
|
||||||
<select form="timeRangeForm" class="timeRangeSelector to_right" name="timeRange">
|
{{template "panel_analytics_time_range_month.html" . }}
|
||||||
<option val="one-month"{{if eq .TimeRange "one-month"}} selected{{end}}>{{lang "panel_statistics_time_range_one_month"}}</option>
|
|
||||||
<option val="one-week"{{if eq .TimeRange "one-week"}} selected{{end}}>{{lang "panel_statistics_time_range_one_week"}}</option>
|
|
||||||
<option val="two-days"{{if eq .TimeRange "two-days"}} selected{{end}}>{{lang "panel_statistics_time_range_two_days"}}</option>
|
|
||||||
<option val="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>{{lang "panel_statistics_time_range_one_day"}}</option>
|
|
||||||
<option val="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>{{lang "panel_statistics_time_range_twelve_hours"}}</option>
|
|
||||||
<option val="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>{{lang "panel_statistics_time_range_six_hours"}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/memory/" method="get"></form>
|
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/memory/" method="get"></form>
|
||||||
|
@ -20,7 +13,7 @@
|
||||||
<h1>{{lang "panel_statistics_details_head"}}</h1>
|
<h1>{{lang "panel_statistics_details_head"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_analytics_posts_table" class="colstack_item rowlist" aria-label="{{lang "panel_statistics_memory_table_aria"}}">
|
<div id="panel_analytics_memory_table" class="colstack_item rowlist" aria-label="{{lang "panel_statistics_memory_table_aria"}}">
|
||||||
{{range .ViewItems}}
|
{{range .ViewItems}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a class="panel_upshift unix_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}to_24_hour_time{{else}}to_date{{end}}">{{.Time}}</a>
|
<a class="panel_upshift unix_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}to_24_hour_time{{else}}to_date{{end}}">{{.Time}}</a>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<select form="timeRangeForm" class="timeRangeSelector to_right" name="timeRange">
|
||||||
|
<option val="one-month"{{if eq .TimeRange "one-month"}} selected{{end}}>{{lang "panel_statistics_time_range_one_month"}}</option>
|
||||||
|
<option val="one-week"{{if eq .TimeRange "one-week"}} selected{{end}}>{{lang "panel_statistics_time_range_one_week"}}</option>
|
||||||
|
<option val="two-days"{{if eq .TimeRange "two-days"}} selected{{end}}>{{lang "panel_statistics_time_range_two_days"}}</option>
|
||||||
|
<option val="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>{{lang "panel_statistics_time_range_one_day"}}</option>
|
||||||
|
<option val="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>{{lang "panel_statistics_time_range_twelve_hours"}}</option>
|
||||||
|
<option val="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>{{lang "panel_statistics_time_range_six_hours"}}</option>
|
||||||
|
</select>
|
|
@ -4,7 +4,7 @@
|
||||||
<div id="panel_dashboard" class="colstack_grid">
|
<div id="panel_dashboard" class="colstack_grid">
|
||||||
{{range .}}
|
{{range .}}
|
||||||
<div id="{{.ID}}" class="grid_item {{.Class}}" title="{{.Note}}" style="{{if .TextColour}}color: {{.TextColour}};{{end}}{{if .Background}}background-color: {{.Background}};{{end}}">
|
<div id="{{.ID}}" class="grid_item {{.Class}}" title="{{.Note}}" style="{{if .TextColour}}color: {{.TextColour}};{{end}}{{if .Background}}background-color: {{.Background}};{{end}}">
|
||||||
<span>{{.Body}}</span>
|
{{if .Href}}<a href="{{.Href}}">{{.Body}}</a>{{else}}<span>{{.Body}}</span>{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
|
@ -65,6 +65,9 @@
|
||||||
<div class="rowitem passive submenu">
|
<div class="rowitem passive submenu">
|
||||||
<a href="/panel/analytics/memory/">{{lang "panel_menu_statistics_memory"}}</a>
|
<a href="/panel/analytics/memory/">{{lang "panel_menu_statistics_memory"}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="rowitem passive submenu">
|
||||||
|
<a href="/panel/analytics/active-memory/">{{lang "panel_menu_statistics_active_memory"}}</a>
|
||||||
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="rowitem passive">
|
<div class="rowitem passive">
|
||||||
<a href="/forum/{{.ReportForumID}}">{{lang "panel_menu_reports"}}</a> <a class="menu_stats" href="#">({{.Stats.Reports}})</a>
|
<a href="/forum/{{.ReportForumID}}">{{lang "panel_menu_reports"}}</a> <a class="menu_stats" href="#">({{.Stats.Reports}})</a>
|
||||||
|
|
|
@ -65,6 +65,9 @@
|
||||||
<div class="rowitem passive submenu">
|
<div class="rowitem passive submenu">
|
||||||
<a href="/panel/analytics/memory/">{{lang "panel_menu_statistics_memory"}}</a>
|
<a href="/panel/analytics/memory/">{{lang "panel_menu_statistics_memory"}}</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="rowitem passive submenu">
|
||||||
|
<a href="/panel/analytics/active-memory/">{{lang "panel_menu_statistics_active_memory"}}</a>
|
||||||
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="rowitem passive">
|
<div class="rowitem passive">
|
||||||
<a href="/forum/{{.ReportForumID}}">{{lang "panel_menu_reports"}}</a> <a class="menu_stats" href="#">({{.Stats.Reports}})</a>
|
<a href="/forum/{{.ReportForumID}}">{{lang "panel_menu_reports"}}</a> <a class="menu_stats" href="#">({{.Stats.Reports}})</a>
|
||||||
|
|
88
tickloop.go
88
tickloop.go
|
@ -3,8 +3,9 @@ package main
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
"time"
|
||||||
|
"strconv"
|
||||||
|
"sync/atomic"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
c "github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
|
@ -51,6 +52,18 @@ func runHook(name string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func tickLoop(thumbChan chan bool) {
|
func tickLoop(thumbChan chan bool) {
|
||||||
|
lastDailyStr, err := c.Meta.Get("lastDaily")
|
||||||
|
// TODO: Report this error back correctly...
|
||||||
|
if err != nil && err != sql.ErrNoRows {
|
||||||
|
c.LogError(err)
|
||||||
|
}
|
||||||
|
lastDaily, _ := strconv.ParseInt(lastDailyStr, 10, 64)
|
||||||
|
now := time.Now().Unix()
|
||||||
|
low := now - (60 * 60 * 24)
|
||||||
|
if lastDaily < low {
|
||||||
|
dailies()
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Write tests for these
|
// TODO: Write tests for these
|
||||||
// Run this goroutine once every half second
|
// Run this goroutine once every half second
|
||||||
halfSecondTicker := time.NewTicker(time.Second / 2)
|
halfSecondTicker := time.NewTicker(time.Second / 2)
|
||||||
|
@ -127,31 +140,58 @@ func tickLoop(thumbChan chan bool) {
|
||||||
runHook("after_hour_tick")
|
runHook("after_hour_tick")
|
||||||
// TODO: Handle the instance going down a lot better
|
// TODO: Handle the instance going down a lot better
|
||||||
case <-dailyTicker.C:
|
case <-dailyTicker.C:
|
||||||
// TODO: Find a more efficient way of doing this
|
dailies()
|
||||||
err := qgen.NewAcc().Select("activity_stream").Cols("asid").EachInt(func(asid int) error {
|
|
||||||
count, err := qgen.NewAcc().Count("activity_stream_matches").Where("asid = ?").Total()
|
|
||||||
if err != sql.ErrNoRows {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if count > 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
_, err = qgen.NewAcc().Delete("activity_stream").Where("asid = ?").Run(asid)
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil && err != sql.ErrNoRows {
|
|
||||||
c.LogError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Config.PostIPCutoff > -1 {
|
|
||||||
// TODO: Use unixtime to remove this MySQLesque logic?
|
|
||||||
_, err := qgen.NewAcc().Update("replies").Set("ipaddress = '0'").DateOlderThan("createdAt",c.Config.PostIPCutoff,"day").Where("ipaddress != '0'").Exec()
|
|
||||||
if err != nil {
|
|
||||||
c.LogError(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle the daily clean-up.
|
// TODO: Handle the daily clean-up.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func dailies() {
|
||||||
|
// TODO: Find a more efficient way of doing this
|
||||||
|
err := qgen.NewAcc().Select("activity_stream").Cols("asid").EachInt(func(asid int) error {
|
||||||
|
count, err := qgen.NewAcc().Count("activity_stream_matches").Where("asid = " + strconv.Itoa(asid)).Total()
|
||||||
|
if err != sql.ErrNoRows {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
_, err = qgen.NewAcc().Delete("activity_stream").Where("asid = ?").Run(asid)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
if err != nil && err != sql.ErrNoRows {
|
||||||
|
c.LogError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Config.PostIPCutoff > -1 {
|
||||||
|
// TODO: Use unixtime to remove this MySQLesque logic?
|
||||||
|
_, err := qgen.NewAcc().Update("topics").Set("ipaddress = '0'").DateOlderThan("createdAt",c.Config.PostIPCutoff,"day").Where("ipaddress != '0'").Exec()
|
||||||
|
if err != nil {
|
||||||
|
c.LogError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = qgen.NewAcc().Update("replies").Set("ipaddress = '0'").DateOlderThan("createdAt",c.Config.PostIPCutoff,"day").Where("ipaddress != '0'").Exec()
|
||||||
|
if err != nil {
|
||||||
|
c.LogError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Find some way of purging the ip data in polls_votes without breaking any anti-cheat measures which might be running... maybe hash it instead?
|
||||||
|
|
||||||
|
_, err = qgen.NewAcc().Update("users_replies").Set("ipaddress = '0'").DateOlderThan("createdAt",c.Config.PostIPCutoff,"day").Where("ipaddress != '0'").Exec()
|
||||||
|
if err != nil {
|
||||||
|
c.LogError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: lastActiveAt isn't currently set, so we can't rely on this to purge last_ips of users who haven't been on in a while
|
||||||
|
/*_, err = qgen.NewAcc().Update("users").Set("last_ip = '0'").DateOlderThan("lastActiveAt",c.Config.PostIPCutoff,"day").Where("last_ip != '0'").Exec()
|
||||||
|
if err != nil {
|
||||||
|
c.LogError(err)
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.Meta.Set("lastDaily", strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
|
if err != nil {
|
||||||
|
c.LogError(err)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue