Moved the counters to their own package.
De-duped some of the logging code. Added per-route state to the not found errors. Exported debugDetail, debugDetailf, debugLog, and debugLogf. Tweaked the padding on Tempra Simple. Added panel submenus to Tempra Conflux. Added Chart CSS to Tempra Conflux. Fixed the padding and margins for the Control Panel in Cosora. Made Cosora's Control Panel a little more tablet friendly. Added the rowmsg CSS class to better style message rows. Removed the repetitive guard code for the pre-render hooks. Removed the repetitive guard code for the string-string hooks. We now capture views for routes.StaticFile Added the move action to the moderation logs. Added the viewchunks_forums table. Began work on Per-forum Views. I probably missed a few things in this changelog.
This commit is contained in:
parent
be47066770
commit
60964868d4
12
alerts.go
12
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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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()
|
||||
}
|
|
@ -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()
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -238,11 +238,9 @@ 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
|
||||
}
|
||||
}
|
||||
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
||||
if err != nil {
|
||||
LogError(err)
|
||||
|
@ -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,11 +287,9 @@ 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
|
||||
}
|
||||
}
|
||||
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
||||
if err != nil {
|
||||
LogError(err)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -173,9 +173,7 @@ func PreparseMessage(msg string) string {
|
|||
msg = strings.Replace(msg, "</p>", "", -1)
|
||||
msg = strings.Replace(msg, "<br>", "\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 = 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", "<br>", -1)
|
||||
if Sshooks["parse_assign"] != nil {
|
||||
msg = RunSshook("parse_assign", msg)
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
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))
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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` = ?")
|
||||
|
|
|
@ -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` = ?")
|
||||
|
|
246
gen_router.go
246
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)
|
||||
}
|
||||
}
|
||||
|
|
19
main.go
19
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
|
||||
}
|
||||
|
|
|
@ -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,11 +480,9 @@ 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
|
||||
}
|
||||
}
|
||||
err = common.Templates.ExecuteTemplate(w, "account_own_edit.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -498,11 +497,9 @@ 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
|
||||
}
|
||||
}
|
||||
err := common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -573,11 +570,9 @@ 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
|
||||
}
|
||||
}
|
||||
err = common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -592,11 +587,9 @@ 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
|
||||
}
|
||||
}
|
||||
err := common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -619,11 +612,9 @@ 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
|
||||
}
|
||||
}
|
||||
err = common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -674,11 +665,9 @@ 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
|
||||
}
|
||||
}
|
||||
err = common.Templates.ExecuteTemplate(w, "account_own_edit_email.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -746,11 +735,9 @@ 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
|
||||
}
|
||||
}
|
||||
err = common.Templates.ExecuteTemplate(w, "account_own_edit_email.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -31,11 +31,9 @@ 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
|
||||
}
|
||||
}
|
||||
err := common.Templates.ExecuteTemplate(w, tmplName+".html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -253,11 +251,9 @@ 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
|
||||
}
|
||||
}
|
||||
err = common.Templates.ExecuteTemplate(w, "are_you_sure.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -330,11 +326,9 @@ 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
|
||||
}
|
||||
}
|
||||
err = common.Templates.ExecuteTemplate(w, "panel-forum-edit.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -493,11 +487,9 @@ 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
|
||||
}
|
||||
}
|
||||
err = common.Templates.ExecuteTemplate(w, "panel-forum-edit-perms.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -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,11 +1850,9 @@ 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
|
||||
}
|
||||
}
|
||||
err = common.Templates.ExecuteTemplate(w, "panel-user-edit.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -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,11 +2042,9 @@ 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
|
||||
}
|
||||
}
|
||||
err = common.Templates.ExecuteTemplate(w, "panel-group-edit.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -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,11 +2128,9 @@ 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
|
||||
}
|
||||
}
|
||||
err = common.Templates.ExecuteTemplate(w, "panel-group-edit-perms.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -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,10 +2481,12 @@ func handleUnknownTopic(topic *common.Topic, err error) *common.Topic {
|
|||
return topic
|
||||
}
|
||||
|
||||
func modlogsElementType(action string, elementType string, elementID int, actor *common.User) (out string) {
|
||||
switch elementType {
|
||||
case "topic":
|
||||
topic := handleUnknownTopic(common.Topics.Get(elementID))
|
||||
// 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 <a href='%s'>%s</a>", elementID, actor.Link, actor.Name)
|
||||
}
|
||||
|
||||
switch action {
|
||||
case "lock":
|
||||
out = "<a href='%s'>%s</a> was locked by <a href='%s'>%s</a>"
|
||||
|
@ -2500,10 +2496,19 @@ func modlogsElementType(action string, elementType string, elementID int, actor
|
|||
out = "<a href='%s'>%s</a> was pinned by <a href='%s'>%s</a>"
|
||||
case "unstick":
|
||||
out = "<a href='%s'>%s</a> was unpinned by <a href='%s'>%s</a>"
|
||||
case "delete":
|
||||
return fmt.Sprintf("Topic #%d was deleted by <a href='%s'>%s</a>", elementID, actor.Link, actor.Name)
|
||||
case "move":
|
||||
out = "<a href='%s'>%s</a> was moved by <a href='%s'>%s</a>" // 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 <a href='%s'>%s</a>", action, elementType, actor.Link, actor.Name)
|
||||
}
|
||||
out = fmt.Sprintf(out, topic.Link, topic.Title, 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))
|
||||
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 <a href='%s'>%s</a> was deleted by <a href='%s'>%s</a>", topic.Link, topic.Title, actor.Link, actor.Name)
|
||||
}
|
||||
}
|
||||
|
||||
if out == "" {
|
||||
out = fmt.Sprintf("Unknown action '%s' on elementType '%s' by <a href='%s'>%s</a>", action, elementType, actor.Link, actor.Name)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -433,7 +433,6 @@ func createTables(adapter qgen.Adapter) error {
|
|||
[]qgen.DBTableKey{},
|
||||
)
|
||||
|
||||
/*
|
||||
qgen.Install.CreateTable("viewchunks_forums", "", "",
|
||||
[]qgen.DBTableColumn{
|
||||
qgen.DBTableColumn{"count", "int", 0, false, false, "0"},
|
||||
|
@ -442,7 +441,6 @@ func createTables(adapter qgen.Adapter) error {
|
|||
},
|
||||
[]qgen.DBTableKey{},
|
||||
)
|
||||
*/
|
||||
|
||||
qgen.Install.CreateTable("topicchunks", "", "",
|
||||
[]qgen.DBTableColumn{
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
`
|
||||
|
|
14
routes.go
14
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,11 +130,9 @@ 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
|
||||
}
|
||||
}
|
||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "forum", pi, w)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -180,19 +178,15 @@ 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)
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "forums", pi, w)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -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,11 +282,9 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "profile", ppage, w)
|
||||
if err != nil {
|
||||
|
|
|
@ -22,11 +22,9 @@ 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
|
||||
}
|
||||
}
|
||||
err := common.Templates.ExecuteTemplate(w, "login.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -83,11 +81,9 @@ 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
|
||||
}
|
||||
}
|
||||
err := common.Templates.ExecuteTemplate(w, "register.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -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,11 +181,9 @@ 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
|
||||
}
|
||||
}
|
||||
err := common.Templates.ExecuteTemplate(w, "account_own_edit.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
err := common.Templates.ExecuteTemplate(w, "overview.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
@ -73,20 +67,18 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
err := common.Templates.ExecuteTemplate(w, "page_"+name+".html", pi)
|
||||
if err != nil {
|
||||
|
|
|
@ -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) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
err = common.Templates.ExecuteTemplate(w, "ip-search.html", pi)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
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,11 +267,9 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "create_topic", ctpage, w)
|
||||
if err != nil {
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "topics", pi, w)
|
||||
if err != nil {
|
||||
return common.InternalError(err, w, r)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
CREATE TABLE [viewchunks_forums] (
|
||||
[count] int DEFAULT 0 not null,
|
||||
[createdAt] datetime not null,
|
||||
[forum] int not null
|
||||
);
|
|
@ -0,0 +1,5 @@
|
|||
CREATE TABLE `viewchunks_forums` (
|
||||
`count` int DEFAULT 0 not null,
|
||||
`createdAt` datetime not null,
|
||||
`forum` int not null
|
||||
);
|
|
@ -0,0 +1,5 @@
|
|||
CREATE TABLE `viewchunks_forums` (
|
||||
`count` int DEFAULT 0 not null,
|
||||
`createdAt` timestamp not null,
|
||||
`forum` int not null
|
||||
);
|
|
@ -921,7 +921,7 @@ var forums_20 = []byte(`
|
|||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
`)
|
||||
var forums_21 = []byte(`<div class="rowitem passive">You don't have access to any forums.</div>`)
|
||||
var forums_21 = []byte(`<div class="rowitem passive rowmsg">You don't have access to any forums.</div>`)
|
||||
var forums_22 = []byte(`
|
||||
</div>
|
||||
|
||||
|
@ -1104,7 +1104,7 @@ var topics_58 = []byte(`</span>
|
|||
</span>
|
||||
</div>
|
||||
</div>`)
|
||||
var topics_59 = []byte(`<div class="rowitem passive">There aren't any topics yet.`)
|
||||
var topics_59 = []byte(`<div class="rowitem passive rowmsg">There aren't any topics yet.`)
|
||||
var topics_60 = []byte(` <a href="/topics/create/">Start one?</a>`)
|
||||
var topics_61 = []byte(`</div>`)
|
||||
var topics_62 = []byte(`
|
||||
|
@ -1279,7 +1279,7 @@ var forum_50 = []byte(`</span>
|
|||
</span>
|
||||
</div>
|
||||
</div>`)
|
||||
var forum_51 = []byte(`<div class="rowitem passive">There aren't any topics in this forum yet.`)
|
||||
var forum_51 = []byte(`<div class="rowitem passive rowmsg">There aren't any topics in this forum yet.`)
|
||||
var forum_52 = []byte(` <a href="/topics/create/`)
|
||||
var forum_53 = []byte(`">Start one?</a>`)
|
||||
var forum_54 = []byte(`</div>`)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div class="rowitem"><h1>Are you sure?</h1></div>
|
||||
</div>
|
||||
<div class="rowblock">
|
||||
<div class="rowitem passive">{{.Something.Message}}<br /><br />
|
||||
<div class="rowitem passive rowmsg">{{.Something.Message}}<br /><br />
|
||||
<a class="username" href="{{.Something.URL}}?session={{.CurrentUser.Session}}">Continue</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div class="rowitem"><h1>An error has occured</h1></div>
|
||||
</div>
|
||||
<div class="rowblock">
|
||||
<div class="rowitem passive">{{.Something}}</div>
|
||||
<div class="rowitem passive rowmsg">{{.Something}}</div>
|
||||
</div>
|
||||
</main>
|
||||
{{template "footer.html" . }}
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
<span class="rowsmall lastReplyAt">{{.RelativeLastReplyAt}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>{{else}}<div class="rowitem passive">There aren't any topics in this forum yet.{{if .CurrentUser.Perms.CreateTopic}} <a href="/topics/create/{{.Forum.ID}}">Start one?</a>{{end}}</div>{{end}}
|
||||
</div>{{else}}<div class="rowitem passive rowmsg">There aren't any topics in this forum yet.{{if .CurrentUser.Perms.CreateTopic}} <a href="/topics/create/{{.Forum.ID}}">Start one?</a>{{end}}</div>{{end}}
|
||||
</div>
|
||||
|
||||
{{if gt .LastPage 1}}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
</span>
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
{{else}}<div class="rowitem passive">You don't have access to any forums.</div>{{end}}
|
||||
{{else}}<div class="rowitem passive rowmsg">You don't have access to any forums.</div>{{end}}
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<a href="/panel/analytics/agent/{{.Agent}}" class="panel_upshift">{{.FriendlyAgent}}</a>
|
||||
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
||||
</div>
|
||||
{{end}}
|
||||
{{else}}<div class="rowitem passive rowmsg">No user agents could be found in the selected time range</div>{{end}}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<a class="panel_upshift unix_to_24_hour_time">{{.Time}}</a>
|
||||
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
||||
</div>
|
||||
{{end}}
|
||||
{{else}}<div class="rowitem passive rowmsg">No posts could be found in the selected time range</div>{{end}}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<a href="/panel/analytics/referrer/{{.Agent}}" class="panel_upshift">{{.Agent}}</a>
|
||||
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
||||
</div>
|
||||
{{end}}
|
||||
{{else}}<div class="rowitem passive rowmsg">No referrers could be found in the selected time range</div>{{end}}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<a href="/panel/analytics/route/{{.Route}}" class="panel_upshift">{{.Route}}</a>
|
||||
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
||||
</div>
|
||||
{{end}}
|
||||
{{else}}<div class="rowitem passive rowmsg">No route view counts could be found in the selected time range</div>{{end}}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<a href="/panel/analytics/system/{{.Agent}}" class="panel_upshift">{{.FriendlyAgent}}</a>
|
||||
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
||||
</div>
|
||||
{{end}}
|
||||
{{else}}<div class="rowitem passive rowmsg">No operating systems could be found in the selected time range</div>{{end}}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</span>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="rowitem">There aren't any backups available at this time.</div>
|
||||
<div class="rowitem rowmsg">There aren't any backups available at this time.</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</main>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
</span>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="rowitem editable_parent">
|
||||
<div class="rowitem editable_parent rowmsg">
|
||||
<a>You don't have any word filters yet.</a>
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
@ -123,7 +123,7 @@
|
|||
<span class="rowsmall lastReplyAt">{{.RelativeLastReplyAt}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>{{else}}<div class="rowitem passive">There aren't any topics yet.{{if .CurrentUser.Perms.CreateTopic}} <a href="/topics/create/">Start one?</a>{{end}}</div>{{end}}
|
||||
</div>{{else}}<div class="rowitem passive rowmsg">There aren't any topics yet.{{if .CurrentUser.Perms.CreateTopic}} <a href="/topics/create/">Start one?</a>{{end}}</div>{{end}}
|
||||
</div>
|
||||
|
||||
{{if gt .LastPage 1}}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -211,3 +214,9 @@
|
|||
.pageset {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
@media(max-width: 999px) {
|
||||
.colstack_left {
|
||||
margin-top: -14.5px;
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue