diff --git a/alerts.go b/alerts.go
index bdf5b664..07741251 100644
--- a/alerts.go
+++ b/alerts.go
@@ -58,9 +58,7 @@ func buildAlert(asid int, event string, elementType string, actorID int, targetU
act = "created a new topic"
topic, err := common.Topics.Get(elementID)
if err != nil {
- if common.Dev.DebugMode {
- log.Print("Unable to find linked topic " + strconv.Itoa(elementID))
- }
+ common.DebugLogf("Unable to find linked topic %d", elementID)
return "", errors.New("Unable to find the linked topic")
}
url = topic.Link
@@ -73,9 +71,7 @@ func buildAlert(asid int, event string, elementType string, actorID int, targetU
case "topic":
topic, err := common.Topics.Get(elementID)
if err != nil {
- if common.Dev.DebugMode {
- log.Print("Unable to find linked topic " + strconv.Itoa(elementID))
- }
+ common.DebugLogf("Unable to find linked topic %d", elementID)
return "", errors.New("Unable to find the linked topic")
}
url = topic.Link
@@ -87,9 +83,7 @@ func buildAlert(asid int, event string, elementType string, actorID int, targetU
case "user":
targetUser, err = common.Users.Get(elementID)
if err != nil {
- if common.Dev.DebugMode {
- log.Print("Unable to find target user " + strconv.Itoa(elementID))
- }
+ common.DebugLogf("Unable to find target user %d", elementID)
return "", errors.New("Unable to find the target user")
}
area = targetUser.Name
diff --git a/bot_routes.go b/bot_routes.go
index ab3d63ba..c747fe90 100644
--- a/bot_routes.go
+++ b/bot_routes.go
@@ -2,7 +2,6 @@ package main
import (
"errors"
- "log"
"net/http"
"strconv"
"strings"
@@ -79,10 +78,9 @@ func sitemapSwitch(w http.ResponseWriter, r *http.Request) common.RouteError {
spath = strings.TrimSuffix(spath, ".xml")
page, err := strconv.Atoi(spath)
if err != nil {
- if common.Dev.DebugMode {
- log.Printf("Unable to convert string '%s' to integer in fuzzy route", spath)
- }
- return common.NotFound(w, r)
+ // ? What's this? Do we need it? Was it just a quick trace?
+ common.DebugLogf("Unable to convert string '%s' to integer in fuzzy route", spath)
+ return common.NotFound(w, r, nil)
}
return fuzzy.Handle(w, r, page)
}
@@ -90,7 +88,7 @@ func sitemapSwitch(w http.ResponseWriter, r *http.Request) common.RouteError {
route, ok := sitemapRoutes[path]
if !ok {
- return common.NotFound(w, r)
+ return common.NotFound(w, r, nil)
}
return route(w, r)
}
diff --git a/common/common.go b/common/common.go
index c02a8cdb..f19bd51a 100644
--- a/common/common.go
+++ b/common/common.go
@@ -84,60 +84,26 @@ func (inits dbInits) Add(init ...func(acc *qgen.Accumulator) error) {
DbInits = dbInits(append(DbInits, init...))
}
-func debugDetail(args ...interface{}) {
+func DebugDetail(args ...interface{}) {
if Dev.SuperDebug {
log.Print(args...)
}
}
-func debugDetailf(str string, args ...interface{}) {
+func DebugDetailf(str string, args ...interface{}) {
if Dev.SuperDebug {
log.Printf(str, args...)
}
}
-func debugLog(args ...interface{}) {
+func DebugLog(args ...interface{}) {
if Dev.DebugMode {
log.Print(args...)
}
}
-func debugLogf(str string, args ...interface{}) {
+func DebugLogf(str string, args ...interface{}) {
if Dev.DebugMode {
log.Printf(str, args...)
}
}
-
-// TODO: Make a neater API for this
-var routeMapEnum map[string]int
-var reverseRouteMapEnum map[int]string
-
-func SetRouteMapEnum(rme map[string]int) {
- routeMapEnum = rme
-}
-
-func SetReverseRouteMapEnum(rrme map[int]string) {
- reverseRouteMapEnum = rrme
-}
-
-var agentMapEnum map[string]int
-var reverseAgentMapEnum map[int]string
-
-func SetAgentMapEnum(ame map[string]int) {
- agentMapEnum = ame
-}
-
-func SetReverseAgentMapEnum(rame map[int]string) {
- reverseAgentMapEnum = rame
-}
-
-var osMapEnum map[string]int
-var reverseOSMapEnum map[int]string
-
-func SetOSMapEnum(osme map[string]int) {
- osMapEnum = osme
-}
-
-func SetReverseOSMapEnum(rosme map[int]string) {
- reverseOSMapEnum = rosme
-}
diff --git a/common/counters.go b/common/counters.go
deleted file mode 100644
index c342ea1a..00000000
--- a/common/counters.go
+++ /dev/null
@@ -1,463 +0,0 @@
-package common
-
-import (
- "database/sql"
- "sync"
- "sync/atomic"
-
- "../query_gen/lib"
-)
-
-// Global counters
-var GlobalViewCounter *DefaultViewCounter
-var AgentViewCounter *DefaultAgentViewCounter
-var OSViewCounter *DefaultOSViewCounter
-var RouteViewCounter *DefaultRouteViewCounter
-var PostCounter *DefaultPostCounter
-var TopicCounter *DefaultTopicCounter
-
-// Local counters
-var TopicViewCounter *DefaultTopicViewCounter
-
-type DefaultViewCounter struct {
- buckets [2]int64
- currentBucket int64
-
- insert *sql.Stmt
-}
-
-func NewGlobalViewCounter() (*DefaultViewCounter, error) {
- acc := qgen.Builder.Accumulator()
- counter := &DefaultViewCounter{
- currentBucket: 0,
- insert: acc.Insert("viewchunks").Columns("count, createdAt").Fields("?,UTC_TIMESTAMP()").Prepare(),
- }
- AddScheduledFifteenMinuteTask(counter.Tick) // This is run once every fifteen minutes to match the frequency of the RouteViewCounter
- //AddScheduledSecondTask(counter.Tick)
- AddShutdownTask(counter.Tick)
- return counter, acc.FirstError()
-}
-
-func (counter *DefaultViewCounter) Tick() (err error) {
- var oldBucket = counter.currentBucket
- var nextBucket int64 // 0
- if counter.currentBucket == 0 {
- nextBucket = 1
- }
- atomic.AddInt64(&counter.buckets[oldBucket], counter.buckets[nextBucket])
- atomic.StoreInt64(&counter.buckets[nextBucket], 0)
- atomic.StoreInt64(&counter.currentBucket, nextBucket)
-
- var previousViewChunk = counter.buckets[oldBucket]
- atomic.AddInt64(&counter.buckets[oldBucket], -previousViewChunk)
- return counter.insertChunk(previousViewChunk)
-}
-
-func (counter *DefaultViewCounter) Bump() {
- atomic.AddInt64(&counter.buckets[counter.currentBucket], 1)
-}
-
-func (counter *DefaultViewCounter) insertChunk(count int64) error {
- if count == 0 {
- return nil
- }
- debugLogf("Inserting a viewchunk with a count of %d", count)
- _, err := counter.insert.Exec(count)
- return err
-}
-
-type DefaultPostCounter struct {
- buckets [2]int64
- currentBucket int64
-
- insert *sql.Stmt
-}
-
-func NewPostCounter() (*DefaultPostCounter, error) {
- acc := qgen.Builder.Accumulator()
- counter := &DefaultPostCounter{
- currentBucket: 0,
- insert: acc.Insert("postchunks").Columns("count, createdAt").Fields("?,UTC_TIMESTAMP()").Prepare(),
- }
- AddScheduledFifteenMinuteTask(counter.Tick)
- //AddScheduledSecondTask(counter.Tick)
- AddShutdownTask(counter.Tick)
- return counter, acc.FirstError()
-}
-
-func (counter *DefaultPostCounter) Tick() (err error) {
- var oldBucket = counter.currentBucket
- var nextBucket int64 // 0
- if counter.currentBucket == 0 {
- nextBucket = 1
- }
- atomic.AddInt64(&counter.buckets[oldBucket], counter.buckets[nextBucket])
- atomic.StoreInt64(&counter.buckets[nextBucket], 0)
- atomic.StoreInt64(&counter.currentBucket, nextBucket)
-
- var previousViewChunk = counter.buckets[oldBucket]
- atomic.AddInt64(&counter.buckets[oldBucket], -previousViewChunk)
- return counter.insertChunk(previousViewChunk)
-}
-
-func (counter *DefaultPostCounter) Bump() {
- atomic.AddInt64(&counter.buckets[counter.currentBucket], 1)
-}
-
-func (counter *DefaultPostCounter) insertChunk(count int64) error {
- if count == 0 {
- return nil
- }
- debugLogf("Inserting a postchunk with a count of %d", count)
- _, err := counter.insert.Exec(count)
- return err
-}
-
-type DefaultTopicCounter struct {
- buckets [2]int64
- currentBucket int64
-
- insert *sql.Stmt
-}
-
-func NewTopicCounter() (*DefaultTopicCounter, error) {
- acc := qgen.Builder.Accumulator()
- counter := &DefaultTopicCounter{
- currentBucket: 0,
- insert: acc.Insert("topicchunks").Columns("count, createdAt").Fields("?,UTC_TIMESTAMP()").Prepare(),
- }
- AddScheduledFifteenMinuteTask(counter.Tick)
- //AddScheduledSecondTask(counter.Tick)
- AddShutdownTask(counter.Tick)
- return counter, acc.FirstError()
-}
-
-func (counter *DefaultTopicCounter) Tick() (err error) {
- var oldBucket = counter.currentBucket
- var nextBucket int64 // 0
- if counter.currentBucket == 0 {
- nextBucket = 1
- }
- atomic.AddInt64(&counter.buckets[oldBucket], counter.buckets[nextBucket])
- atomic.StoreInt64(&counter.buckets[nextBucket], 0)
- atomic.StoreInt64(&counter.currentBucket, nextBucket)
-
- var previousViewChunk = counter.buckets[oldBucket]
- atomic.AddInt64(&counter.buckets[oldBucket], -previousViewChunk)
- return counter.insertChunk(previousViewChunk)
-}
-
-func (counter *DefaultTopicCounter) Bump() {
- atomic.AddInt64(&counter.buckets[counter.currentBucket], 1)
-}
-
-func (counter *DefaultTopicCounter) insertChunk(count int64) error {
- if count == 0 {
- return nil
- }
- debugLogf("Inserting a topicchunk with a count of %d", count)
- _, err := counter.insert.Exec(count)
- return err
-}
-
-type RWMutexCounterBucket struct {
- counter int
- sync.RWMutex
-}
-
-type DefaultAgentViewCounter struct {
- agentBuckets []*RWMutexCounterBucket //[AgentID]count
- insert *sql.Stmt
-}
-
-func NewDefaultAgentViewCounter() (*DefaultAgentViewCounter, error) {
- acc := qgen.Builder.Accumulator()
- var agentBuckets = make([]*RWMutexCounterBucket, len(agentMapEnum))
- for bucketID, _ := range agentBuckets {
- agentBuckets[bucketID] = &RWMutexCounterBucket{counter: 0}
- }
- counter := &DefaultAgentViewCounter{
- agentBuckets: agentBuckets,
- insert: acc.Insert("viewchunks_agents").Columns("count, createdAt, browser").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
- }
- AddScheduledFifteenMinuteTask(counter.Tick)
- //AddScheduledSecondTask(counter.Tick)
- AddShutdownTask(counter.Tick)
- return counter, acc.FirstError()
-}
-
-func (counter *DefaultAgentViewCounter) Tick() error {
- for agentID, agentBucket := range counter.agentBuckets {
- var count int
- agentBucket.RLock()
- count = agentBucket.counter
- agentBucket.counter = 0
- agentBucket.RUnlock()
-
- err := counter.insertChunk(count, agentID) // TODO: Bulk insert for speed?
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func (counter *DefaultAgentViewCounter) insertChunk(count int, agent int) error {
- if count == 0 {
- return nil
- }
- var agentName = reverseAgentMapEnum[agent]
- debugLogf("Inserting a viewchunk with a count of %d for agent %s (%d)", count, agentName, agent)
- _, err := counter.insert.Exec(count, agentName)
- return err
-}
-
-func (counter *DefaultAgentViewCounter) Bump(agent int) {
- // TODO: Test this check
- debugDetail("counter.agentBuckets[", agent, "]: ", counter.agentBuckets[agent])
- if len(counter.agentBuckets) <= agent || agent < 0 {
- return
- }
- counter.agentBuckets[agent].Lock()
- counter.agentBuckets[agent].counter++
- counter.agentBuckets[agent].Unlock()
-}
-
-type DefaultOSViewCounter struct {
- osBuckets []*RWMutexCounterBucket //[OSID]count
- insert *sql.Stmt
-}
-
-func NewDefaultOSViewCounter() (*DefaultOSViewCounter, error) {
- acc := qgen.Builder.Accumulator()
- var osBuckets = make([]*RWMutexCounterBucket, len(osMapEnum))
- for bucketID, _ := range osBuckets {
- osBuckets[bucketID] = &RWMutexCounterBucket{counter: 0}
- }
- counter := &DefaultOSViewCounter{
- osBuckets: osBuckets,
- insert: acc.Insert("viewchunks_systems").Columns("count, createdAt, system").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
- }
- AddScheduledFifteenMinuteTask(counter.Tick)
- //AddScheduledSecondTask(counter.Tick)
- AddShutdownTask(counter.Tick)
- return counter, acc.FirstError()
-}
-
-func (counter *DefaultOSViewCounter) Tick() error {
- for osID, osBucket := range counter.osBuckets {
- var count int
- osBucket.RLock()
- count = osBucket.counter
- osBucket.counter = 0 // TODO: Add a SetZero method to reduce the amount of duplicate code between the OS and agent counters?
- osBucket.RUnlock()
-
- err := counter.insertChunk(count, osID) // TODO: Bulk insert for speed?
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func (counter *DefaultOSViewCounter) insertChunk(count int, os int) error {
- if count == 0 {
- return nil
- }
- var osName = reverseOSMapEnum[os]
- debugLogf("Inserting a viewchunk with a count of %d for OS %s (%d)", count, osName, os)
- _, err := counter.insert.Exec(count, osName)
- return err
-}
-
-func (counter *DefaultOSViewCounter) Bump(os int) {
- // TODO: Test this check
- debugDetail("counter.osBuckets[", os, "]: ", counter.osBuckets[os])
- if len(counter.osBuckets) <= os || os < 0 {
- return
- }
- counter.osBuckets[os].Lock()
- counter.osBuckets[os].counter++
- counter.osBuckets[os].Unlock()
-}
-
-type DefaultRouteViewCounter struct {
- routeBuckets []*RWMutexCounterBucket //[RouteID]count
- insert *sql.Stmt
-}
-
-func NewDefaultRouteViewCounter() (*DefaultRouteViewCounter, error) {
- acc := qgen.Builder.Accumulator()
- var routeBuckets = make([]*RWMutexCounterBucket, len(routeMapEnum))
- for bucketID, _ := range routeBuckets {
- routeBuckets[bucketID] = &RWMutexCounterBucket{counter: 0}
- }
- counter := &DefaultRouteViewCounter{
- routeBuckets: routeBuckets,
- insert: acc.Insert("viewchunks").Columns("count, createdAt, route").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
- }
- AddScheduledFifteenMinuteTask(counter.Tick) // There could be a lot of routes, so we don't want to be running this every second
- //AddScheduledSecondTask(counter.Tick)
- AddShutdownTask(counter.Tick)
- return counter, acc.FirstError()
-}
-
-func (counter *DefaultRouteViewCounter) Tick() error {
- for routeID, routeBucket := range counter.routeBuckets {
- var count int
- routeBucket.RLock()
- count = routeBucket.counter
- routeBucket.counter = 0
- routeBucket.RUnlock()
-
- err := counter.insertChunk(count, routeID) // TODO: Bulk insert for speed?
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func (counter *DefaultRouteViewCounter) insertChunk(count int, route int) error {
- if count == 0 {
- return nil
- }
- var routeName = reverseRouteMapEnum[route]
- debugLogf("Inserting a viewchunk with a count of %d for route %s (%d)", count, routeName, route)
- _, err := counter.insert.Exec(count, routeName)
- return err
-}
-
-func (counter *DefaultRouteViewCounter) Bump(route int) {
- // TODO: Test this check
- debugDetail("counter.routeBuckets[", route, "]: ", counter.routeBuckets[route])
- if len(counter.routeBuckets) <= route || route < 0 {
- return
- }
- counter.routeBuckets[route].Lock()
- counter.routeBuckets[route].counter++
- counter.routeBuckets[route].Unlock()
-}
-
-// TODO: The ForumViewCounter and TopicViewCounter
-
-// TODO: Unload forum counters without any views over the past 15 minutes, if the admin has configured the forumstore with a cap and it's been hit?
-// Forums can be reloaded from the database at any time, so we want to keep the counters separate from them
-type ForumViewCounter struct {
- buckets [2]int64
- currentBucket int64
-}
-
-/*func (counter *ForumViewCounter) insertChunk(count int, forum int) error {
- if count == 0 {
- return nil
- }
- debugLogf("Inserting a viewchunk with a count of %d for forum %d", count, forum)
- _, err := counter.insert.Exec(count, forum)
- return err
-}*/
-
-// TODO: Use two odd-even maps for now, and move to something more concurrent later, maybe a sharded map?
-type DefaultTopicViewCounter struct {
- oddTopics map[int]*RWMutexCounterBucket // map[tid]struct{counter,sync.RWMutex}
- evenTopics map[int]*RWMutexCounterBucket
- oddLock sync.RWMutex
- evenLock sync.RWMutex
-
- update *sql.Stmt
-}
-
-func NewDefaultTopicViewCounter() (*DefaultTopicViewCounter, error) {
- acc := qgen.Builder.Accumulator()
- counter := &DefaultTopicViewCounter{
- oddTopics: make(map[int]*RWMutexCounterBucket),
- evenTopics: make(map[int]*RWMutexCounterBucket),
- update: acc.Update("topics").Set("views = views + ?").Where("tid = ?").Prepare(),
- }
- AddScheduledFifteenMinuteTask(counter.Tick) // Who knows how many topics we have queued up, we probably don't want this running too frequently
- //AddScheduledSecondTask(counter.Tick)
- AddShutdownTask(counter.Tick)
- return counter, acc.FirstError()
-}
-
-func (counter *DefaultTopicViewCounter) Tick() error {
- counter.oddLock.RLock()
- oddTopics := counter.oddTopics
- counter.oddLock.RUnlock()
- for topicID, topic := range oddTopics {
- var count int
- topic.RLock()
- count = topic.counter
- topic.RUnlock()
- // TODO: Only delete the bucket when it's zero to avoid hitting popular topics?
- counter.oddLock.Lock()
- delete(counter.oddTopics, topicID)
- counter.oddLock.Unlock()
- err := counter.insertChunk(count, topicID)
- if err != nil {
- return err
- }
- }
-
- counter.evenLock.RLock()
- evenTopics := counter.evenTopics
- counter.evenLock.RUnlock()
- for topicID, topic := range evenTopics {
- var count int
- topic.RLock()
- count = topic.counter
- topic.RUnlock()
- // TODO: Only delete the bucket when it's zero to avoid hitting popular topics?
- counter.evenLock.Lock()
- delete(counter.evenTopics, topicID)
- counter.evenLock.Unlock()
- err := counter.insertChunk(count, topicID)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// TODO: Optimise this further. E.g. Using IN() on every one view topic. Rinse and repeat for two views, three views, four views and five views.
-func (counter *DefaultTopicViewCounter) insertChunk(count int, topicID int) error {
- if count == 0 {
- return nil
- }
- debugLogf("Inserting %d views into topic %d", count, topicID)
- _, err := counter.update.Exec(count, topicID)
- return err
-}
-
-func (counter *DefaultTopicViewCounter) Bump(topicID int) {
- // Is the ID even?
- if topicID%2 == 0 {
- counter.evenLock.RLock()
- topic, ok := counter.evenTopics[topicID]
- counter.evenLock.RUnlock()
- if ok {
- topic.Lock()
- topic.counter++
- topic.Unlock()
- } else {
- counter.evenLock.Lock()
- counter.evenTopics[topicID] = &RWMutexCounterBucket{counter: 1}
- counter.evenLock.Unlock()
- }
- return
- }
-
- counter.oddLock.RLock()
- topic, ok := counter.oddTopics[topicID]
- counter.oddLock.RUnlock()
- if ok {
- topic.Lock()
- topic.counter++
- topic.Unlock()
- } else {
- counter.oddLock.Lock()
- counter.oddTopics[topicID] = &RWMutexCounterBucket{counter: 1}
- counter.oddLock.Unlock()
- }
-}
diff --git a/common/counters/agents.go b/common/counters/agents.go
new file mode 100644
index 00000000..2f2f2008
--- /dev/null
+++ b/common/counters/agents.go
@@ -0,0 +1,68 @@
+package counters
+
+import (
+ "database/sql"
+
+ ".."
+ "../../query_gen/lib"
+)
+
+var AgentViewCounter *DefaultAgentViewCounter
+
+type DefaultAgentViewCounter struct {
+ agentBuckets []*RWMutexCounterBucket //[AgentID]count
+ insert *sql.Stmt
+}
+
+func NewDefaultAgentViewCounter() (*DefaultAgentViewCounter, error) {
+ acc := qgen.Builder.Accumulator()
+ var agentBuckets = make([]*RWMutexCounterBucket, len(agentMapEnum))
+ for bucketID, _ := range agentBuckets {
+ agentBuckets[bucketID] = &RWMutexCounterBucket{counter: 0}
+ }
+ counter := &DefaultAgentViewCounter{
+ agentBuckets: agentBuckets,
+ insert: acc.Insert("viewchunks_agents").Columns("count, createdAt, browser").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
+ }
+ common.AddScheduledFifteenMinuteTask(counter.Tick)
+ //common.AddScheduledSecondTask(counter.Tick)
+ common.AddShutdownTask(counter.Tick)
+ return counter, acc.FirstError()
+}
+
+func (counter *DefaultAgentViewCounter) Tick() error {
+ for agentID, agentBucket := range counter.agentBuckets {
+ var count int
+ agentBucket.RLock()
+ count = agentBucket.counter
+ agentBucket.counter = 0
+ agentBucket.RUnlock()
+
+ err := counter.insertChunk(count, agentID) // TODO: Bulk insert for speed?
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (counter *DefaultAgentViewCounter) insertChunk(count int, agent int) error {
+ if count == 0 {
+ return nil
+ }
+ var agentName = reverseAgentMapEnum[agent]
+ common.DebugLogf("Inserting a viewchunk with a count of %d for agent %s (%d)", count, agentName, agent)
+ _, err := counter.insert.Exec(count, agentName)
+ return err
+}
+
+func (counter *DefaultAgentViewCounter) Bump(agent int) {
+ // TODO: Test this check
+ common.DebugDetail("counter.agentBuckets[", agent, "]: ", counter.agentBuckets[agent])
+ if len(counter.agentBuckets) <= agent || agent < 0 {
+ return
+ }
+ counter.agentBuckets[agent].Lock()
+ counter.agentBuckets[agent].counter++
+ counter.agentBuckets[agent].Unlock()
+}
diff --git a/common/counters/common.go b/common/counters/common.go
new file mode 100644
index 00000000..7b331191
--- /dev/null
+++ b/common/counters/common.go
@@ -0,0 +1,42 @@
+package counters
+
+import "sync"
+
+type RWMutexCounterBucket struct {
+ counter int
+ sync.RWMutex
+}
+
+// TODO: Make a neater API for this
+var routeMapEnum map[string]int
+var reverseRouteMapEnum map[int]string
+
+func SetRouteMapEnum(rme map[string]int) {
+ routeMapEnum = rme
+}
+
+func SetReverseRouteMapEnum(rrme map[int]string) {
+ reverseRouteMapEnum = rrme
+}
+
+var agentMapEnum map[string]int
+var reverseAgentMapEnum map[int]string
+
+func SetAgentMapEnum(ame map[string]int) {
+ agentMapEnum = ame
+}
+
+func SetReverseAgentMapEnum(rame map[int]string) {
+ reverseAgentMapEnum = rame
+}
+
+var osMapEnum map[string]int
+var reverseOSMapEnum map[int]string
+
+func SetOSMapEnum(osme map[string]int) {
+ osMapEnum = osme
+}
+
+func SetReverseOSMapEnum(rosme map[int]string) {
+ reverseOSMapEnum = rosme
+}
diff --git a/common/counters/forums.go b/common/counters/forums.go
new file mode 100644
index 00000000..296b832e
--- /dev/null
+++ b/common/counters/forums.go
@@ -0,0 +1,86 @@
+package counters
+
+import (
+ "database/sql"
+ "sync"
+
+ ".."
+ "../../query_gen/lib"
+)
+
+// TODO: The forum view counter
+
+// TODO: Unload forum counters without any views over the past 15 minutes, if the admin has configured the forumstore with a cap and it's been hit?
+// Forums can be reloaded from the database at any time, so we want to keep the counters separate from them
+type DefaultForumViewCounter struct {
+ oddMap map[int]*RWMutexCounterBucket // map[fid]struct{counter,sync.RWMutex}
+ evenMap map[int]*RWMutexCounterBucket
+ oddLock sync.RWMutex
+ evenLock sync.RWMutex
+
+ insert *sql.Stmt
+}
+
+func NewDefaultForumViewCounter() (*DefaultForumViewCounter, error) {
+ acc := qgen.Builder.Accumulator()
+ counter := &DefaultForumViewCounter{
+ oddMap: make(map[int]*RWMutexCounterBucket),
+ evenMap: make(map[int]*RWMutexCounterBucket),
+ insert: acc.Insert("viewchunks_forums").Columns("count, createdAt, forum").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
+ }
+ common.AddScheduledFifteenMinuteTask(counter.Tick) // There could be a lot of routes, so we don't want to be running this every second
+ //AddScheduledSecondTask(counter.Tick)
+ common.AddShutdownTask(counter.Tick)
+ return counter, acc.FirstError()
+}
+
+func (counter *DefaultForumViewCounter) Tick() error {
+ counter.oddLock.RLock()
+ oddMap := counter.oddMap
+ counter.oddLock.RUnlock()
+ for forumID, forum := range oddMap {
+ var count int
+ forum.RLock()
+ count = forum.counter
+ forum.RUnlock()
+ // TODO: Only delete the bucket when it's zero to avoid hitting popular forums?
+ counter.oddLock.Lock()
+ delete(counter.oddMap, forumID)
+ counter.oddLock.Unlock()
+ err := counter.insertChunk(count, forumID)
+ if err != nil {
+ return err
+ }
+ }
+
+ counter.evenLock.RLock()
+ evenMap := counter.evenMap
+ counter.evenLock.RUnlock()
+ for forumID, forum := range evenMap {
+ var count int
+ forum.RLock()
+ count = forum.counter
+ forum.RUnlock()
+ // TODO: Only delete the bucket when it's zero to avoid hitting popular forums?
+ counter.evenLock.Lock()
+ delete(counter.evenMap, forumID)
+ counter.evenLock.Unlock()
+ err := counter.insertChunk(count, forumID)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (counter *DefaultForumViewCounter) insertChunk(count int, forum int) error {
+ if count == 0 {
+ return nil
+ }
+ common.DebugLogf("Inserting a viewchunk with a count of %d for forum %d", count, forum)
+ _, err := counter.insert.Exec(count, forum)
+ return err
+}
+
+// TODO: Add a forum counter backed by two maps which grow as forums are created but never shrinks
diff --git a/common/counters/posts.go b/common/counters/posts.go
new file mode 100644
index 00000000..c4a8ae45
--- /dev/null
+++ b/common/counters/posts.go
@@ -0,0 +1,58 @@
+package counters
+
+import (
+ "database/sql"
+ "sync/atomic"
+
+ ".."
+ "../../query_gen/lib"
+)
+
+var PostCounter *DefaultPostCounter
+
+type DefaultPostCounter struct {
+ buckets [2]int64
+ currentBucket int64
+
+ insert *sql.Stmt
+}
+
+func NewPostCounter() (*DefaultPostCounter, error) {
+ acc := qgen.Builder.Accumulator()
+ counter := &DefaultPostCounter{
+ currentBucket: 0,
+ insert: acc.Insert("postchunks").Columns("count, createdAt").Fields("?,UTC_TIMESTAMP()").Prepare(),
+ }
+ common.AddScheduledFifteenMinuteTask(counter.Tick)
+ //common.AddScheduledSecondTask(counter.Tick)
+ common.AddShutdownTask(counter.Tick)
+ return counter, acc.FirstError()
+}
+
+func (counter *DefaultPostCounter) Tick() (err error) {
+ var oldBucket = counter.currentBucket
+ var nextBucket int64 // 0
+ if counter.currentBucket == 0 {
+ nextBucket = 1
+ }
+ atomic.AddInt64(&counter.buckets[oldBucket], counter.buckets[nextBucket])
+ atomic.StoreInt64(&counter.buckets[nextBucket], 0)
+ atomic.StoreInt64(&counter.currentBucket, nextBucket)
+
+ var previousViewChunk = counter.buckets[oldBucket]
+ atomic.AddInt64(&counter.buckets[oldBucket], -previousViewChunk)
+ return counter.insertChunk(previousViewChunk)
+}
+
+func (counter *DefaultPostCounter) Bump() {
+ atomic.AddInt64(&counter.buckets[counter.currentBucket], 1)
+}
+
+func (counter *DefaultPostCounter) insertChunk(count int64) error {
+ if count == 0 {
+ return nil
+ }
+ common.DebugLogf("Inserting a postchunk with a count of %d", count)
+ _, err := counter.insert.Exec(count)
+ return err
+}
diff --git a/common/requests.go b/common/counters/referrers.go
similarity index 91%
rename from common/requests.go
rename to common/counters/referrers.go
index 52ac3bbe..f9c7d5b6 100644
--- a/common/requests.go
+++ b/common/counters/referrers.go
@@ -1,11 +1,12 @@
-package common
+package counters
import (
"database/sql"
"sync"
"sync/atomic"
- "../query_gen/lib"
+ ".."
+ "../../query_gen/lib"
)
var ReferrerTracker *DefaultReferrerTracker
@@ -35,9 +36,9 @@ func NewDefaultReferrerTracker() (*DefaultReferrerTracker, error) {
even: make(map[string]*ReferrerItem),
insert: acc.Insert("viewchunks_referrers").Columns("count, createdAt, domain").Fields("?,UTC_TIMESTAMP(),?").Prepare(), // TODO: Do something more efficient than doing a query for each referrer
}
- AddScheduledFifteenMinuteTask(refTracker.Tick)
- //AddScheduledSecondTask(refTracker.Tick)
- AddShutdownTask(refTracker.Tick)
+ common.AddScheduledFifteenMinuteTask(refTracker.Tick)
+ //common.AddScheduledSecondTask(refTracker.Tick)
+ common.AddShutdownTask(refTracker.Tick)
return refTracker, acc.FirstError()
}
@@ -92,7 +93,7 @@ func (ref *DefaultReferrerTracker) insertChunk(referrer string, count int64) err
if count == 0 {
return nil
}
- debugDetailf("Inserting a viewchunk with a count of %d for referrer %s", count, referrer)
+ common.DebugDetailf("Inserting a viewchunk with a count of %d for referrer %s", count, referrer)
_, err := ref.insert.Exec(count, referrer)
return err
}
diff --git a/common/counters/requests.go b/common/counters/requests.go
new file mode 100644
index 00000000..13c2921d
--- /dev/null
+++ b/common/counters/requests.go
@@ -0,0 +1,60 @@
+package counters
+
+import (
+ "database/sql"
+ "sync/atomic"
+
+ ".."
+ "../../query_gen/lib"
+)
+
+// TODO: Rename this?
+var GlobalViewCounter *DefaultViewCounter
+
+// TODO: Rename this and shard it?
+type DefaultViewCounter struct {
+ buckets [2]int64
+ currentBucket int64
+
+ insert *sql.Stmt
+}
+
+func NewGlobalViewCounter() (*DefaultViewCounter, error) {
+ acc := qgen.Builder.Accumulator()
+ counter := &DefaultViewCounter{
+ currentBucket: 0,
+ insert: acc.Insert("viewchunks").Columns("count, createdAt").Fields("?,UTC_TIMESTAMP()").Prepare(),
+ }
+ common.AddScheduledFifteenMinuteTask(counter.Tick) // This is run once every fifteen minutes to match the frequency of the RouteViewCounter
+ //common.AddScheduledSecondTask(counter.Tick)
+ common.AddShutdownTask(counter.Tick)
+ return counter, acc.FirstError()
+}
+
+func (counter *DefaultViewCounter) Tick() (err error) {
+ var oldBucket = counter.currentBucket
+ var nextBucket int64 // 0
+ if counter.currentBucket == 0 {
+ nextBucket = 1
+ }
+ atomic.AddInt64(&counter.buckets[oldBucket], counter.buckets[nextBucket])
+ atomic.StoreInt64(&counter.buckets[nextBucket], 0)
+ atomic.StoreInt64(&counter.currentBucket, nextBucket)
+
+ var previousViewChunk = counter.buckets[oldBucket]
+ atomic.AddInt64(&counter.buckets[oldBucket], -previousViewChunk)
+ return counter.insertChunk(previousViewChunk)
+}
+
+func (counter *DefaultViewCounter) Bump() {
+ atomic.AddInt64(&counter.buckets[counter.currentBucket], 1)
+}
+
+func (counter *DefaultViewCounter) insertChunk(count int64) error {
+ if count == 0 {
+ return nil
+ }
+ common.DebugLogf("Inserting a viewchunk with a count of %d", count)
+ _, err := counter.insert.Exec(count)
+ return err
+}
diff --git a/common/counters/routes.go b/common/counters/routes.go
new file mode 100644
index 00000000..22fe2566
--- /dev/null
+++ b/common/counters/routes.go
@@ -0,0 +1,66 @@
+package counters
+
+import "database/sql"
+import ".."
+import "../../query_gen/lib"
+
+var RouteViewCounter *DefaultRouteViewCounter
+
+// TODO: Make this lockless?
+type DefaultRouteViewCounter struct {
+ routeBuckets []*RWMutexCounterBucket //[RouteID]count
+ insert *sql.Stmt
+}
+
+func NewDefaultRouteViewCounter() (*DefaultRouteViewCounter, error) {
+ acc := qgen.Builder.Accumulator()
+ var routeBuckets = make([]*RWMutexCounterBucket, len(routeMapEnum))
+ for bucketID, _ := range routeBuckets {
+ routeBuckets[bucketID] = &RWMutexCounterBucket{counter: 0}
+ }
+ counter := &DefaultRouteViewCounter{
+ routeBuckets: routeBuckets,
+ insert: acc.Insert("viewchunks").Columns("count, createdAt, route").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
+ }
+ common.AddScheduledFifteenMinuteTask(counter.Tick) // There could be a lot of routes, so we don't want to be running this every second
+ //common.AddScheduledSecondTask(counter.Tick)
+ common.AddShutdownTask(counter.Tick)
+ return counter, acc.FirstError()
+}
+
+func (counter *DefaultRouteViewCounter) Tick() error {
+ for routeID, routeBucket := range counter.routeBuckets {
+ var count int
+ routeBucket.RLock()
+ count = routeBucket.counter
+ routeBucket.counter = 0
+ routeBucket.RUnlock()
+
+ err := counter.insertChunk(count, routeID) // TODO: Bulk insert for speed?
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (counter *DefaultRouteViewCounter) insertChunk(count int, route int) error {
+ if count == 0 {
+ return nil
+ }
+ var routeName = reverseRouteMapEnum[route]
+ common.DebugLogf("Inserting a viewchunk with a count of %d for route %s (%d)", count, routeName, route)
+ _, err := counter.insert.Exec(count, routeName)
+ return err
+}
+
+func (counter *DefaultRouteViewCounter) Bump(route int) {
+ // TODO: Test this check
+ common.DebugDetail("counter.routeBuckets[", route, "]: ", counter.routeBuckets[route])
+ if len(counter.routeBuckets) <= route || route < 0 {
+ return
+ }
+ counter.routeBuckets[route].Lock()
+ counter.routeBuckets[route].counter++
+ counter.routeBuckets[route].Unlock()
+}
diff --git a/common/counters/systems.go b/common/counters/systems.go
new file mode 100644
index 00000000..b24aa364
--- /dev/null
+++ b/common/counters/systems.go
@@ -0,0 +1,65 @@
+package counters
+
+import "database/sql"
+import ".."
+import "../../query_gen/lib"
+
+var OSViewCounter *DefaultOSViewCounter
+
+type DefaultOSViewCounter struct {
+ osBuckets []*RWMutexCounterBucket //[OSID]count
+ insert *sql.Stmt
+}
+
+func NewDefaultOSViewCounter() (*DefaultOSViewCounter, error) {
+ acc := qgen.Builder.Accumulator()
+ var osBuckets = make([]*RWMutexCounterBucket, len(osMapEnum))
+ for bucketID, _ := range osBuckets {
+ osBuckets[bucketID] = &RWMutexCounterBucket{counter: 0}
+ }
+ counter := &DefaultOSViewCounter{
+ osBuckets: osBuckets,
+ insert: acc.Insert("viewchunks_systems").Columns("count, createdAt, system").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
+ }
+ common.AddScheduledFifteenMinuteTask(counter.Tick)
+ //common.AddScheduledSecondTask(counter.Tick)
+ common.AddShutdownTask(counter.Tick)
+ return counter, acc.FirstError()
+}
+
+func (counter *DefaultOSViewCounter) Tick() error {
+ for osID, osBucket := range counter.osBuckets {
+ var count int
+ osBucket.RLock()
+ count = osBucket.counter
+ osBucket.counter = 0 // TODO: Add a SetZero method to reduce the amount of duplicate code between the OS and agent counters?
+ osBucket.RUnlock()
+
+ err := counter.insertChunk(count, osID) // TODO: Bulk insert for speed?
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (counter *DefaultOSViewCounter) insertChunk(count int, os int) error {
+ if count == 0 {
+ return nil
+ }
+ var osName = reverseOSMapEnum[os]
+ common.DebugLogf("Inserting a viewchunk with a count of %d for OS %s (%d)", count, osName, os)
+ _, err := counter.insert.Exec(count, osName)
+ return err
+}
+
+func (counter *DefaultOSViewCounter) Bump(os int) {
+ // TODO: Test this check
+ common.DebugDetail("counter.osBuckets[", os, "]: ", counter.osBuckets[os])
+ if len(counter.osBuckets) <= os || os < 0 {
+ return
+ }
+ counter.osBuckets[os].Lock()
+ counter.osBuckets[os].counter++
+ counter.osBuckets[os].Unlock()
+}
diff --git a/common/counters/topics.go b/common/counters/topics.go
new file mode 100644
index 00000000..3387e01b
--- /dev/null
+++ b/common/counters/topics.go
@@ -0,0 +1,58 @@
+package counters
+
+import (
+ "database/sql"
+ "sync/atomic"
+
+ ".."
+ "../../query_gen/lib"
+)
+
+var TopicCounter *DefaultTopicCounter
+
+type DefaultTopicCounter struct {
+ buckets [2]int64
+ currentBucket int64
+
+ insert *sql.Stmt
+}
+
+func NewTopicCounter() (*DefaultTopicCounter, error) {
+ acc := qgen.Builder.Accumulator()
+ counter := &DefaultTopicCounter{
+ currentBucket: 0,
+ insert: acc.Insert("topicchunks").Columns("count, createdAt").Fields("?,UTC_TIMESTAMP()").Prepare(),
+ }
+ common.AddScheduledFifteenMinuteTask(counter.Tick)
+ //common.AddScheduledSecondTask(counter.Tick)
+ common.AddShutdownTask(counter.Tick)
+ return counter, acc.FirstError()
+}
+
+func (counter *DefaultTopicCounter) Tick() (err error) {
+ var oldBucket = counter.currentBucket
+ var nextBucket int64 // 0
+ if counter.currentBucket == 0 {
+ nextBucket = 1
+ }
+ atomic.AddInt64(&counter.buckets[oldBucket], counter.buckets[nextBucket])
+ atomic.StoreInt64(&counter.buckets[nextBucket], 0)
+ atomic.StoreInt64(&counter.currentBucket, nextBucket)
+
+ var previousViewChunk = counter.buckets[oldBucket]
+ atomic.AddInt64(&counter.buckets[oldBucket], -previousViewChunk)
+ return counter.insertChunk(previousViewChunk)
+}
+
+func (counter *DefaultTopicCounter) Bump() {
+ atomic.AddInt64(&counter.buckets[counter.currentBucket], 1)
+}
+
+func (counter *DefaultTopicCounter) insertChunk(count int64) error {
+ if count == 0 {
+ return nil
+ }
+ common.DebugLogf("Inserting a topicchunk with a count of %d", count)
+ _, err := counter.insert.Exec(count)
+ return err
+}
diff --git a/common/counters/topics_views.go b/common/counters/topics_views.go
new file mode 100644
index 00000000..31555a4d
--- /dev/null
+++ b/common/counters/topics_views.go
@@ -0,0 +1,116 @@
+package counters
+
+import (
+ "database/sql"
+ "sync"
+
+ ".."
+ "../../query_gen/lib"
+)
+
+var TopicViewCounter *DefaultTopicViewCounter
+
+// TODO: Use two odd-even maps for now, and move to something more concurrent later, maybe a sharded map?
+type DefaultTopicViewCounter struct {
+ oddTopics map[int]*RWMutexCounterBucket // map[tid]struct{counter,sync.RWMutex}
+ evenTopics map[int]*RWMutexCounterBucket
+ oddLock sync.RWMutex
+ evenLock sync.RWMutex
+
+ update *sql.Stmt
+}
+
+func NewDefaultTopicViewCounter() (*DefaultTopicViewCounter, error) {
+ acc := qgen.Builder.Accumulator()
+ counter := &DefaultTopicViewCounter{
+ oddTopics: make(map[int]*RWMutexCounterBucket),
+ evenTopics: make(map[int]*RWMutexCounterBucket),
+ update: acc.Update("topics").Set("views = views + ?").Where("tid = ?").Prepare(),
+ }
+ common.AddScheduledFifteenMinuteTask(counter.Tick) // Who knows how many topics we have queued up, we probably don't want this running too frequently
+ //common.AddScheduledSecondTask(counter.Tick)
+ common.AddShutdownTask(counter.Tick)
+ return counter, acc.FirstError()
+}
+
+func (counter *DefaultTopicViewCounter) Tick() error {
+ counter.oddLock.RLock()
+ oddTopics := counter.oddTopics
+ counter.oddLock.RUnlock()
+ for topicID, topic := range oddTopics {
+ var count int
+ topic.RLock()
+ count = topic.counter
+ topic.RUnlock()
+ // TODO: Only delete the bucket when it's zero to avoid hitting popular topics?
+ counter.oddLock.Lock()
+ delete(counter.oddTopics, topicID)
+ counter.oddLock.Unlock()
+ err := counter.insertChunk(count, topicID)
+ if err != nil {
+ return err
+ }
+ }
+
+ counter.evenLock.RLock()
+ evenTopics := counter.evenTopics
+ counter.evenLock.RUnlock()
+ for topicID, topic := range evenTopics {
+ var count int
+ topic.RLock()
+ count = topic.counter
+ topic.RUnlock()
+ // TODO: Only delete the bucket when it's zero to avoid hitting popular topics?
+ counter.evenLock.Lock()
+ delete(counter.evenTopics, topicID)
+ counter.evenLock.Unlock()
+ err := counter.insertChunk(count, topicID)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// TODO: Optimise this further. E.g. Using IN() on every one view topic. Rinse and repeat for two views, three views, four views and five views.
+func (counter *DefaultTopicViewCounter) insertChunk(count int, topicID int) error {
+ if count == 0 {
+ return nil
+ }
+ common.DebugLogf("Inserting %d views into topic %d", count, topicID)
+ _, err := counter.update.Exec(count, topicID)
+ return err
+}
+
+func (counter *DefaultTopicViewCounter) Bump(topicID int) {
+ // Is the ID even?
+ if topicID%2 == 0 {
+ counter.evenLock.RLock()
+ topic, ok := counter.evenTopics[topicID]
+ counter.evenLock.RUnlock()
+ if ok {
+ topic.Lock()
+ topic.counter++
+ topic.Unlock()
+ } else {
+ counter.evenLock.Lock()
+ counter.evenTopics[topicID] = &RWMutexCounterBucket{counter: 1}
+ counter.evenLock.Unlock()
+ }
+ return
+ }
+
+ counter.oddLock.RLock()
+ topic, ok := counter.oddTopics[topicID]
+ counter.oddLock.RUnlock()
+ if ok {
+ topic.Lock()
+ topic.counter++
+ topic.Unlock()
+ } else {
+ counter.oddLock.Lock()
+ counter.oddTopics[topicID] = &RWMutexCounterBucket{counter: 1}
+ counter.oddLock.Unlock()
+ }
+}
diff --git a/common/email.go b/common/email.go
index a6bf7de0..bd69d79f 100644
--- a/common/email.go
+++ b/common/email.go
@@ -29,6 +29,7 @@ func SendValidationEmail(username string, email string, token string) bool {
// TODO: Add support for TLS
func SendEmail(email string, subject string, msg string) bool {
// This hook is useful for plugin_sendmail or for testing tools. Possibly to hook it into some sort of mail server?
+ // TODO: Abstract this
if Vhooks["email_send_intercept"] != nil {
return Vhooks["email_send_intercept"](email, subject, msg).(bool)
}
diff --git a/common/errors.go b/common/errors.go
index 88896abb..245ac182 100644
--- a/common/errors.go
+++ b/common/errors.go
@@ -238,10 +238,8 @@ func LoginRequiredJS(w http.ResponseWriter, r *http.Request, user User) RouteErr
func SecurityError(w http.ResponseWriter, r *http.Request, user User) RouteError {
w.WriteHeader(403)
pi := Page{"Security Error", user, DefaultHeaderVar(), tList, "There was a security issue with your request."}
- if PreRenderHooks["pre_render_security_error"] != nil {
- if RunPreRenderHook("pre_render_security_error", w, r, &user, &pi) {
- return nil
- }
+ if RunPreRenderHook("pre_render_security_error", w, r, &user, &pi) {
+ return nil
}
err := Templates.ExecuteTemplate(w, "error.html", pi)
if err != nil {
@@ -253,22 +251,28 @@ func SecurityError(w http.ResponseWriter, r *http.Request, user User) RouteError
// NotFound is used when the requested page doesn't exist
// ? - Add a JSQ and JS version of this?
// ? - Add a user parameter?
-func NotFound(w http.ResponseWriter, r *http.Request) RouteError {
- return CustomError("The requested page doesn't exist.", 404, "Not Found", w, r, GuestUser)
+func NotFound(w http.ResponseWriter, r *http.Request, headerVars *HeaderVars) RouteError {
+ return CustomError("The requested page doesn't exist.", 404, "Not Found", w, r, headerVars, GuestUser)
}
// CustomError lets us make custom error types which aren't covered by the generic functions above
-func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, user User) RouteError {
+func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, headerVars *HeaderVars, user User) RouteError {
+ if headerVars == nil {
+ headerVars = DefaultHeaderVar()
+ }
w.WriteHeader(errcode)
- pi := Page{errtitle, user, DefaultHeaderVar(), tList, errmsg}
+ pi := Page{errtitle, user, headerVars, tList, errmsg}
handleErrorTemplate(w, r, pi)
return HandledRouteError()
}
// CustomErrorJSQ is a version of CustomError which lets us handle both JSON and regular pages depending on how it's being accessed
-func CustomErrorJSQ(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, user User, isJs bool) RouteError {
+func CustomErrorJSQ(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, headerVars *HeaderVars, user User, isJs bool) RouteError {
if !isJs {
- return CustomError(errmsg, errcode, errtitle, w, r, user)
+ if headerVars == nil {
+ headerVars = DefaultHeaderVar()
+ }
+ return CustomError(errmsg, errcode, errtitle, w, r, headerVars, user)
}
return CustomErrorJS(errmsg, errcode, w, r, user)
}
@@ -283,10 +287,8 @@ func CustomErrorJS(errmsg string, errcode int, w http.ResponseWriter, r *http.Re
func handleErrorTemplate(w http.ResponseWriter, r *http.Request, pi Page) {
//LogError(errors.New("error happened"))
// TODO: What to do about this hook?
- if PreRenderHooks["pre_render_error"] != nil {
- if RunPreRenderHook("pre_render_error", w, r, &pi.CurrentUser, &pi) {
- return
- }
+ if RunPreRenderHook("pre_render_error", w, r, &pi.CurrentUser, &pi) {
+ return
}
err := Templates.ExecuteTemplate(w, "error.html", pi)
if err != nil {
diff --git a/common/files.go b/common/files.go
index 44e68586..a8a37a5f 100644
--- a/common/files.go
+++ b/common/files.go
@@ -51,7 +51,7 @@ func (list SFileList) Init() error {
list.Set("/static/"+path, SFile{data, gzipData, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)})
- debugLogf("Added the '%s' static file.", path)
+ DebugLogf("Added the '%s' static file.", path)
return nil
})
}
@@ -76,7 +76,7 @@ func (list SFileList) Add(path string, prefix string) error {
list.Set("/static"+path, SFile{data, gzipData, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)})
- debugLogf("Added the '%s' static file", path)
+ DebugLogf("Added the '%s' static file", path)
return nil
}
diff --git a/common/forum_perms_store.go b/common/forum_perms_store.go
index 7f49653f..f6f48713 100644
--- a/common/forum_perms_store.go
+++ b/common/forum_perms_store.go
@@ -3,7 +3,6 @@ package common
import (
"database/sql"
"encoding/json"
- "log"
"sync"
"../query_gen/lib"
@@ -46,15 +45,15 @@ func (fps *MemoryForumPermsStore) Init() error {
if err != nil {
return err
}
- debugDetail("fids: ", fids)
+ DebugDetail("fids: ", fids)
rows, err := fps.get.Query()
if err != nil {
return err
}
defer rows.Close()
- debugLog("Adding the forum permissions")
- debugDetail("forumPerms[gid][fid]")
+ DebugLog("Adding the forum permissions")
+ DebugDetail("forumPerms[gid][fid]")
forumPerms = make(map[int]map[int]*ForumPerms)
for rows.Next() {
@@ -74,9 +73,9 @@ func (fps *MemoryForumPermsStore) Init() error {
forumPerms[gid] = make(map[int]*ForumPerms)
}
- debugDetail("gid: ", gid)
- debugDetail("fid: ", fid)
- debugDetailf("perms: %+v\n", pperms)
+ DebugDetail("gid: ", gid)
+ DebugDetail("fid: ", fid)
+ DebugDetailf("perms: %+v\n", pperms)
forumPerms[gid][fid] = pperms
}
@@ -84,7 +83,7 @@ func (fps *MemoryForumPermsStore) Init() error {
}
func (fps *MemoryForumPermsStore) parseForumPerm(perms []byte) (pperms *ForumPerms, err error) {
- debugDetail("perms: ", string(perms))
+ DebugDetail("perms: ", string(perms))
pperms = BlankForumPerms()
err = json.Unmarshal(perms, &pperms)
pperms.ExtData = make(map[string]bool)
@@ -96,7 +95,7 @@ func (fps *MemoryForumPermsStore) parseForumPerm(perms []byte) (pperms *ForumPer
func (fps *MemoryForumPermsStore) Reload(fid int) error {
fps.updateMutex.Lock()
defer fps.updateMutex.Unlock()
- debugLogf("Reloading the forum permissions for forum #%d", fid)
+ DebugLogf("Reloading the forum permissions for forum #%d", fid)
fids, err := Forums.GetAllIDs()
if err != nil {
return err
@@ -159,22 +158,20 @@ func (fps *MemoryForumPermsStore) cascadePermSetToGroups(forumPerms map[int]map[
}
for _, group := range groups {
- debugLogf("Updating the forum permissions for Group #%d", group.ID)
+ DebugLogf("Updating the forum permissions for Group #%d", group.ID)
group.Forums = []*ForumPerms{BlankForumPerms()}
group.CanSee = []int{}
fps.cascadePermSetToGroup(forumPerms, group, fids)
- if Dev.SuperDebug {
- log.Printf("group.CanSee (length %d): %+v \n", len(group.CanSee), group.CanSee)
- log.Printf("group.Forums (length %d): %+v\n", len(group.Forums), group.Forums)
- }
+ DebugDetailf("group.CanSee (length %d): %+v \n", len(group.CanSee), group.CanSee)
+ DebugDetailf("group.Forums (length %d): %+v\n", len(group.Forums), group.Forums)
}
return nil
}
func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[int]*ForumPerms, group *Group, fids []int) {
for _, fid := range fids {
- debugDetailf("Forum #%+v\n", fid)
+ DebugDetailf("Forum #%+v\n", fid)
forumPerm, ok := forumPerms[group.ID][fid]
if ok {
//log.Printf("Overriding permissions for forum #%d",fid)
@@ -192,9 +189,9 @@ func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[i
group.CanSee = append(group.CanSee, fid)
}
- debugDetail("group.ID: ", group.ID)
- debugDetailf("forumPerm: %+v\n", forumPerm)
- debugDetail("group.CanSee: ", group.CanSee)
+ DebugDetail("group.ID: ", group.ID)
+ DebugDetailf("forumPerm: %+v\n", forumPerm)
+ DebugDetail("group.CanSee: ", group.CanSee)
}
}
diff --git a/common/forum_store.go b/common/forum_store.go
index fb75e931..0d428374 100644
--- a/common/forum_store.go
+++ b/common/forum_store.go
@@ -109,7 +109,7 @@ func (mfs *MemoryForumStore) LoadForums() error {
}
if forum.Name == "" {
- debugLog("Adding a placeholder forum")
+ DebugLog("Adding a placeholder forum")
} else {
log.Printf("Adding the '%s' forum", forum.Name)
}
diff --git a/common/group_store.go b/common/group_store.go
index 06f1aac7..1ae74aaa 100644
--- a/common/group_store.go
+++ b/common/group_store.go
@@ -88,7 +88,7 @@ func (mgs *MemoryGroupStore) LoadGroups() error {
}
mgs.groupCount = i
- debugLog("Binding the Not Loggedin Group")
+ DebugLog("Binding the Not Loggedin Group")
GuestPerms = mgs.dirtyGetUnsafe(6).Perms
return nil
}
@@ -162,9 +162,7 @@ func (mgs *MemoryGroupStore) initGroup(group *Group) error {
log.Print("bad group perms: ", group.PermissionsText)
return err
}
- if Dev.DebugMode {
- log.Printf(group.Name+": %+v\n", group.Perms)
- }
+ DebugLogf(group.Name+": %+v\n", group.Perms)
err = json.Unmarshal(group.PluginPermsText, &group.PluginPerms)
if err != nil {
@@ -172,7 +170,7 @@ func (mgs *MemoryGroupStore) initGroup(group *Group) error {
log.Print("bad group plugin perms: ", group.PluginPermsText)
return err
}
- debugLogf(group.Name+": %+v\n", group.PluginPerms)
+ DebugLogf(group.Name+": %+v\n", group.PluginPerms)
//group.Perms.ExtData = make(map[string]bool)
// TODO: Can we optimise the bit where this cascades down to the user now?
diff --git a/common/parser.go b/common/parser.go
index e4c33137..1eb7b87c 100644
--- a/common/parser.go
+++ b/common/parser.go
@@ -173,9 +173,7 @@ func PreparseMessage(msg string) string {
msg = strings.Replace(msg, "
", "", -1)
msg = strings.Replace(msg, "
", "\n\n", -1)
msg = strings.TrimSpace(msg) // There are a few useful cases for having spaces, but I'd like to stop the WYSIWYG from inserting random lines here and there
- if Sshooks["preparse_preassign"] != nil {
- msg = RunSshook("preparse_preassign", msg)
- }
+ msg = RunSshook("preparse_preassign", msg)
msg = html.EscapeString(msg)
msg = strings.Replace(msg, " ", "", -1)
@@ -573,9 +571,7 @@ func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/)
//log.Print("msg",`"`+msg+`"`)
msg = strings.Replace(msg, "\n", "
", -1)
- if Sshooks["parse_assign"] != nil {
- msg = RunSshook("parse_assign", msg)
- }
+ msg = RunSshook("parse_assign", msg)
return msg
}
diff --git a/common/permissions.go b/common/permissions.go
index d7064ed8..2fde3313 100644
--- a/common/permissions.go
+++ b/common/permissions.go
@@ -136,8 +136,8 @@ func init() {
}
GuestUser.Perms = GuestPerms
- debugLogf("Guest Perms: %+v\n", GuestPerms)
- debugLogf("All Perms: %+v\n", AllPerms)
+ DebugLogf("Guest Perms: %+v\n", GuestPerms)
+ DebugLogf("All Perms: %+v\n", AllPerms)
}
func StripInvalidGroupForumPreset(preset string) string {
diff --git a/common/phrases.go b/common/phrases.go
index fc947a3c..558aa5ea 100644
--- a/common/phrases.go
+++ b/common/phrases.go
@@ -65,9 +65,7 @@ func InitPhrases() error {
var ext = filepath.Ext("/langs/" + path)
if ext != ".json" {
- if Dev.DebugMode {
- log.Printf("Found a '%s' in /langs/", ext)
- }
+ log.Printf("Found a '%s' in /langs/", ext)
return nil
}
diff --git a/common/poll_store.go b/common/poll_store.go
index d5ac3f3e..2e2a3985 100644
--- a/common/poll_store.go
+++ b/common/poll_store.go
@@ -189,6 +189,7 @@ func (store *DefaultPollStore) BulkGetMap(ids []int) (list map[int]*Poll, err er
// We probably don't need this, but it might be useful in case of bugs in BulkCascadeGetMap
if sidList == "" {
+ // TODO: Bulk log this
if Dev.DebugMode {
log.Print("This data is sampled later in the BulkCascadeGetMap function, so it might miss the cached IDs")
log.Print("idCount", idCount)
diff --git a/common/routes_common.go b/common/routes_common.go
index 47a17e49..ace95c1f 100644
--- a/common/routes_common.go
+++ b/common/routes_common.go
@@ -52,7 +52,7 @@ func forumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fid int)
return headerVars, rerr
}
if !Forums.Exists(fid) {
- return headerVars, NotFound(w, r)
+ return headerVars, NotFound(w, r, headerVars)
}
if VhookSkippable["forum_check_pre_perms"] != nil {
@@ -353,7 +353,7 @@ func HandleUploadRoute(w http.ResponseWriter, r *http.Request, user User, maxFil
// TODO: Reuse this code more
if r.ContentLength > int64(maxFileSize) {
size, unit := ConvertByteUnit(float64(maxFileSize))
- return CustomError("Your upload is too big. Your files need to be smaller than "+strconv.Itoa(int(size))+unit+".", http.StatusExpectationFailed, "Error", w, r, user)
+ return CustomError("Your upload is too big. Your files need to be smaller than "+strconv.Itoa(int(size))+unit+".", http.StatusExpectationFailed, "Error", w, r, nil, user)
}
r.Body = http.MaxBytesReader(w, r.Body, int64(maxFileSize))
diff --git a/common/themes.go b/common/themes.go
index b7488341..c8690c44 100644
--- a/common/themes.go
+++ b/common/themes.go
@@ -169,7 +169,7 @@ func InitThemes() error {
}
if theme.FullImage != "" {
- debugLog("Adding theme image")
+ DebugLog("Adding theme image")
err = StaticFiles.Add("./themes/"+themeName+"/"+theme.FullImage, "./themes/"+themeName)
if err != nil {
return err
@@ -206,7 +206,7 @@ func (theme *Theme) LoadStaticFiles() error {
func (theme *Theme) AddThemeStaticFiles() error {
// TODO: Use a function instead of a closure to make this more testable? What about a function call inside the closure to take the theme variable into account?
return filepath.Walk("./themes/"+theme.Name+"/public", func(path string, f os.FileInfo, err error) error {
- debugLog("Attempting to add static file '" + path + "' for default theme '" + theme.Name + "'")
+ DebugLog("Attempting to add static file '" + path + "' for default theme '" + theme.Name + "'")
if err != nil {
return err
}
@@ -236,7 +236,7 @@ func (theme *Theme) AddThemeStaticFiles() error {
gzipData := compressBytesGzip(data)
StaticFiles.Set("/static/"+theme.Name+path, SFile{data, gzipData, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)})
- debugLog("Added the '/" + theme.Name + path + "' static file for theme " + theme.Name + ".")
+ DebugLog("Added the '/" + theme.Name + path + "' static file for theme " + theme.Name + ".")
return nil
})
}
diff --git a/common/user_store.go b/common/user_store.go
index 2fd8a514..64a7fae5 100644
--- a/common/user_store.go
+++ b/common/user_store.go
@@ -155,6 +155,7 @@ func (mus *DefaultUserStore) BulkGetMap(ids []int) (list map[int]*User, err erro
// We probably don't need this, but it might be useful in case of bugs in BulkCascadeGetMap
if sidList == "" {
+ // TODO: Bulk log this
if Dev.DebugMode {
log.Print("This data is sampled later in the BulkCascadeGetMap function, so it might miss the cached IDs")
log.Print("idCount", idCount)
diff --git a/common/widgets.go b/common/widgets.go
index 143ff407..8e547d6a 100644
--- a/common/widgets.go
+++ b/common/widgets.go
@@ -6,7 +6,6 @@ import (
"database/sql"
"encoding/json"
"html/template"
- "log"
"strings"
"sync"
@@ -215,11 +214,9 @@ func InitWidgets() error {
Docks.Footer = footerWidgets
widgetUpdateMutex.Unlock()
- if Dev.SuperDebug {
- log.Print("Docks.LeftSidebar", Docks.LeftSidebar)
- log.Print("Docks.RightSidebar", Docks.RightSidebar)
- log.Print("Docks.Footer", Docks.Footer)
- }
+ DebugLog("Docks.LeftSidebar", Docks.LeftSidebar)
+ DebugLog("Docks.RightSidebar", Docks.RightSidebar)
+ DebugLog("Docks.Footer", Docks.Footer)
return nil
}
diff --git a/extend/guilds/lib/guilds.go b/extend/guilds/lib/guilds.go
index 78035934..f7b66c34 100644
--- a/extend/guilds/lib/guilds.go
+++ b/extend/guilds/lib/guilds.go
@@ -215,8 +215,9 @@ func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user common.User) c
if err != nil {
return common.LocalError("Bad guild", w, r, user)
}
+ // TODO: Build and pass headerVars
if !guildItem.Active {
- return common.NotFound(w, r)
+ return common.NotFound(w, r, nil)
}
return nil
@@ -357,11 +358,9 @@ func RouteMemberList(w http.ResponseWriter, r *http.Request, user common.User) c
pi := MemberListPage{"Guild Member List", user, headerVars, guildMembers, guildItem, 0, 0}
// A plugin with plugins. Pluginception!
- if common.PreRenderHooks["pre_render_guilds_member_list"] != nil {
- if common.RunPreRenderHook("pre_render_guilds_member_list", w, r, &user, &pi) {
+ if common.RunPreRenderHook("pre_render_guilds_member_list", w, r, &user, &pi) {
return nil
}
- }
err = common.RunThemeTemplate(headerVars.Theme.Name, "guilds_member_list", pi, w)
if err != nil {
return common.InternalError(err, w, r)
@@ -446,7 +445,7 @@ func ForumCheck(args ...interface{}) (skip bool, rerr common.RouteError) {
return true, common.InternalError(errors.New("Unable to find the parent group for a forum"), w, r)
}
if !guildItem.Active {
- return true, common.NotFound(w, r)
+ return true, common.NotFound(w, r, nil) // TODO: Can we pull headerVars out of args?
}
r = r.WithContext(context.WithValue(r.Context(), "guilds_current_group", guildItem))
}
diff --git a/gen_mssql.go b/gen_mssql.go
index 805df442..be837151 100644
--- a/gen_mssql.go
+++ b/gen_mssql.go
@@ -64,9 +64,7 @@ type Stmts struct {
// nolint
func _gen_mssql() (err error) {
- if common.Dev.DebugMode {
- log.Print("Building the generated statements")
- }
+ common.DebugLog("Building the generated statements")
log.Print("Preparing getPassword statement.")
stmts.getPassword, err = db.Prepare("SELECT [password],[salt] FROM [users] WHERE [uid] = ?1")
diff --git a/gen_mysql.go b/gen_mysql.go
index 2d2ed881..b5be4b99 100644
--- a/gen_mysql.go
+++ b/gen_mysql.go
@@ -66,9 +66,7 @@ type Stmts struct {
// nolint
func _gen_mysql() (err error) {
- if common.Dev.DebugMode {
- log.Print("Building the generated statements")
- }
+ common.DebugLog("Building the generated statements")
log.Print("Preparing getPassword statement.")
stmts.getPassword, err = db.Prepare("SELECT `password`,`salt` FROM `users` WHERE `uid` = ?")
diff --git a/gen_pgsql.go b/gen_pgsql.go
index 2e42523c..8f19d5e7 100644
--- a/gen_pgsql.go
+++ b/gen_pgsql.go
@@ -34,9 +34,7 @@ type Stmts struct {
// nolint
func _gen_pgsql() (err error) {
- if common.Dev.DebugMode {
- log.Print("Building the generated statements")
- }
+ common.DebugLog("Building the generated statements")
log.Print("Preparing editReply statement.")
stmts.editReply, err = db.Prepare("UPDATE `replies` SET `content` = ?,`parsed_content` = ? WHERE `rid` = ?")
diff --git a/gen_router.go b/gen_router.go
index 03dab123..4dec4f8a 100644
--- a/gen_router.go
+++ b/gen_router.go
@@ -10,6 +10,7 @@ import (
"net/http"
"./common"
+ "./common/counters"
"./routes"
)
@@ -113,6 +114,7 @@ var RouteMap = map[string]interface{}{
"routes.AccountRegisterSubmit": routes.AccountRegisterSubmit,
"routeDynamic": routeDynamic,
"routeUploads": routeUploads,
+ "routes.StaticFile": routes.StaticFile,
"BadRoute": BadRoute,
}
@@ -215,7 +217,8 @@ var routeMapEnum = map[string]int{
"routes.AccountRegisterSubmit": 94,
"routeDynamic": 95,
"routeUploads": 96,
- "BadRoute": 97,
+ "routes.StaticFile": 97,
+ "BadRoute": 98,
}
var reverseRouteMapEnum = map[int]string{
0: "routeAPI",
@@ -315,7 +318,8 @@ var reverseRouteMapEnum = map[int]string{
94: "routes.AccountRegisterSubmit",
95: "routeDynamic",
96: "routeUploads",
- 97: "BadRoute",
+ 97: "routes.StaticFile",
+ 98: "BadRoute",
}
var osMapEnum = map[string]int{
"unknown": 0,
@@ -428,12 +432,12 @@ var markToAgent = map[string]string{
// TODO: Stop spilling these into the package scope?
func init() {
- common.SetRouteMapEnum(routeMapEnum)
- common.SetReverseRouteMapEnum(reverseRouteMapEnum)
- common.SetAgentMapEnum(agentMapEnum)
- common.SetReverseAgentMapEnum(reverseAgentMapEnum)
- common.SetOSMapEnum(osMapEnum)
- common.SetReverseOSMapEnum(reverseOSMapEnum)
+ counters.SetRouteMapEnum(routeMapEnum)
+ counters.SetReverseRouteMapEnum(reverseRouteMapEnum)
+ counters.SetAgentMapEnum(agentMapEnum)
+ counters.SetReverseAgentMapEnum(reverseAgentMapEnum)
+ counters.SetOSMapEnum(osMapEnum)
+ counters.SetReverseOSMapEnum(reverseOSMapEnum)
}
type GenRouter struct {
@@ -500,7 +504,7 @@ func (router *GenRouter) DumpRequest(req *http.Request) {
func (router *GenRouter) SuspiciousRequest(req *http.Request) {
log.Print("Suspicious Request")
router.DumpRequest(req)
- common.AgentViewCounter.Bump(26)
+ counters.AgentViewCounter.Bump(26)
}
// TODO: Pass the default route or config struct to the router rather than accessing it via a package global
@@ -533,7 +537,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.Write([]byte(""))
log.Print("Malformed Request")
router.DumpRequest(req)
- common.AgentViewCounter.Bump(25)
+ counters.AgentViewCounter.Bump(25)
return
}
@@ -563,8 +567,11 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
log.Print("before routes.StaticFile")
router.DumpRequest(req)
}
+ // Increment the request counter
+ counters.GlobalViewCounter.Bump()
if prefix == "/static" {
+ counters.RouteViewCounter.Bump(97)
req.URL.Path += extraData
routes.StaticFile(w, req)
return
@@ -573,15 +580,12 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
log.Print("before PreRoute")
}
- // Increment the global view counter
- common.GlobalViewCounter.Bump()
-
// Track the user agents. Unfortunately, everyone pretends to be Mozilla, so this'll be a little less efficient than I would like.
// TODO: Add a setting to disable this?
// TODO: Use a more efficient detector instead of smashing every possible combination in
ua := strings.TrimSpace(strings.Replace(strings.TrimPrefix(req.UserAgent(),"Mozilla/5.0 ")," Safari/537.36","",-1)) // Noise, no one's going to be running this and it would require some sort of agent ranking system to determine which identifier should be prioritised over another
if ua == "" {
- common.AgentViewCounter.Bump(24)
+ counters.AgentViewCounter.Bump(24)
if common.Dev.DebugMode {
log.Print("Blank UA: ", req.UserAgent())
router.DumpRequest(req)
@@ -681,15 +685,15 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
if agent == "" {
- common.AgentViewCounter.Bump(0)
+ counters.AgentViewCounter.Bump(0)
if common.Dev.DebugMode {
log.Print("Unknown UA: ", req.UserAgent())
router.DumpRequest(req)
}
} else {
- common.AgentViewCounter.Bump(agentMapEnum[agent])
+ counters.AgentViewCounter.Bump(agentMapEnum[agent])
}
- common.OSViewCounter.Bump(osMapEnum[os])
+ counters.OSViewCounter.Bump(osMapEnum[os])
}
referrer := req.Header.Get("Referer") // Check the 'referrer' header too? :P
@@ -699,7 +703,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
referrer = strings.Split(referrer,"/")[0]
portless := strings.Split(referrer,":")[0]
if portless != "localhost" && portless != "127.0.0.1" && portless != common.Site.Host {
- common.ReferrerTracker.Bump(referrer)
+ counters.ReferrerTracker.Bump(referrer)
}
}
@@ -716,31 +720,31 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
var err common.RouteError
switch(prefix) {
case "/api":
- common.RouteViewCounter.Bump(0)
+ counters.RouteViewCounter.Bump(0)
err = routeAPI(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
}
case "/overview":
- common.RouteViewCounter.Bump(1)
+ counters.RouteViewCounter.Bump(1)
err = routes.Overview(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
}
case "/pages":
- common.RouteViewCounter.Bump(2)
+ counters.RouteViewCounter.Bump(2)
err = routes.CustomPage(w,req,user,extraData)
if err != nil {
router.handleError(err,w,req,user)
}
case "/forums":
- common.RouteViewCounter.Bump(3)
+ counters.RouteViewCounter.Bump(3)
err = routeForums(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
}
case "/forum":
- common.RouteViewCounter.Bump(4)
+ counters.RouteViewCounter.Bump(4)
err = routeForum(w,req,user,extraData)
if err != nil {
router.handleError(err,w,req,user)
@@ -752,7 +756,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(5)
+ counters.RouteViewCounter.Bump(5)
err = routeChangeTheme(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
@@ -764,14 +768,14 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(6)
+ counters.RouteViewCounter.Bump(6)
err = routeShowAttachment(w,req,user,extraData)
if err != nil {
router.handleError(err,w,req,user)
}
case "/ws":
req.URL.Path += extraData
- common.RouteViewCounter.Bump(7)
+ counters.RouteViewCounter.Bump(7)
err = routeWebsockets(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
@@ -797,7 +801,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(8)
+ counters.RouteViewCounter.Bump(8)
err = routeReportSubmit(w,req,user,extraData)
}
if err != nil {
@@ -812,10 +816,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(9)
+ counters.RouteViewCounter.Bump(9)
err = routes.CreateTopic(w,req,user,extraData)
default:
- common.RouteViewCounter.Bump(10)
+ counters.RouteViewCounter.Bump(10)
err = routes.TopicList(w,req,user)
}
if err != nil {
@@ -830,7 +834,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
switch(req.URL.Path) {
case "/panel/forums/":
- common.RouteViewCounter.Bump(11)
+ counters.RouteViewCounter.Bump(11)
err = routePanelForums(w,req,user)
case "/panel/forums/create/":
err = common.NoSessionMismatch(w,req,user)
@@ -839,7 +843,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(12)
+ counters.RouteViewCounter.Bump(12)
err = routePanelForumsCreateSubmit(w,req,user)
case "/panel/forums/delete/":
err = common.NoSessionMismatch(w,req,user)
@@ -848,7 +852,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(13)
+ counters.RouteViewCounter.Bump(13)
err = routePanelForumsDelete(w,req,user,extraData)
case "/panel/forums/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -857,10 +861,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(14)
+ counters.RouteViewCounter.Bump(14)
err = routePanelForumsDeleteSubmit(w,req,user,extraData)
case "/panel/forums/edit/":
- common.RouteViewCounter.Bump(15)
+ counters.RouteViewCounter.Bump(15)
err = routePanelForumsEdit(w,req,user,extraData)
case "/panel/forums/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -869,7 +873,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(16)
+ counters.RouteViewCounter.Bump(16)
err = routePanelForumsEditSubmit(w,req,user,extraData)
case "/panel/forums/edit/perms/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -878,10 +882,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(17)
+ counters.RouteViewCounter.Bump(17)
err = routePanelForumsEditPermsSubmit(w,req,user,extraData)
case "/panel/forums/edit/perms/":
- common.RouteViewCounter.Bump(18)
+ counters.RouteViewCounter.Bump(18)
err = routePanelForumsEditPermsAdvance(w,req,user,extraData)
case "/panel/forums/edit/perms/adv/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -890,13 +894,13 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(19)
+ counters.RouteViewCounter.Bump(19)
err = routePanelForumsEditPermsAdvanceSubmit(w,req,user,extraData)
case "/panel/settings/":
- common.RouteViewCounter.Bump(20)
+ counters.RouteViewCounter.Bump(20)
err = routePanelSettings(w,req,user)
case "/panel/settings/edit/":
- common.RouteViewCounter.Bump(21)
+ counters.RouteViewCounter.Bump(21)
err = routePanelSettingEdit(w,req,user,extraData)
case "/panel/settings/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -905,10 +909,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(22)
+ counters.RouteViewCounter.Bump(22)
err = routePanelSettingEditSubmit(w,req,user,extraData)
case "/panel/settings/word-filters/":
- common.RouteViewCounter.Bump(23)
+ counters.RouteViewCounter.Bump(23)
err = routePanelWordFilters(w,req,user)
case "/panel/settings/word-filters/create/":
err = common.NoSessionMismatch(w,req,user)
@@ -917,10 +921,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(24)
+ counters.RouteViewCounter.Bump(24)
err = routePanelWordFiltersCreateSubmit(w,req,user)
case "/panel/settings/word-filters/edit/":
- common.RouteViewCounter.Bump(25)
+ counters.RouteViewCounter.Bump(25)
err = routePanelWordFiltersEdit(w,req,user,extraData)
case "/panel/settings/word-filters/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -929,7 +933,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(26)
+ counters.RouteViewCounter.Bump(26)
err = routePanelWordFiltersEditSubmit(w,req,user,extraData)
case "/panel/settings/word-filters/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -938,10 +942,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(27)
+ counters.RouteViewCounter.Bump(27)
err = routePanelWordFiltersDeleteSubmit(w,req,user,extraData)
case "/panel/themes/":
- common.RouteViewCounter.Bump(28)
+ counters.RouteViewCounter.Bump(28)
err = routePanelThemes(w,req,user)
case "/panel/themes/default/":
err = common.NoSessionMismatch(w,req,user)
@@ -950,10 +954,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(29)
+ counters.RouteViewCounter.Bump(29)
err = routePanelThemesSetDefault(w,req,user,extraData)
case "/panel/plugins/":
- common.RouteViewCounter.Bump(30)
+ counters.RouteViewCounter.Bump(30)
err = routePanelPlugins(w,req,user)
case "/panel/plugins/activate/":
err = common.NoSessionMismatch(w,req,user)
@@ -962,7 +966,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(31)
+ counters.RouteViewCounter.Bump(31)
err = routePanelPluginsActivate(w,req,user,extraData)
case "/panel/plugins/deactivate/":
err = common.NoSessionMismatch(w,req,user)
@@ -971,7 +975,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(32)
+ counters.RouteViewCounter.Bump(32)
err = routePanelPluginsDeactivate(w,req,user,extraData)
case "/panel/plugins/install/":
err = common.NoSessionMismatch(w,req,user)
@@ -980,13 +984,13 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(33)
+ counters.RouteViewCounter.Bump(33)
err = routePanelPluginsInstall(w,req,user,extraData)
case "/panel/users/":
- common.RouteViewCounter.Bump(34)
+ counters.RouteViewCounter.Bump(34)
err = routePanelUsers(w,req,user)
case "/panel/users/edit/":
- common.RouteViewCounter.Bump(35)
+ counters.RouteViewCounter.Bump(35)
err = routePanelUsersEdit(w,req,user,extraData)
case "/panel/users/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -995,7 +999,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(36)
+ counters.RouteViewCounter.Bump(36)
err = routePanelUsersEditSubmit(w,req,user,extraData)
case "/panel/analytics/views/":
err = common.ParseForm(w,req,user)
@@ -1004,7 +1008,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(37)
+ counters.RouteViewCounter.Bump(37)
err = routePanelAnalyticsViews(w,req,user)
case "/panel/analytics/routes/":
err = common.ParseForm(w,req,user)
@@ -1013,7 +1017,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(38)
+ counters.RouteViewCounter.Bump(38)
err = routePanelAnalyticsRoutes(w,req,user)
case "/panel/analytics/agents/":
err = common.ParseForm(w,req,user)
@@ -1022,7 +1026,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(39)
+ counters.RouteViewCounter.Bump(39)
err = routePanelAnalyticsAgents(w,req,user)
case "/panel/analytics/systems/":
err = common.ParseForm(w,req,user)
@@ -1031,7 +1035,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(40)
+ counters.RouteViewCounter.Bump(40)
err = routePanelAnalyticsSystems(w,req,user)
case "/panel/analytics/referrers/":
err = common.ParseForm(w,req,user)
@@ -1040,19 +1044,19 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(41)
+ counters.RouteViewCounter.Bump(41)
err = routePanelAnalyticsReferrers(w,req,user)
case "/panel/analytics/route/":
- common.RouteViewCounter.Bump(42)
+ counters.RouteViewCounter.Bump(42)
err = routePanelAnalyticsRouteViews(w,req,user,extraData)
case "/panel/analytics/agent/":
- common.RouteViewCounter.Bump(43)
+ counters.RouteViewCounter.Bump(43)
err = routePanelAnalyticsAgentViews(w,req,user,extraData)
case "/panel/analytics/system/":
- common.RouteViewCounter.Bump(44)
+ counters.RouteViewCounter.Bump(44)
err = routePanelAnalyticsSystemViews(w,req,user,extraData)
case "/panel/analytics/referrer/":
- common.RouteViewCounter.Bump(45)
+ counters.RouteViewCounter.Bump(45)
err = routePanelAnalyticsReferrerViews(w,req,user,extraData)
case "/panel/analytics/posts/":
err = common.ParseForm(w,req,user)
@@ -1061,7 +1065,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(46)
+ counters.RouteViewCounter.Bump(46)
err = routePanelAnalyticsPosts(w,req,user)
case "/panel/analytics/topics/":
err = common.ParseForm(w,req,user)
@@ -1070,16 +1074,16 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(47)
+ counters.RouteViewCounter.Bump(47)
err = routePanelAnalyticsTopics(w,req,user)
case "/panel/groups/":
- common.RouteViewCounter.Bump(48)
+ counters.RouteViewCounter.Bump(48)
err = routePanelGroups(w,req,user)
case "/panel/groups/edit/":
- common.RouteViewCounter.Bump(49)
+ counters.RouteViewCounter.Bump(49)
err = routePanelGroupsEdit(w,req,user,extraData)
case "/panel/groups/edit/perms/":
- common.RouteViewCounter.Bump(50)
+ counters.RouteViewCounter.Bump(50)
err = routePanelGroupsEditPerms(w,req,user,extraData)
case "/panel/groups/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1088,7 +1092,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(51)
+ counters.RouteViewCounter.Bump(51)
err = routePanelGroupsEditSubmit(w,req,user,extraData)
case "/panel/groups/edit/perms/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1097,7 +1101,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(52)
+ counters.RouteViewCounter.Bump(52)
err = routePanelGroupsEditPermsSubmit(w,req,user,extraData)
case "/panel/groups/create/":
err = common.NoSessionMismatch(w,req,user)
@@ -1106,7 +1110,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(53)
+ counters.RouteViewCounter.Bump(53)
err = routePanelGroupsCreateSubmit(w,req,user)
case "/panel/backups/":
err = common.SuperAdminOnly(w,req,user)
@@ -1115,10 +1119,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(54)
+ counters.RouteViewCounter.Bump(54)
err = routePanelBackups(w,req,user,extraData)
case "/panel/logs/mod/":
- common.RouteViewCounter.Bump(55)
+ counters.RouteViewCounter.Bump(55)
err = routePanelLogsMod(w,req,user)
case "/panel/debug/":
err = common.AdminOnly(w,req,user)
@@ -1127,10 +1131,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(56)
+ counters.RouteViewCounter.Bump(56)
err = routePanelDebug(w,req,user)
default:
- common.RouteViewCounter.Bump(57)
+ counters.RouteViewCounter.Bump(57)
err = routePanelDashboard(w,req,user)
}
if err != nil {
@@ -1145,7 +1149,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(58)
+ counters.RouteViewCounter.Bump(58)
err = routes.AccountEditCritical(w,req,user)
case "/user/edit/critical/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1160,7 +1164,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(59)
+ counters.RouteViewCounter.Bump(59)
err = routeAccountEditCriticalSubmit(w,req,user)
case "/user/edit/avatar/":
err = common.MemberOnly(w,req,user)
@@ -1169,7 +1173,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(60)
+ counters.RouteViewCounter.Bump(60)
err = routeAccountEditAvatar(w,req,user)
case "/user/edit/avatar/submit/":
err = common.MemberOnly(w,req,user)
@@ -1189,7 +1193,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(61)
+ counters.RouteViewCounter.Bump(61)
err = routeAccountEditAvatarSubmit(w,req,user)
case "/user/edit/username/":
err = common.MemberOnly(w,req,user)
@@ -1198,7 +1202,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(62)
+ counters.RouteViewCounter.Bump(62)
err = routeAccountEditUsername(w,req,user)
case "/user/edit/username/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1213,7 +1217,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(63)
+ counters.RouteViewCounter.Bump(63)
err = routeAccountEditUsernameSubmit(w,req,user)
case "/user/edit/email/":
err = common.MemberOnly(w,req,user)
@@ -1222,7 +1226,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(64)
+ counters.RouteViewCounter.Bump(64)
err = routeAccountEditEmail(w,req,user)
case "/user/edit/token/":
err = common.NoSessionMismatch(w,req,user)
@@ -1237,11 +1241,11 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(65)
+ counters.RouteViewCounter.Bump(65)
err = routeAccountEditEmailTokenSubmit(w,req,user,extraData)
default:
req.URL.Path += extraData
- common.RouteViewCounter.Bump(66)
+ counters.RouteViewCounter.Bump(66)
err = routeProfile(w,req,user)
}
if err != nil {
@@ -1262,7 +1266,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(67)
+ counters.RouteViewCounter.Bump(67)
err = routes.BanUserSubmit(w,req,user,extraData)
case "/users/unban/":
err = common.NoSessionMismatch(w,req,user)
@@ -1277,7 +1281,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(68)
+ counters.RouteViewCounter.Bump(68)
err = routes.UnbanUser(w,req,user,extraData)
case "/users/activate/":
err = common.NoSessionMismatch(w,req,user)
@@ -1292,7 +1296,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(69)
+ counters.RouteViewCounter.Bump(69)
err = routes.ActivateUser(w,req,user,extraData)
case "/users/ips/":
err = common.MemberOnly(w,req,user)
@@ -1301,7 +1305,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(70)
+ counters.RouteViewCounter.Bump(70)
err = routes.IPSearch(w,req,user)
}
if err != nil {
@@ -1327,7 +1331,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(71)
+ counters.RouteViewCounter.Bump(71)
err = routes.CreateTopicSubmit(w,req,user)
case "/topic/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1342,7 +1346,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(72)
+ counters.RouteViewCounter.Bump(72)
err = routes.EditTopicSubmit(w,req,user,extraData)
case "/topic/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1358,7 +1362,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
req.URL.Path += extraData
- common.RouteViewCounter.Bump(73)
+ counters.RouteViewCounter.Bump(73)
err = routes.DeleteTopicSubmit(w,req,user)
case "/topic/stick/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1373,7 +1377,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(74)
+ counters.RouteViewCounter.Bump(74)
err = routes.StickTopicSubmit(w,req,user,extraData)
case "/topic/unstick/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1388,7 +1392,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(75)
+ counters.RouteViewCounter.Bump(75)
err = routes.UnstickTopicSubmit(w,req,user,extraData)
case "/topic/lock/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1404,7 +1408,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
req.URL.Path += extraData
- common.RouteViewCounter.Bump(76)
+ counters.RouteViewCounter.Bump(76)
err = routes.LockTopicSubmit(w,req,user)
case "/topic/unlock/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1419,7 +1423,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(77)
+ counters.RouteViewCounter.Bump(77)
err = routes.UnlockTopicSubmit(w,req,user,extraData)
case "/topic/move/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1434,7 +1438,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(78)
+ counters.RouteViewCounter.Bump(78)
err = routes.MoveTopicSubmit(w,req,user,extraData)
case "/topic/like/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1449,10 +1453,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(79)
+ counters.RouteViewCounter.Bump(79)
err = routeLikeTopicSubmit(w,req,user,extraData)
default:
- common.RouteViewCounter.Bump(80)
+ counters.RouteViewCounter.Bump(80)
err = routes.ViewTopic(w,req,user, extraData)
}
if err != nil {
@@ -1478,7 +1482,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(81)
+ counters.RouteViewCounter.Bump(81)
err = routeCreateReplySubmit(w,req,user)
case "/reply/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1493,7 +1497,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(82)
+ counters.RouteViewCounter.Bump(82)
err = routes.ReplyEditSubmit(w,req,user,extraData)
case "/reply/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1508,7 +1512,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(83)
+ counters.RouteViewCounter.Bump(83)
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
case "/reply/like/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1523,7 +1527,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(84)
+ counters.RouteViewCounter.Bump(84)
err = routeReplyLikeSubmit(w,req,user,extraData)
}
if err != nil {
@@ -1544,7 +1548,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(85)
+ counters.RouteViewCounter.Bump(85)
err = routeProfileReplyCreateSubmit(w,req,user)
case "/profile/reply/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1559,7 +1563,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(86)
+ counters.RouteViewCounter.Bump(86)
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
case "/profile/reply/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
@@ -1574,7 +1578,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(87)
+ counters.RouteViewCounter.Bump(87)
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
}
if err != nil {
@@ -1595,10 +1599,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(88)
+ counters.RouteViewCounter.Bump(88)
err = routes.PollVote(w,req,user,extraData)
case "/poll/results/":
- common.RouteViewCounter.Bump(89)
+ counters.RouteViewCounter.Bump(89)
err = routes.PollResults(w,req,user,extraData)
}
if err != nil {
@@ -1607,10 +1611,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
case "/accounts":
switch(req.URL.Path) {
case "/accounts/login/":
- common.RouteViewCounter.Bump(90)
+ counters.RouteViewCounter.Bump(90)
err = routes.AccountLogin(w,req,user)
case "/accounts/create/":
- common.RouteViewCounter.Bump(91)
+ counters.RouteViewCounter.Bump(91)
err = routes.AccountRegister(w,req,user)
case "/accounts/logout/":
err = common.NoSessionMismatch(w,req,user)
@@ -1625,7 +1629,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(92)
+ counters.RouteViewCounter.Bump(92)
err = routeLogout(w,req,user)
case "/accounts/login/submit/":
err = common.ParseForm(w,req,user)
@@ -1634,7 +1638,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(93)
+ counters.RouteViewCounter.Bump(93)
err = routes.AccountLoginSubmit(w,req,user)
case "/accounts/create/submit/":
err = common.ParseForm(w,req,user)
@@ -1643,7 +1647,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
- common.RouteViewCounter.Bump(94)
+ counters.RouteViewCounter.Bump(94)
err = routes.AccountRegisterSubmit(w,req,user)
}
if err != nil {
@@ -1657,10 +1661,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}*/
case "/uploads":
if extraData == "" {
- common.NotFound(w,req)
+ common.NotFound(w,req,nil)
return
}
- common.RouteViewCounter.Bump(96)
+ counters.RouteViewCounter.Bump(96)
req.URL.Path += extraData
// TODO: Find a way to propagate errors up from this?
router.UploadHandler(w,req) // TODO: Count these views
@@ -1682,7 +1686,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return*/
}
if extraData != "" {
- common.NotFound(w,req)
+ common.NotFound(w,req,nil)
return
}
@@ -1690,10 +1694,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if !ok {
// TODO: Make this a startup error not a runtime one
log.Print("Unable to find the default route")
- common.NotFound(w,req)
+ common.NotFound(w,req,nil)
return
}
- common.RouteViewCounter.Bump(routeMapEnum[common.Config.DefaultRoute])
+ counters.RouteViewCounter.Bump(routeMapEnum[common.Config.DefaultRoute])
handle.(func(http.ResponseWriter, *http.Request, common.User) common.RouteError)(w,req,user)
default:
@@ -1703,7 +1707,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
router.RUnlock()
if ok {
- common.RouteViewCounter.Bump(95) // TODO: Be more specific about *which* dynamic route it is
+ counters.RouteViewCounter.Bump(95) // TODO: Be more specific about *which* dynamic route it is
req.URL.Path += extraData
err = handle(w,req,user)
if err != nil {
@@ -1717,7 +1721,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if strings.Contains(lowerPath,"admin") || strings.Contains(lowerPath,"sql") || strings.Contains(lowerPath,"manage") || strings.Contains(lowerPath,"//") || strings.Contains(lowerPath,"\\\\") || strings.Contains(lowerPath,"wp") || strings.Contains(lowerPath,"wordpress") || strings.Contains(lowerPath,"config") || strings.Contains(lowerPath,"setup") || strings.Contains(lowerPath,"install") || strings.Contains(lowerPath,"update") || strings.Contains(lowerPath,"php") {
router.SuspiciousRequest(req)
}
- common.RouteViewCounter.Bump(97)
- common.NotFound(w,req)
+ counters.RouteViewCounter.Bump(98)
+ common.NotFound(w,req,nil)
}
}
diff --git a/main.go b/main.go
index 104805eb..97aa40e9 100644
--- a/main.go
+++ b/main.go
@@ -16,8 +16,9 @@ import (
"strings"
"syscall"
"time"
- //"runtime/pprof"
+
"./common"
+ "./common/counters"
"github.com/fsnotify/fsnotify"
)
@@ -101,35 +102,35 @@ func afterDBInit() (err error) {
return err
}
- common.GlobalViewCounter, err = common.NewGlobalViewCounter()
+ counters.GlobalViewCounter, err = counters.NewGlobalViewCounter()
if err != nil {
return err
}
- common.AgentViewCounter, err = common.NewDefaultAgentViewCounter()
+ counters.AgentViewCounter, err = counters.NewDefaultAgentViewCounter()
if err != nil {
return err
}
- common.OSViewCounter, err = common.NewDefaultOSViewCounter()
+ counters.OSViewCounter, err = counters.NewDefaultOSViewCounter()
if err != nil {
return err
}
- common.RouteViewCounter, err = common.NewDefaultRouteViewCounter()
+ counters.RouteViewCounter, err = counters.NewDefaultRouteViewCounter()
if err != nil {
return err
}
- common.PostCounter, err = common.NewPostCounter()
+ counters.PostCounter, err = counters.NewPostCounter()
if err != nil {
return err
}
- common.TopicCounter, err = common.NewTopicCounter()
+ counters.TopicCounter, err = counters.NewTopicCounter()
if err != nil {
return err
}
- common.TopicViewCounter, err = common.NewDefaultTopicViewCounter()
+ counters.TopicViewCounter, err = counters.NewDefaultTopicViewCounter()
if err != nil {
return err
}
- common.ReferrerTracker, err = common.NewDefaultReferrerTracker()
+ counters.ReferrerTracker, err = counters.NewDefaultReferrerTracker()
if err != nil {
return err
}
diff --git a/member_routes.go b/member_routes.go
index 742f937e..e352740a 100644
--- a/member_routes.go
+++ b/member_routes.go
@@ -14,6 +14,7 @@ import (
"strings"
"./common"
+ "./common/counters"
)
func routeCreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
@@ -194,7 +195,7 @@ func routeCreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.
return common.InternalError(err, w, r)
}
- common.PostCounter.Bump()
+ counters.PostCounter.Bump()
return nil
}
@@ -348,7 +349,7 @@ func routeProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user
return common.InternalError(err, w, r)
}
- common.PostCounter.Bump()
+ counters.PostCounter.Bump()
http.Redirect(w, r, "/user/"+strconv.Itoa(uid), http.StatusSeeOther)
return nil
}
@@ -398,7 +399,7 @@ func routeReportSubmit(w http.ResponseWriter, r *http.Request, user common.User,
} else if itemType == "topic" {
err = stmts.getTopicBasic.QueryRow(itemID).Scan(&title, &content)
if err == ErrNoRows {
- return common.NotFound(w, r)
+ return common.NotFound(w, r, nil)
} else if err != nil {
return common.InternalError(err, w, r)
}
@@ -439,7 +440,7 @@ func routeReportSubmit(w http.ResponseWriter, r *http.Request, user common.User,
if err != nil && err != ErrNoRows {
return common.InternalError(err, w, r)
}
- common.PostCounter.Bump()
+ counters.PostCounter.Bump()
http.Redirect(w, r, "/topic/"+strconv.FormatInt(lastID, 10), http.StatusSeeOther)
return nil
@@ -479,10 +480,8 @@ func routeAccountEditCriticalSubmit(w http.ResponseWriter, r *http.Request, user
headerVars.NoticeList = append(headerVars.NoticeList, "Your password was successfully updated")
pi := common.Page{"Edit Password", user, headerVars, tList, nil}
- if common.PreRenderHooks["pre_render_account_own_edit_critical"] != nil {
- if common.RunPreRenderHook("pre_render_account_own_edit_critical", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_account_own_edit_critical", w, r, &user, &pi) {
+ return nil
}
err = common.Templates.ExecuteTemplate(w, "account_own_edit.html", pi)
if err != nil {
@@ -498,10 +497,8 @@ func routeAccountEditAvatar(w http.ResponseWriter, r *http.Request, user common.
}
pi := common.Page{"Edit Avatar", user, headerVars, tList, nil}
- if common.PreRenderHooks["pre_render_account_own_edit_avatar"] != nil {
- if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) {
+ return nil
}
err := common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi)
if err != nil {
@@ -573,10 +570,8 @@ func routeAccountEditAvatarSubmit(w http.ResponseWriter, r *http.Request, user c
headerVars.NoticeList = append(headerVars.NoticeList, "Your avatar was successfully updated")
pi := common.Page{"Edit Avatar", user, headerVars, tList, nil}
- if common.PreRenderHooks["pre_render_account_own_edit_avatar"] != nil {
- if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) {
+ return nil
}
err = common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi)
if err != nil {
@@ -592,10 +587,8 @@ func routeAccountEditUsername(w http.ResponseWriter, r *http.Request, user commo
}
pi := common.Page{"Edit Username", user, headerVars, tList, user.Name}
- if common.PreRenderHooks["pre_render_account_own_edit_username"] != nil {
- if common.RunPreRenderHook("pre_render_account_own_edit_username", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_account_own_edit_username", w, r, &user, &pi) {
+ return nil
}
err := common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi)
if err != nil {
@@ -619,10 +612,8 @@ func routeAccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user
headerVars.NoticeList = append(headerVars.NoticeList, "Your username was successfully updated")
pi := common.Page{"Edit Username", user, headerVars, tList, nil}
- if common.PreRenderHooks["pre_render_account_own_edit_username"] != nil {
- if common.RunPreRenderHook("pre_render_account_own_edit_username", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_account_own_edit_username", w, r, &user, &pi) {
+ return nil
}
err = common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi)
if err != nil {
@@ -674,10 +665,8 @@ func routeAccountEditEmail(w http.ResponseWriter, r *http.Request, user common.U
}
pi := common.Page{"Email Manager", user, headerVars, emailList, nil}
- if common.PreRenderHooks["pre_render_account_own_edit_email"] != nil {
- if common.RunPreRenderHook("pre_render_account_own_edit_email", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_account_own_edit_email", w, r, &user, &pi) {
+ return nil
}
err = common.Templates.ExecuteTemplate(w, "account_own_edit_email.html", pi)
if err != nil {
@@ -746,10 +735,8 @@ func routeAccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, us
}
headerVars.NoticeList = append(headerVars.NoticeList, "Your email was successfully verified")
pi := common.Page{"Email Manager", user, headerVars, emailList, nil}
- if common.PreRenderHooks["pre_render_account_own_edit_email"] != nil {
- if common.RunPreRenderHook("pre_render_account_own_edit_email", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_account_own_edit_email", w, r, &user, &pi) {
+ return nil
}
err = common.Templates.ExecuteTemplate(w, "account_own_edit_email.html", pi)
if err != nil {
@@ -786,7 +773,7 @@ func routeShowAttachment(w http.ResponseWriter, r *http.Request, user common.Use
var originID, uploadedBy int
err = stmts.getAttachment.QueryRow(filename, sectionID, sectionTable).Scan(§ionID, §ionTable, &originID, &originTable, &uploadedBy, &filename)
if err == ErrNoRows {
- return common.NotFound(w, r)
+ return common.NotFound(w, r, nil)
} else if err != nil {
return common.InternalError(err, w, r)
}
diff --git a/panel_routes.go b/panel_routes.go
index 35943c4d..668a8266 100644
--- a/panel_routes.go
+++ b/panel_routes.go
@@ -31,10 +31,8 @@ func panelSuccessRedirect(dest string, w http.ResponseWriter, r *http.Request, i
return nil
}
func panelRenderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, user common.User, pi interface{}) common.RouteError {
- if common.PreRenderHooks["pre_render_"+tmplName] != nil {
- if common.RunPreRenderHook("pre_render_"+tmplName, w, r, &user, pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_"+tmplName, w, r, &user, pi) {
+ return nil
}
err := common.Templates.ExecuteTemplate(w, tmplName+".html", pi)
if err != nil {
@@ -253,10 +251,8 @@ func routePanelForumsDelete(w http.ResponseWriter, r *http.Request, user common.
yousure := common.AreYouSure{"/panel/forums/delete/submit/" + strconv.Itoa(fid), confirmMsg}
pi := common.PanelPage{common.GetTitlePhrase("panel_delete_forum"), user, headerVars, stats, "forums", tList, yousure}
- if common.PreRenderHooks["pre_render_panel_delete_forum"] != nil {
- if common.RunPreRenderHook("pre_render_panel_delete_forum", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_panel_delete_forum", w, r, &user, &pi) {
+ return nil
}
err = common.Templates.ExecuteTemplate(w, "are_you_sure.html", pi)
if err != nil {
@@ -330,10 +326,8 @@ func routePanelForumsEdit(w http.ResponseWriter, r *http.Request, user common.Us
}
pi := common.PanelEditForumPage{common.GetTitlePhrase("panel_edit_forum"), user, headerVars, stats, "forums", forum.ID, forum.Name, forum.Desc, forum.Active, forum.Preset, gplist}
- if common.PreRenderHooks["pre_render_panel_edit_forum"] != nil {
- if common.RunPreRenderHook("pre_render_panel_edit_forum", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_panel_edit_forum", w, r, &user, &pi) {
+ return nil
}
err = common.Templates.ExecuteTemplate(w, "panel-forum-edit.html", pi)
if err != nil {
@@ -493,10 +487,8 @@ func routePanelForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, us
addNameLangToggle("MoveTopic", forumPerms.MoveTopic)
pi := common.PanelEditForumGroupPage{common.GetTitlePhrase("panel_edit_forum"), user, headerVars, stats, "forums", forum.ID, gid, forum.Name, forum.Desc, forum.Active, forum.Preset, formattedPermList}
- if common.PreRenderHooks["pre_render_panel_edit_forum"] != nil {
- if common.RunPreRenderHook("pre_render_panel_edit_forum", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_panel_edit_forum", w, r, &user, &pi) {
+ return nil
}
err = common.Templates.ExecuteTemplate(w, "panel-forum-edit-perms.html", pi)
if err != nil {
@@ -801,6 +793,7 @@ func routePanelAnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user
}
var unixCreatedAt = createdAt.Unix()
+ // TODO: Bulk log this
if common.Dev.SuperDebug {
log.Print("count: ", count)
log.Print("createdAt: ", createdAt)
@@ -883,6 +876,7 @@ func routePanelAnalyticsSystemViews(w http.ResponseWriter, r *http.Request, user
}
var unixCreatedAt = createdAt.Unix()
+ // TODO: Bulk log this
if common.Dev.SuperDebug {
log.Print("count: ", count)
log.Print("createdAt: ", createdAt)
@@ -964,6 +958,7 @@ func routePanelAnalyticsReferrerViews(w http.ResponseWriter, r *http.Request, us
}
var unixCreatedAt = createdAt.Unix()
+ // TODO: Bulk log this
if common.Dev.SuperDebug {
log.Print("count: ", count)
log.Print("createdAt: ", createdAt)
@@ -1038,6 +1033,7 @@ func routePanelAnalyticsTopics(w http.ResponseWriter, r *http.Request, user comm
}
var unixCreatedAt = createdAt.Unix()
+ // TODO: Bulk log this
if common.Dev.SuperDebug {
log.Print("count: ", count)
log.Print("createdAt: ", createdAt)
@@ -1171,6 +1167,7 @@ func routePanelAnalyticsRoutes(w http.ResponseWriter, r *http.Request, user comm
return common.InternalError(err, w, r)
}
+ // TODO: Bulk log this
if common.Dev.SuperDebug {
log.Print("count: ", count)
log.Print("route: ", route)
@@ -1222,6 +1219,7 @@ func routePanelAnalyticsAgents(w http.ResponseWriter, r *http.Request, user comm
return common.InternalError(err, w, r)
}
+ // TODO: Bulk log this
if common.Dev.SuperDebug {
log.Print("count: ", count)
log.Print("agent: ", agent)
@@ -1278,6 +1276,7 @@ func routePanelAnalyticsSystems(w http.ResponseWriter, r *http.Request, user com
return common.InternalError(err, w, r)
}
+ // TODO: Bulk log this
if common.Dev.SuperDebug {
log.Print("count: ", count)
log.Print("system: ", system)
@@ -1334,6 +1333,7 @@ func routePanelAnalyticsReferrers(w http.ResponseWriter, r *http.Request, user c
return common.InternalError(err, w, r)
}
+ // TODO: Bulk log this
if common.Dev.SuperDebug {
log.Print("count: ", count)
log.Print("domain: ", domain)
@@ -1850,10 +1850,8 @@ func routePanelUsersEdit(w http.ResponseWriter, r *http.Request, user common.Use
}
pi := common.PanelPage{common.GetTitlePhrase("panel_edit_user"), user, headerVars, stats, "users", groupList, targetUser}
- if common.PreRenderHooks["pre_render_panel_edit_user"] != nil {
- if common.RunPreRenderHook("pre_render_panel_edit_user", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_panel_edit_user", w, r, &user, &pi) {
+ return nil
}
err = common.Templates.ExecuteTemplate(w, "panel-user-edit.html", pi)
if err != nil {
@@ -2015,7 +2013,7 @@ func routePanelGroupsEdit(w http.ResponseWriter, r *http.Request, user common.Us
group, err := common.Groups.Get(gid)
if err == ErrNoRows {
//log.Print("aaaaa monsters")
- return common.NotFound(w, r)
+ return common.NotFound(w, r, headerVars)
} else if err != nil {
return common.InternalError(err, w, r)
}
@@ -2044,10 +2042,8 @@ func routePanelGroupsEdit(w http.ResponseWriter, r *http.Request, user common.Us
disableRank := !user.Perms.EditGroupGlobalPerms || (group.ID == 6)
pi := common.PanelEditGroupPage{common.GetTitlePhrase("panel_edit_group"), user, headerVars, stats, "groups", group.ID, group.Name, group.Tag, rank, disableRank}
- if common.PreRenderHooks["pre_render_panel_edit_group"] != nil {
- if common.RunPreRenderHook("pre_render_panel_edit_group", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_panel_edit_group", w, r, &user, &pi) {
+ return nil
}
err = common.Templates.ExecuteTemplate(w, "panel-group-edit.html", pi)
if err != nil {
@@ -2073,7 +2069,7 @@ func routePanelGroupsEditPerms(w http.ResponseWriter, r *http.Request, user comm
group, err := common.Groups.Get(gid)
if err == ErrNoRows {
//log.Print("aaaaa monsters")
- return common.NotFound(w, r)
+ return common.NotFound(w, r, headerVars)
} else if err != nil {
return common.InternalError(err, w, r)
}
@@ -2132,10 +2128,8 @@ func routePanelGroupsEditPerms(w http.ResponseWriter, r *http.Request, user comm
addGlobalPerm("UploadFiles", group.Perms.UploadFiles)
pi := common.PanelEditGroupPermsPage{common.GetTitlePhrase("panel_edit_group"), user, headerVars, stats, "groups", group.ID, group.Name, localPerms, globalPerms}
- if common.PreRenderHooks["pre_render_panel_edit_group_perms"] != nil {
- if common.RunPreRenderHook("pre_render_panel_edit_group_perms", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_panel_edit_group_perms", w, r, &user, &pi) {
+ return nil
}
err = common.Templates.ExecuteTemplate(w, "panel-group-edit-perms.html", pi)
if err != nil {
@@ -2161,7 +2155,7 @@ func routePanelGroupsEditSubmit(w http.ResponseWriter, r *http.Request, user com
group, err := common.Groups.Get(gid)
if err == ErrNoRows {
//log.Print("aaaaa monsters")
- return common.NotFound(w, r)
+ return common.NotFound(w, r, nil)
} else if err != nil {
return common.InternalError(err, w, r)
}
@@ -2252,7 +2246,7 @@ func routePanelGroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, use
group, err := common.Groups.Get(gid)
if err == ErrNoRows {
//log.Print("aaaaa monsters o.o")
- return common.NotFound(w, r)
+ return common.NotFound(w, r, nil)
} else if err != nil {
return common.InternalError(err, w, r)
}
@@ -2444,7 +2438,7 @@ func routePanelBackups(w http.ResponseWriter, r *http.Request, user common.User,
if ext == ".sql" {
info, err := os.Stat("./backups/" + backupURL)
if err != nil {
- return common.NotFound(w, r)
+ return common.NotFound(w, r, headerVars)
}
// TODO: Change the served filename to gosora_backup_%timestamp%.sql, the time the file was generated, not when it was modified aka what the name of it should be
w.Header().Set("Content-Disposition", "attachment; filename=gosora_backup.sql")
@@ -2453,7 +2447,7 @@ func routePanelBackups(w http.ResponseWriter, r *http.Request, user common.User,
http.ServeFile(w, r, "./backups/"+backupURL)
return nil
}
- return common.NotFound(w, r)
+ return common.NotFound(w, r, headerVars)
}
var backupList []common.BackupItem
@@ -2487,23 +2481,34 @@ func handleUnknownTopic(topic *common.Topic, err error) *common.Topic {
return topic
}
+// TODO: Move the log building logic into /common/ and it's own abstraction
+func topicElementTypeAction(action string, elementType string, elementID int, actor *common.User, topic *common.Topic) (out string) {
+ if action == "delete" {
+ return fmt.Sprintf("Topic #%d was deleted by %s", elementID, actor.Link, actor.Name)
+ }
+
+ switch action {
+ case "lock":
+ out = "%s was locked by %s"
+ case "unlock":
+ out = "%s was reopened by %s"
+ case "stick":
+ out = "%s was pinned by %s"
+ case "unstick":
+ out = "%s was unpinned by %s"
+ case "move":
+ out = "%s was moved by %s" // TODO: Add where it was moved to, we'll have to change the source data for that, most likely? Investigate that and try to work this in
+ default:
+ return fmt.Sprintf("Unknown action '%s' on elementType '%s' by %s", action, elementType, actor.Link, actor.Name)
+ }
+ return fmt.Sprintf(out, topic.Link, topic.Title, actor.Link, actor.Name)
+}
+
func modlogsElementType(action string, elementType string, elementID int, actor *common.User) (out string) {
switch elementType {
case "topic":
topic := handleUnknownTopic(common.Topics.Get(elementID))
- switch action {
- case "lock":
- out = "%s was locked by %s"
- case "unlock":
- out = "%s was reopened by %s"
- case "stick":
- out = "%s was pinned by %s"
- case "unstick":
- out = "%s was unpinned by %s"
- case "delete":
- return fmt.Sprintf("Topic #%d was deleted by %s", elementID, actor.Link, actor.Name)
- }
- out = fmt.Sprintf(out, topic.Link, topic.Title, actor.Link, actor.Name)
+ out = topicElementTypeAction(action, elementType, elementID, actor, topic)
case "user":
targetUser := handleUnknownUser(common.Users.Get(elementID))
switch action {
@@ -2521,6 +2526,7 @@ func modlogsElementType(action string, elementType string, elementID int, actor
out = fmt.Sprintf("A reply in %s was deleted by %s", topic.Link, topic.Title, actor.Link, actor.Name)
}
}
+
if out == "" {
out = fmt.Sprintf("Unknown action '%s' on elementType '%s' by %s", action, elementType, actor.Link, actor.Name)
}
diff --git a/query_gen/lib/mssql.go b/query_gen/lib/mssql.go
index ef21ce1d..b9d4fcfe 100644
--- a/query_gen/lib/mssql.go
+++ b/query_gen/lib/mssql.go
@@ -1123,9 +1123,7 @@ type Stmts struct {
// nolint
func _gen_mssql() (err error) {
- if common.Dev.DebugMode {
- log.Print("Building the generated statements")
- }
+ common.DebugLog("Building the generated statements")
` + body + `
return nil
}
diff --git a/query_gen/lib/mysql.go b/query_gen/lib/mysql.go
index 8686ff17..433f9d6c 100644
--- a/query_gen/lib/mysql.go
+++ b/query_gen/lib/mysql.go
@@ -684,9 +684,7 @@ type Stmts struct {
// nolint
func _gen_mysql() (err error) {
- if common.Dev.DebugMode {
- log.Print("Building the generated statements")
- }
+ common.DebugLog("Building the generated statements")
` + body + `
return nil
}
diff --git a/query_gen/lib/pgsql.go b/query_gen/lib/pgsql.go
index fa676e12..ae9a3e44 100644
--- a/query_gen/lib/pgsql.go
+++ b/query_gen/lib/pgsql.go
@@ -381,9 +381,7 @@ type Stmts struct {
// nolint
func _gen_pgsql() (err error) {
- if common.Dev.DebugMode {
- log.Print("Building the generated statements")
- }
+ common.DebugLog("Building the generated statements")
` + body + `
return nil
}
diff --git a/query_gen/tables.go b/query_gen/tables.go
index 9965b948..5a99b42c 100644
--- a/query_gen/tables.go
+++ b/query_gen/tables.go
@@ -433,16 +433,14 @@ func createTables(adapter qgen.Adapter) error {
[]qgen.DBTableKey{},
)
- /*
- qgen.Install.CreateTable("viewchunks_forums", "", "",
- []qgen.DBTableColumn{
- qgen.DBTableColumn{"count", "int", 0, false, false, "0"},
- qgen.DBTableColumn{"createdAt", "datetime", 0, false, false, ""},
- qgen.DBTableColumn{"forum", "int", 0, false, false, ""},
- },
- []qgen.DBTableKey{},
- )
- */
+ qgen.Install.CreateTable("viewchunks_forums", "", "",
+ []qgen.DBTableColumn{
+ qgen.DBTableColumn{"count", "int", 0, false, false, "0"},
+ qgen.DBTableColumn{"createdAt", "datetime", 0, false, false, ""},
+ qgen.DBTableColumn{"forum", "int", 0, false, false, ""},
+ },
+ []qgen.DBTableKey{},
+ )
qgen.Install.CreateTable("topicchunks", "", "",
[]qgen.DBTableColumn{
diff --git a/router.go b/router.go
index a966dff2..d3a58801 100644
--- a/router.go
+++ b/router.go
@@ -63,5 +63,5 @@ func (router *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
//log.Print("req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/')]",req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/')])
- common.NotFound(w, req)
+ common.NotFound(w, req,nil)
}
diff --git a/router_gen/main.go b/router_gen/main.go
index 9ad0c57d..fee0ee16 100644
--- a/router_gen/main.go
+++ b/router_gen/main.go
@@ -70,7 +70,7 @@ func main() {
var end = len(route.Path) - 1
out += "\n\t\tcase \"" + route.Path[0:end] + "\":"
out += runBefore(route.RunBefore, 4)
- out += "\n\t\t\tcommon.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[route.Name]) + ")"
+ out += "\n\t\t\tcounters.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[route.Name]) + ")"
out += "\n\t\t\terr = " + route.Name + "(w,req,user"
for _, item := range route.Vars {
out += "," + item
@@ -128,7 +128,7 @@ func main() {
}
}
}
- out += "\n\t\t\t\t\tcommon.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[route.Name]) + ")"
+ out += "\n\t\t\t\t\tcounters.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[route.Name]) + ")"
out += "\n\t\t\t\t\terr = " + route.Name + "(w,req,user"
for _, item := range route.Vars {
out += "," + item
@@ -140,7 +140,7 @@ func main() {
mapIt(defaultRoute.Name)
out += "\n\t\t\t\tdefault:"
out += runBefore(defaultRoute.RunBefore, 4)
- out += "\n\t\t\t\t\tcommon.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[defaultRoute.Name]) + ")"
+ out += "\n\t\t\t\t\tcounters.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[defaultRoute.Name]) + ")"
out += "\n\t\t\t\t\terr = " + defaultRoute.Name + "(w,req,user"
for _, item := range defaultRoute.Vars {
out += ", " + item
@@ -157,6 +157,7 @@ func main() {
// Stubs for us to refer to these routes through
mapIt("routeDynamic")
mapIt("routeUploads")
+ mapIt("routes.StaticFile")
mapIt("BadRoute")
tmplVars.AllRouteNames = allRouteNames
tmplVars.AllRouteMap = allRouteMap
@@ -224,6 +225,7 @@ import (
"net/http"
"./common"
+ "./common/counters"
"./routes"
)
@@ -287,12 +289,12 @@ var markToAgent = map[string]string{
// TODO: Stop spilling these into the package scope?
func init() {
- common.SetRouteMapEnum(routeMapEnum)
- common.SetReverseRouteMapEnum(reverseRouteMapEnum)
- common.SetAgentMapEnum(agentMapEnum)
- common.SetReverseAgentMapEnum(reverseAgentMapEnum)
- common.SetOSMapEnum(osMapEnum)
- common.SetReverseOSMapEnum(reverseOSMapEnum)
+ counters.SetRouteMapEnum(routeMapEnum)
+ counters.SetReverseRouteMapEnum(reverseRouteMapEnum)
+ counters.SetAgentMapEnum(agentMapEnum)
+ counters.SetReverseAgentMapEnum(reverseAgentMapEnum)
+ counters.SetOSMapEnum(osMapEnum)
+ counters.SetReverseOSMapEnum(reverseOSMapEnum)
}
type GenRouter struct {
@@ -359,7 +361,7 @@ func (router *GenRouter) DumpRequest(req *http.Request) {
func (router *GenRouter) SuspiciousRequest(req *http.Request) {
log.Print("Suspicious Request")
router.DumpRequest(req)
- common.AgentViewCounter.Bump({{.AllAgentMap.suspicious}})
+ counters.AgentViewCounter.Bump({{.AllAgentMap.suspicious}})
}
// TODO: Pass the default route or config struct to the router rather than accessing it via a package global
@@ -392,7 +394,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.Write([]byte(""))
log.Print("Malformed Request")
router.DumpRequest(req)
- common.AgentViewCounter.Bump({{.AllAgentMap.malformed}})
+ counters.AgentViewCounter.Bump({{.AllAgentMap.malformed}})
return
}
@@ -422,8 +424,11 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
log.Print("before routes.StaticFile")
router.DumpRequest(req)
}
+ // Increment the request counter
+ counters.GlobalViewCounter.Bump()
if prefix == "/static" {
+ counters.RouteViewCounter.Bump({{ index .AllRouteMap "routes.StaticFile" }})
req.URL.Path += extraData
routes.StaticFile(w, req)
return
@@ -432,15 +437,12 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
log.Print("before PreRoute")
}
- // Increment the global view counter
- common.GlobalViewCounter.Bump()
-
// Track the user agents. Unfortunately, everyone pretends to be Mozilla, so this'll be a little less efficient than I would like.
// TODO: Add a setting to disable this?
// TODO: Use a more efficient detector instead of smashing every possible combination in
ua := strings.TrimSpace(strings.Replace(strings.TrimPrefix(req.UserAgent(),"Mozilla/5.0 ")," Safari/537.36","",-1)) // Noise, no one's going to be running this and it would require some sort of agent ranking system to determine which identifier should be prioritised over another
if ua == "" {
- common.AgentViewCounter.Bump({{.AllAgentMap.blank}})
+ counters.AgentViewCounter.Bump({{.AllAgentMap.blank}})
if common.Dev.DebugMode {
log.Print("Blank UA: ", req.UserAgent())
router.DumpRequest(req)
@@ -540,15 +542,15 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
if agent == "" {
- common.AgentViewCounter.Bump({{.AllAgentMap.unknown}})
+ counters.AgentViewCounter.Bump({{.AllAgentMap.unknown}})
if common.Dev.DebugMode {
log.Print("Unknown UA: ", req.UserAgent())
router.DumpRequest(req)
}
} else {
- common.AgentViewCounter.Bump(agentMapEnum[agent])
+ counters.AgentViewCounter.Bump(agentMapEnum[agent])
}
- common.OSViewCounter.Bump(osMapEnum[os])
+ counters.OSViewCounter.Bump(osMapEnum[os])
}
referrer := req.Header.Get("Referer") // Check the 'referrer' header too? :P
@@ -558,7 +560,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
referrer = strings.Split(referrer,"/")[0]
portless := strings.Split(referrer,":")[0]
if portless != "localhost" && portless != "127.0.0.1" && portless != common.Site.Host {
- common.ReferrerTracker.Bump(referrer)
+ counters.ReferrerTracker.Bump(referrer)
}
}
@@ -582,10 +584,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}*/
case "/uploads":
if extraData == "" {
- common.NotFound(w,req)
+ common.NotFound(w,req,nil)
return
}
- common.RouteViewCounter.Bump({{.AllRouteMap.routeUploads}})
+ counters.RouteViewCounter.Bump({{.AllRouteMap.routeUploads}})
req.URL.Path += extraData
// TODO: Find a way to propagate errors up from this?
router.UploadHandler(w,req) // TODO: Count these views
@@ -607,7 +609,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return*/
}
if extraData != "" {
- common.NotFound(w,req)
+ common.NotFound(w,req,nil)
return
}
@@ -615,10 +617,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if !ok {
// TODO: Make this a startup error not a runtime one
log.Print("Unable to find the default route")
- common.NotFound(w,req)
+ common.NotFound(w,req,nil)
return
}
- common.RouteViewCounter.Bump(routeMapEnum[common.Config.DefaultRoute])
+ counters.RouteViewCounter.Bump(routeMapEnum[common.Config.DefaultRoute])
handle.(func(http.ResponseWriter, *http.Request, common.User) common.RouteError)(w,req,user)
default:
@@ -628,7 +630,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
router.RUnlock()
if ok {
- common.RouteViewCounter.Bump({{.AllRouteMap.routeDynamic}}) // TODO: Be more specific about *which* dynamic route it is
+ counters.RouteViewCounter.Bump({{.AllRouteMap.routeDynamic}}) // TODO: Be more specific about *which* dynamic route it is
req.URL.Path += extraData
err = handle(w,req,user)
if err != nil {
@@ -642,8 +644,8 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if strings.Contains(lowerPath,"admin") || strings.Contains(lowerPath,"sql") || strings.Contains(lowerPath,"manage") || strings.Contains(lowerPath,"//") || strings.Contains(lowerPath,"\\\\") || strings.Contains(lowerPath,"wp") || strings.Contains(lowerPath,"wordpress") || strings.Contains(lowerPath,"config") || strings.Contains(lowerPath,"setup") || strings.Contains(lowerPath,"install") || strings.Contains(lowerPath,"update") || strings.Contains(lowerPath,"php") {
router.SuspiciousRequest(req)
}
- common.RouteViewCounter.Bump({{.AllRouteMap.BadRoute}})
- common.NotFound(w,req)
+ counters.RouteViewCounter.Bump({{.AllRouteMap.BadRoute}})
+ common.NotFound(w,req,nil)
}
}
`
diff --git a/routes.go b/routes.go
index 25d79803..5f9b2e0b 100644
--- a/routes.go
+++ b/routes.go
@@ -64,15 +64,15 @@ func routeForum(w http.ResponseWriter, r *http.Request, user common.User, sfid s
if !user.Perms.ViewTopic {
return common.NoPermissions(w, r, user)
}
+ headerVars.Zone = "view_forum"
// TODO: Fix this double-check
forum, err := common.Forums.Get(fid)
if err == ErrNoRows {
- return common.NotFound(w, r)
+ return common.NotFound(w, r, headerVars)
} else if err != nil {
return common.InternalError(err, w, r)
}
- headerVars.Zone = "view_forum"
// TODO: Does forum.TopicCount take the deleted items into consideration for guests? We don't have soft-delete yet, only hard-delete
offset, page, lastPage := common.PageOffset(forum.TopicCount, page, common.Config.ItemsPerPage)
@@ -130,10 +130,8 @@ func routeForum(w http.ResponseWriter, r *http.Request, user common.User, sfid s
pageList := common.Paginate(forum.TopicCount, common.Config.ItemsPerPage, 5)
pi := common.ForumPage{forum.Name, user, headerVars, topicList, forum, pageList, page, lastPage}
- if common.PreRenderHooks["pre_render_forum"] != nil {
- if common.RunPreRenderHook("pre_render_forum", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_forum", w, r, &user, &pi) {
+ return nil
}
err = common.RunThemeTemplate(headerVars.Theme.Name, "forum", pi, w)
if err != nil {
@@ -180,18 +178,14 @@ func routeForums(w http.ResponseWriter, r *http.Request, user common.User) commo
} else {
forum.LastTopicTime = ""
}
- if common.Hooks["forums_frow_assign"] != nil {
- common.RunHook("forums_frow_assign", &forum)
- }
+ common.RunHook("forums_frow_assign", &forum)
forumList = append(forumList, forum)
}
}
pi := common.ForumsPage{common.GetTitlePhrase("forums"), user, headerVars, forumList}
- if common.PreRenderHooks["pre_render_forum_list"] != nil {
- if common.RunPreRenderHook("pre_render_forum_list", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_forum_list", w, r, &user, &pi) {
+ return nil
}
err = common.RunThemeTemplate(headerVars.Theme.Name, "forums", pi, w)
if err != nil {
@@ -233,7 +227,7 @@ func routeProfile(w http.ResponseWriter, r *http.Request, user common.User) comm
// TODO: Add a shared function for checking for ErrNoRows and internal erroring if it's not that case?
puser, err = common.Users.Get(pid)
if err == ErrNoRows {
- return common.NotFound(w, r)
+ return common.NotFound(w, r, headerVars)
} else if err != nil {
return common.InternalError(err, w, r)
}
@@ -288,10 +282,8 @@ func routeProfile(w http.ResponseWriter, r *http.Request, user common.User) comm
// TODO: Add a phrase for this title
ppage := common.ProfilePage{puser.Name + "'s Profile", user, headerVars, replyList, *puser}
- if common.PreRenderHooks["pre_render_profile"] != nil {
- if common.RunPreRenderHook("pre_render_profile", w, r, &user, &ppage) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_profile", w, r, &user, &ppage) {
+ return nil
}
err = common.RunThemeTemplate(headerVars.Theme.Name, "profile", ppage, w)
diff --git a/routes/account.go b/routes/account.go
index 7684809d..e3ef6656 100644
--- a/routes/account.go
+++ b/routes/account.go
@@ -22,10 +22,8 @@ func AccountLogin(w http.ResponseWriter, r *http.Request, user common.User) comm
return common.LocalError("You're already logged in.", w, r, user)
}
pi := common.Page{common.GetTitlePhrase("login"), user, headerVars, tList, nil}
- if common.PreRenderHooks["pre_render_login"] != nil {
- if common.RunPreRenderHook("pre_render_login", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_login", w, r, &user, &pi) {
+ return nil
}
err := common.Templates.ExecuteTemplate(w, "login.html", pi)
if err != nil {
@@ -83,10 +81,8 @@ func AccountRegister(w http.ResponseWriter, r *http.Request, user common.User) c
return common.LocalError("You're already logged in.", w, r, user)
}
pi := common.Page{common.GetTitlePhrase("register"), user, headerVars, tList, nil}
- if common.PreRenderHooks["pre_render_register"] != nil {
- if common.RunPreRenderHook("pre_render_register", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_register", w, r, &user, &pi) {
+ return nil
}
err := common.Templates.ExecuteTemplate(w, "register.html", pi)
if err != nil {
@@ -124,9 +120,7 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.U
}
confirmPassword := r.PostFormValue("confirm_password")
- if common.Dev.DebugMode {
- log.Print("Registration Attempt! Username: " + username) // TODO: Add more controls over what is logged when?
- }
+ common.DebugLog("Registration Attempt! Username: " + username) // TODO: Add more controls over what is logged when?
// Do the two inputted passwords match..?
if password != confirmPassword {
@@ -187,10 +181,8 @@ func AccountEditCritical(w http.ResponseWriter, r *http.Request, user common.Use
}
pi := common.Page{"Edit Password", user, headerVars, tList, nil}
- if common.PreRenderHooks["pre_render_account_own_edit_critical"] != nil {
- if common.RunPreRenderHook("pre_render_account_own_edit_critical", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_account_own_edit_critical", w, r, &user, &pi) {
+ return nil
}
err := common.Templates.ExecuteTemplate(w, "account_own_edit.html", pi)
if err != nil {
diff --git a/routes/misc.go b/routes/misc.go
index 39955f1e..677583ba 100644
--- a/routes/misc.go
+++ b/routes/misc.go
@@ -3,7 +3,6 @@ package routes
import (
"bytes"
"io"
- "log"
"net/http"
"strconv"
"strings"
@@ -18,9 +17,7 @@ var cacheControlMaxAge = "max-age=" + strconv.Itoa(common.Day) // TODO: Make thi
func StaticFile(w http.ResponseWriter, r *http.Request) {
file, ok := common.StaticFiles.Get(r.URL.Path)
if !ok {
- if common.Dev.DebugMode {
- log.Printf("Failed to find '%s'", r.URL.Path)
- }
+ common.DebugLogf("Failed to find '%s'", r.URL.Path)
w.WriteHeader(http.StatusNotFound)
return
}
@@ -55,12 +52,9 @@ func Overview(w http.ResponseWriter, r *http.Request, user common.User) common.R
headerVars.Zone = "overview"
pi := common.Page{common.GetTitlePhrase("overview"), user, headerVars, tList, nil}
- if common.PreRenderHooks["pre_render_overview"] != nil {
- if common.RunPreRenderHook("pre_render_overview", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_overview", w, r, &user, &pi) {
+ return nil
}
-
err := common.Templates.ExecuteTemplate(w, "overview.html", pi)
if err != nil {
return common.InternalError(err, w, r)
@@ -73,19 +67,17 @@ func CustomPage(w http.ResponseWriter, r *http.Request, user common.User, name s
if ferr != nil {
return ferr
}
+ headerVars.Zone = "custom_page"
// ! Is this safe?
if common.Templates.Lookup("page_"+name+".html") == nil {
- return common.NotFound(w, r)
+ return common.NotFound(w, r, headerVars)
}
- headerVars.Zone = "custom_page"
pi := common.Page{common.GetTitlePhrase("page"), user, headerVars, tList, nil}
// TODO: Pass the page name to the pre-render hook?
- if common.PreRenderHooks["pre_render_custom_page"] != nil {
- if common.RunPreRenderHook("pre_render_custom_page", w, r, &user, &pi) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_custom_page", w, r, &user, &pi) {
+ return nil
}
err := common.Templates.ExecuteTemplate(w, "page_"+name+".html", pi)
diff --git a/routes/moderate.go b/routes/moderate.go
index db850b86..1116e003 100644
--- a/routes/moderate.go
+++ b/routes/moderate.go
@@ -31,11 +31,9 @@ func IPSearch(w http.ResponseWriter, r *http.Request, user common.User) common.R
}
pi := common.IPSearchPage{common.GetTitlePhrase("ip-search"), user, headerVars, userList, ip}
- if common.PreRenderHooks["pre_render_ip_search"] != nil {
- if common.RunPreRenderHook("pre_render_ip_search", w, r, &user, &pi) {
+ if common.RunPreRenderHook("pre_render_ip_search", w, r, &user, &pi) {
return nil
}
- }
err = common.Templates.ExecuteTemplate(w, "ip-search.html", pi)
if err != nil {
return common.InternalError(err, w, r)
diff --git a/routes/topic.go b/routes/topic.go
index 037e55dd..42d9d9f9 100644
--- a/routes/topic.go
+++ b/routes/topic.go
@@ -15,6 +15,7 @@ import (
"strings"
"../common"
+ "../common/counters"
"../query_gen/lib"
)
@@ -54,7 +55,7 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit
// Get the topic...
topic, err := common.GetTopicUser(tid)
if err == sql.ErrNoRows {
- return common.NotFound(w, r)
+ return common.NotFound(w, r, nil) // TODO: Can we add a simplified invocation of headerVars here? This is likely to be an extremely common NotFound
} else if err != nil {
return common.InternalError(err, w, r)
}
@@ -182,16 +183,14 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit
}
}
- if common.PreRenderHooks["pre_render_view_topic"] != nil {
- if common.RunPreRenderHook("pre_render_view_topic", w, r, &user, &tpage) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_view_topic", w, r, &user, &tpage) {
+ return nil
}
err = common.RunThemeTemplate(headerVars.Theme.Name, "topic", tpage, w)
if err != nil {
return common.InternalError(err, w, r)
}
- common.TopicViewCounter.Bump(topic.ID) // TODO: Move this into the router?
+ counters.TopicViewCounter.Bump(topic.ID) // TODO: Move this into the router?
return nil
}
@@ -256,6 +255,7 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user common.User, sfid
forum := common.Forums.DirtyGet(ffid)
if forum.Name != "" && forum.Active {
fcopy := forum.Copy()
+ // TODO: Abstract this
if common.Hooks["topic_create_frow_assign"] != nil {
// TODO: Add the skip feature to all the other row based hooks?
if common.RunHook("topic_create_frow_assign", &fcopy).(bool) {
@@ -267,10 +267,8 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user common.User, sfid
}
ctpage := common.CreateTopicPage{"Create Topic", user, headerVars, forumList, fid}
- if common.PreRenderHooks["pre_render_create_topic"] != nil {
- if common.RunPreRenderHook("pre_render_create_topic", w, r, &user, &ctpage) {
- return nil
- }
+ if common.RunPreRenderHook("pre_render_create_topic", w, r, &user, &ctpage) {
+ return nil
}
err = common.RunThemeTemplate(headerVars.Theme.Name, "create_topic", ctpage, w)
@@ -382,9 +380,7 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User)
}
for _, file := range files {
- if common.Dev.DebugMode {
- log.Print("file.Filename ", file.Filename)
- }
+ common.DebugLog("file.Filename ", file.Filename)
extarr := strings.Split(file.Filename, ".")
if len(extarr) < 2 {
return common.LocalError("Bad file", w, r, user)
@@ -441,8 +437,8 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User)
}
}
- common.PostCounter.Bump()
- common.TopicCounter.Bump()
+ counters.PostCounter.Bump()
+ counters.TopicCounter.Bump()
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
return nil
}
diff --git a/routes/topic_list.go b/routes/topic_list.go
index 0aed72ae..d8f1ddc1 100644
--- a/routes/topic_list.go
+++ b/routes/topic_list.go
@@ -43,15 +43,13 @@ func TopicList(w http.ResponseWriter, r *http.Request, user common.User) common.
//log.Printf("topicList: %+v\n", topicList)
//log.Printf("forumList: %+v\n", forumList)
if len(topicList) == 0 {
- return common.NotFound(w, r)
+ return common.NotFound(w, r, headerVars)
}
pi := common.TopicsPage{common.GetTitlePhrase("topics"), user, headerVars, topicList, forumList, common.Config.DefaultForum, pageList, page, lastPage}
- if common.PreRenderHooks["pre_render_topic_list"] != nil {
- if common.RunPreRenderHook("pre_render_topic_list", w, r, &user, &pi) {
+ if common.RunPreRenderHook("pre_render_topic_list", w, r, &user, &pi) {
return nil
}
- }
err = common.RunThemeTemplate(headerVars.Theme.Name, "topics", pi, w)
if err != nil {
return common.InternalError(err, w, r)
diff --git a/schema/mssql/query_viewchunks_forums.sql b/schema/mssql/query_viewchunks_forums.sql
new file mode 100644
index 00000000..56e54bdd
--- /dev/null
+++ b/schema/mssql/query_viewchunks_forums.sql
@@ -0,0 +1,5 @@
+CREATE TABLE [viewchunks_forums] (
+ [count] int DEFAULT 0 not null,
+ [createdAt] datetime not null,
+ [forum] int not null
+);
\ No newline at end of file
diff --git a/schema/mysql/query_viewchunks_forums.sql b/schema/mysql/query_viewchunks_forums.sql
new file mode 100644
index 00000000..34c01a71
--- /dev/null
+++ b/schema/mysql/query_viewchunks_forums.sql
@@ -0,0 +1,5 @@
+CREATE TABLE `viewchunks_forums` (
+ `count` int DEFAULT 0 not null,
+ `createdAt` datetime not null,
+ `forum` int not null
+);
\ No newline at end of file
diff --git a/schema/pgsql/query_viewchunks_forums.sql b/schema/pgsql/query_viewchunks_forums.sql
new file mode 100644
index 00000000..60d539a0
--- /dev/null
+++ b/schema/pgsql/query_viewchunks_forums.sql
@@ -0,0 +1,5 @@
+CREATE TABLE `viewchunks_forums` (
+ `count` int DEFAULT 0 not null,
+ `createdAt` timestamp not null,
+ `forum` int not null
+);
\ No newline at end of file
diff --git a/template_list.go b/template_list.go
index 138a12f4..f0336911 100644
--- a/template_list.go
+++ b/template_list.go
@@ -921,7 +921,7 @@ var forums_20 = []byte(`
`)
-var forums_21 = []byte(`You don't have access to any forums.
`)
+var forums_21 = []byte(`You don't have access to any forums.
`)
var forums_22 = []byte(`
@@ -1104,7 +1104,7 @@ var topics_58 = []byte(`
`)
-var topics_59 = []byte(`There aren't any topics yet.`)
+var topics_59 = []byte(`
There aren't any topics yet.`)
var topics_60 = []byte(`
Start one?`)
var topics_61 = []byte(`
`)
var topics_62 = []byte(`
@@ -1279,7 +1279,7 @@ var forum_50 = []byte(`
`)
-var forum_51 = []byte(`There aren't any topics in this forum yet.`)
+var forum_51 = []byte(`
There aren't any topics in this forum yet.`)
var forum_52 = []byte(`
Start one?`)
var forum_54 = []byte(`
`)
diff --git a/templates/are_you_sure.html b/templates/are_you_sure.html
index df1dfa7b..c5fba07b 100644
--- a/templates/are_you_sure.html
+++ b/templates/are_you_sure.html
@@ -4,7 +4,7 @@
Are you sure?
-
diff --git a/templates/error.html b/templates/error.html
index 5572a1e0..10f1c515 100644
--- a/templates/error.html
+++ b/templates/error.html
@@ -4,7 +4,7 @@
An error has occured
-
{{.Something}}
+
{{.Something}}
{{template "footer.html" . }}
diff --git a/templates/forum.html b/templates/forum.html
index d506ca9c..b7b76ec9 100644
--- a/templates/forum.html
+++ b/templates/forum.html
@@ -98,7 +98,7 @@
{{.RelativeLastReplyAt}}
- {{else}}There aren't any topics in this forum yet.{{if .CurrentUser.Perms.CreateTopic}}
Start one?{{end}}
{{end}}
+ {{else}}There aren't any topics in this forum yet.{{if .CurrentUser.Perms.CreateTopic}}
Start one?{{end}}
{{end}}
{{if gt .LastPage 1}}
diff --git a/templates/forums.html b/templates/forums.html
index b8de4a45..3b130c36 100644
--- a/templates/forums.html
+++ b/templates/forums.html
@@ -25,7 +25,7 @@
- {{else}}You don't have access to any forums.
{{end}}
+ {{else}}You don't have access to any forums.
{{end}}
diff --git a/templates/panel_analytics_agents.html b/templates/panel_analytics_agents.html
index 44d2bc4e..aea783a0 100644
--- a/templates/panel_analytics_agents.html
+++ b/templates/panel_analytics_agents.html
@@ -22,7 +22,7 @@
{{.FriendlyAgent}}
{{.Count}} views
- {{end}}
+ {{else}}No user agents could be found in the selected time range
{{end}}
diff --git a/templates/panel_analytics_posts.html b/templates/panel_analytics_posts.html
index 1aa02f2a..16d04fbb 100644
--- a/templates/panel_analytics_posts.html
+++ b/templates/panel_analytics_posts.html
@@ -28,7 +28,7 @@
{{.Time}}
{{.Count}} views
- {{end}}
+ {{else}}No posts could be found in the selected time range
{{end}}
diff --git a/templates/panel_analytics_referrers.html b/templates/panel_analytics_referrers.html
index 9ad69dc4..72c079aa 100644
--- a/templates/panel_analytics_referrers.html
+++ b/templates/panel_analytics_referrers.html
@@ -22,7 +22,7 @@
{{.Agent}}
{{.Count}} views
- {{end}}
+ {{else}}No referrers could be found in the selected time range
{{end}}
diff --git a/templates/panel_analytics_routes.html b/templates/panel_analytics_routes.html
index ed960cc1..f2e4cbe0 100644
--- a/templates/panel_analytics_routes.html
+++ b/templates/panel_analytics_routes.html
@@ -22,7 +22,7 @@
{{.Route}}
{{.Count}} views
- {{end}}
+ {{else}}No route view counts could be found in the selected time range
{{end}}
diff --git a/templates/panel_analytics_systems.html b/templates/panel_analytics_systems.html
index 92c683b0..af80a0ea 100644
--- a/templates/panel_analytics_systems.html
+++ b/templates/panel_analytics_systems.html
@@ -22,7 +22,7 @@
{{.FriendlyAgent}}
{{.Count}} views
- {{end}}
+ {{else}}No operating systems could be found in the selected time range
{{end}}
diff --git a/templates/panel_backups.html b/templates/panel_backups.html
index ffb5fdc9..40740dd6 100644
--- a/templates/panel_backups.html
+++ b/templates/panel_backups.html
@@ -14,7 +14,7 @@
{{else}}
- There aren't any backups available at this time.
+ There aren't any backups available at this time.
{{end}}
diff --git a/templates/panel_word_filters.html b/templates/panel_word_filters.html
index 556225de..e724338b 100644
--- a/templates/panel_word_filters.html
+++ b/templates/panel_word_filters.html
@@ -19,7 +19,7 @@
{{else}}
-
+
{{end}}
diff --git a/templates/topics.html b/templates/topics.html
index 7ed93f4d..b6ebd30c 100644
--- a/templates/topics.html
+++ b/templates/topics.html
@@ -123,7 +123,7 @@
{{.RelativeLastReplyAt}}
- {{else}}There aren't any topics yet.{{if .CurrentUser.Perms.CreateTopic}}
Start one?{{end}}
{{end}}
+ {{else}}There aren't any topics yet.{{if .CurrentUser.Perms.CreateTopic}}
Start one?{{end}}
{{end}}
{{if gt .LastPage 1}}
diff --git a/themes/cosora/public/main.css b/themes/cosora/public/main.css
index c9a2feff..c86dd64b 100644
--- a/themes/cosora/public/main.css
+++ b/themes/cosora/public/main.css
@@ -232,6 +232,7 @@ ul {
margin-left: 12px;
}
/* TODO: Reduce the number of nots */
+/* TODO: Apply the property to the rowitem on the colstack_head rather than the container itself */
.rowblock:not(.topic_list):not(.forum_list):not(.post_container):not(.topic_reply_container), .colstack_head, .topic_row .rowitem, .forum_list .rowitem {
background-color: var(--element-background-color);
}
@@ -269,6 +270,15 @@ h1, h3 {
margin-bottom: 0px;
}
+.rowmsg.rowitem {
+ padding: 12px;
+}
+.topic_list .rowmsg.rowitem,
+.forum_list .rowmsg.rowitem {
+ border: 1px solid var(--element-border-color);
+ border-bottom: 2px solid var(--element-border-color);
+}
+
.colstack {
display: flex;
}
@@ -692,8 +702,8 @@ textarea {
margin-bottom: 8px;
padding: 4px;
display: flex;
- border: 1px solid var(--element-border-color);
- border-bottom: 2px solid var(--element-border-color);
+ border: 1px solid var(--element-border-color);
+ border-bottom: 2px solid var(--element-border-color);
}
.rowlist .rowitem {
background-color: var(--element-background-color);
diff --git a/themes/cosora/public/panel.css b/themes/cosora/public/panel.css
index 0a126829..1094412f 100644
--- a/themes/cosora/public/panel.css
+++ b/themes/cosora/public/panel.css
@@ -39,12 +39,15 @@
}
.colstack_right {
margin-right: 14px;
- margin-top: -4px;
+ /*margin-top: -4px;*/
margin-bottom: 14px;
}
.footer {
margin-top: 0px;
}
+.colstack_right .colstack_head:not(:first-child) {
+ margin-top: 14px;
+}
.complex_rowlist {
background-color: inherit !important;
@@ -210,4 +213,10 @@
.pageset {
margin-left: 16px;
+}
+
+@media(max-width: 999px) {
+ .colstack_left {
+ margin-top: -14.5px;
+ }
}
\ No newline at end of file
diff --git a/themes/tempra-conflux/public/panel.css b/themes/tempra-conflux/public/panel.css
index c2621aa0..33818c8d 100644
--- a/themes/tempra-conflux/public/panel.css
+++ b/themes/tempra-conflux/public/panel.css
@@ -1,4 +1,10 @@
-/* Control Panel */
+/*.submenu {
+ padding-left: 18px;
+}*/
+.submenu:before {
+ content:"–";
+ margin-right: 8px;
+}
.edit_button:before {
content: "Edit";
@@ -97,6 +103,18 @@
padding-right: 2px;
}
+.ct_chart {
+ padding-left: 10px;
+ padding-top: 18px;
+ padding-bottom: 2px;
+ padding-right: 10px;
+ margin-bottom: 12px;
+
+ background-color: white;
+ border: 1px solid var(--main-border-color);
+ border-bottom: 1.5px inset var(--main-border-color);
+}
+
@media(max-width: 1300px) {
.theme_row { background-image: none !important; }
}
diff --git a/themes/tempra-simple/public/media.partial.css b/themes/tempra-simple/public/media.partial.css
index 0f8fe378..40b2195a 100644
--- a/themes/tempra-simple/public/media.partial.css
+++ b/themes/tempra-simple/public/media.partial.css
@@ -20,7 +20,7 @@
}
ul {
height: 30px;
- margin-top: 8px;
+ margin-top: 14px;
}
.menu_left, .menu_right { padding-right: 9px; }
.menu_alerts {
@@ -30,8 +30,8 @@
}
body {
- padding-left: 4px;
- padding-right: 4px;
+ padding-left: 12px;
+ padding-right: 12px;
margin: 0px !important;
width: 100% !important;
height: 100% !important;