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"
|
act = "created a new topic"
|
||||||
topic, err := common.Topics.Get(elementID)
|
topic, err := common.Topics.Get(elementID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if common.Dev.DebugMode {
|
common.DebugLogf("Unable to find linked topic %d", elementID)
|
||||||
log.Print("Unable to find linked topic " + strconv.Itoa(elementID))
|
|
||||||
}
|
|
||||||
return "", errors.New("Unable to find the linked topic")
|
return "", errors.New("Unable to find the linked topic")
|
||||||
}
|
}
|
||||||
url = topic.Link
|
url = topic.Link
|
||||||
|
@ -73,9 +71,7 @@ func buildAlert(asid int, event string, elementType string, actorID int, targetU
|
||||||
case "topic":
|
case "topic":
|
||||||
topic, err := common.Topics.Get(elementID)
|
topic, err := common.Topics.Get(elementID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if common.Dev.DebugMode {
|
common.DebugLogf("Unable to find linked topic %d", elementID)
|
||||||
log.Print("Unable to find linked topic " + strconv.Itoa(elementID))
|
|
||||||
}
|
|
||||||
return "", errors.New("Unable to find the linked topic")
|
return "", errors.New("Unable to find the linked topic")
|
||||||
}
|
}
|
||||||
url = topic.Link
|
url = topic.Link
|
||||||
|
@ -87,9 +83,7 @@ func buildAlert(asid int, event string, elementType string, actorID int, targetU
|
||||||
case "user":
|
case "user":
|
||||||
targetUser, err = common.Users.Get(elementID)
|
targetUser, err = common.Users.Get(elementID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if common.Dev.DebugMode {
|
common.DebugLogf("Unable to find target user %d", elementID)
|
||||||
log.Print("Unable to find target user " + strconv.Itoa(elementID))
|
|
||||||
}
|
|
||||||
return "", errors.New("Unable to find the target user")
|
return "", errors.New("Unable to find the target user")
|
||||||
}
|
}
|
||||||
area = targetUser.Name
|
area = targetUser.Name
|
||||||
|
|
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -79,10 +78,9 @@ func sitemapSwitch(w http.ResponseWriter, r *http.Request) common.RouteError {
|
||||||
spath = strings.TrimSuffix(spath, ".xml")
|
spath = strings.TrimSuffix(spath, ".xml")
|
||||||
page, err := strconv.Atoi(spath)
|
page, err := strconv.Atoi(spath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if common.Dev.DebugMode {
|
// ? What's this? Do we need it? Was it just a quick trace?
|
||||||
log.Printf("Unable to convert string '%s' to integer in fuzzy route", spath)
|
common.DebugLogf("Unable to convert string '%s' to integer in fuzzy route", spath)
|
||||||
}
|
return common.NotFound(w, r, nil)
|
||||||
return common.NotFound(w, r)
|
|
||||||
}
|
}
|
||||||
return fuzzy.Handle(w, r, page)
|
return fuzzy.Handle(w, r, page)
|
||||||
}
|
}
|
||||||
|
@ -90,7 +88,7 @@ func sitemapSwitch(w http.ResponseWriter, r *http.Request) common.RouteError {
|
||||||
|
|
||||||
route, ok := sitemapRoutes[path]
|
route, ok := sitemapRoutes[path]
|
||||||
if !ok {
|
if !ok {
|
||||||
return common.NotFound(w, r)
|
return common.NotFound(w, r, nil)
|
||||||
}
|
}
|
||||||
return route(w, r)
|
return route(w, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,60 +84,26 @@ func (inits dbInits) Add(init ...func(acc *qgen.Accumulator) error) {
|
||||||
DbInits = dbInits(append(DbInits, init...))
|
DbInits = dbInits(append(DbInits, init...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func debugDetail(args ...interface{}) {
|
func DebugDetail(args ...interface{}) {
|
||||||
if Dev.SuperDebug {
|
if Dev.SuperDebug {
|
||||||
log.Print(args...)
|
log.Print(args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func debugDetailf(str string, args ...interface{}) {
|
func DebugDetailf(str string, args ...interface{}) {
|
||||||
if Dev.SuperDebug {
|
if Dev.SuperDebug {
|
||||||
log.Printf(str, args...)
|
log.Printf(str, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func debugLog(args ...interface{}) {
|
func DebugLog(args ...interface{}) {
|
||||||
if Dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print(args...)
|
log.Print(args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func debugLogf(str string, args ...interface{}) {
|
func DebugLogf(str string, args ...interface{}) {
|
||||||
if Dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Printf(str, args...)
|
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 (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"../query_gen/lib"
|
".."
|
||||||
|
"../../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ReferrerTracker *DefaultReferrerTracker
|
var ReferrerTracker *DefaultReferrerTracker
|
||||||
|
@ -35,9 +36,9 @@ func NewDefaultReferrerTracker() (*DefaultReferrerTracker, error) {
|
||||||
even: make(map[string]*ReferrerItem),
|
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
|
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)
|
common.AddScheduledFifteenMinuteTask(refTracker.Tick)
|
||||||
//AddScheduledSecondTask(refTracker.Tick)
|
//common.AddScheduledSecondTask(refTracker.Tick)
|
||||||
AddShutdownTask(refTracker.Tick)
|
common.AddShutdownTask(refTracker.Tick)
|
||||||
return refTracker, acc.FirstError()
|
return refTracker, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +93,7 @@ func (ref *DefaultReferrerTracker) insertChunk(referrer string, count int64) err
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return nil
|
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)
|
_, err := ref.insert.Exec(count, referrer)
|
||||||
return err
|
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
|
// TODO: Add support for TLS
|
||||||
func SendEmail(email string, subject string, msg string) bool {
|
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?
|
// 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 {
|
if Vhooks["email_send_intercept"] != nil {
|
||||||
return Vhooks["email_send_intercept"](email, subject, msg).(bool)
|
return Vhooks["email_send_intercept"](email, subject, msg).(bool)
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,10 +238,8 @@ func LoginRequiredJS(w http.ResponseWriter, r *http.Request, user User) RouteErr
|
||||||
func SecurityError(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
func SecurityError(w http.ResponseWriter, r *http.Request, user User) RouteError {
|
||||||
w.WriteHeader(403)
|
w.WriteHeader(403)
|
||||||
pi := Page{"Security Error", user, DefaultHeaderVar(), tList, "There was a security issue with your request."}
|
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) {
|
||||||
if RunPreRenderHook("pre_render_security_error", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -253,22 +251,28 @@ func SecurityError(w http.ResponseWriter, r *http.Request, user User) RouteError
|
||||||
// NotFound is used when the requested page doesn't exist
|
// NotFound is used when the requested page doesn't exist
|
||||||
// ? - Add a JSQ and JS version of this?
|
// ? - Add a JSQ and JS version of this?
|
||||||
// ? - Add a user parameter?
|
// ? - Add a user parameter?
|
||||||
func NotFound(w http.ResponseWriter, r *http.Request) RouteError {
|
func NotFound(w http.ResponseWriter, r *http.Request, headerVars *HeaderVars) RouteError {
|
||||||
return CustomError("The requested page doesn't exist.", 404, "Not Found", w, r, GuestUser)
|
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
|
// 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)
|
w.WriteHeader(errcode)
|
||||||
pi := Page{errtitle, user, DefaultHeaderVar(), tList, errmsg}
|
pi := Page{errtitle, user, headerVars, tList, errmsg}
|
||||||
handleErrorTemplate(w, r, pi)
|
handleErrorTemplate(w, r, pi)
|
||||||
return HandledRouteError()
|
return HandledRouteError()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomErrorJSQ is a version of CustomError which lets us handle both JSON and regular pages depending on how it's being accessed
|
// 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 {
|
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)
|
return CustomErrorJS(errmsg, errcode, w, r, user)
|
||||||
}
|
}
|
||||||
|
@ -283,10 +287,8 @@ func CustomErrorJS(errmsg string, errcode int, w http.ResponseWriter, r *http.Re
|
||||||
func handleErrorTemplate(w http.ResponseWriter, r *http.Request, pi Page) {
|
func handleErrorTemplate(w http.ResponseWriter, r *http.Request, pi Page) {
|
||||||
//LogError(errors.New("error happened"))
|
//LogError(errors.New("error happened"))
|
||||||
// TODO: What to do about this hook?
|
// TODO: What to do about this hook?
|
||||||
if PreRenderHooks["pre_render_error"] != nil {
|
if RunPreRenderHook("pre_render_error", w, r, &pi.CurrentUser, &pi) {
|
||||||
if RunPreRenderHook("pre_render_error", w, r, &pi.CurrentUser, &pi) {
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
err := Templates.ExecuteTemplate(w, "error.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -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)})
|
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
|
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)})
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package common
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"../query_gen/lib"
|
"../query_gen/lib"
|
||||||
|
@ -46,15 +45,15 @@ func (fps *MemoryForumPermsStore) Init() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
debugDetail("fids: ", fids)
|
DebugDetail("fids: ", fids)
|
||||||
|
|
||||||
rows, err := fps.get.Query()
|
rows, err := fps.get.Query()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
debugLog("Adding the forum permissions")
|
DebugLog("Adding the forum permissions")
|
||||||
debugDetail("forumPerms[gid][fid]")
|
DebugDetail("forumPerms[gid][fid]")
|
||||||
|
|
||||||
forumPerms = make(map[int]map[int]*ForumPerms)
|
forumPerms = make(map[int]map[int]*ForumPerms)
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
|
@ -74,9 +73,9 @@ func (fps *MemoryForumPermsStore) Init() error {
|
||||||
forumPerms[gid] = make(map[int]*ForumPerms)
|
forumPerms[gid] = make(map[int]*ForumPerms)
|
||||||
}
|
}
|
||||||
|
|
||||||
debugDetail("gid: ", gid)
|
DebugDetail("gid: ", gid)
|
||||||
debugDetail("fid: ", fid)
|
DebugDetail("fid: ", fid)
|
||||||
debugDetailf("perms: %+v\n", pperms)
|
DebugDetailf("perms: %+v\n", pperms)
|
||||||
forumPerms[gid][fid] = pperms
|
forumPerms[gid][fid] = pperms
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +83,7 @@ func (fps *MemoryForumPermsStore) Init() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fps *MemoryForumPermsStore) parseForumPerm(perms []byte) (pperms *ForumPerms, err error) {
|
func (fps *MemoryForumPermsStore) parseForumPerm(perms []byte) (pperms *ForumPerms, err error) {
|
||||||
debugDetail("perms: ", string(perms))
|
DebugDetail("perms: ", string(perms))
|
||||||
pperms = BlankForumPerms()
|
pperms = BlankForumPerms()
|
||||||
err = json.Unmarshal(perms, &pperms)
|
err = json.Unmarshal(perms, &pperms)
|
||||||
pperms.ExtData = make(map[string]bool)
|
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 {
|
func (fps *MemoryForumPermsStore) Reload(fid int) error {
|
||||||
fps.updateMutex.Lock()
|
fps.updateMutex.Lock()
|
||||||
defer fps.updateMutex.Unlock()
|
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()
|
fids, err := Forums.GetAllIDs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -159,22 +158,20 @@ func (fps *MemoryForumPermsStore) cascadePermSetToGroups(forumPerms map[int]map[
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, group := range groups {
|
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.Forums = []*ForumPerms{BlankForumPerms()}
|
||||||
group.CanSee = []int{}
|
group.CanSee = []int{}
|
||||||
fps.cascadePermSetToGroup(forumPerms, group, fids)
|
fps.cascadePermSetToGroup(forumPerms, group, fids)
|
||||||
|
|
||||||
if Dev.SuperDebug {
|
DebugDetailf("group.CanSee (length %d): %+v \n", len(group.CanSee), group.CanSee)
|
||||||
log.Printf("group.CanSee (length %d): %+v \n", len(group.CanSee), group.CanSee)
|
DebugDetailf("group.Forums (length %d): %+v\n", len(group.Forums), group.Forums)
|
||||||
log.Printf("group.Forums (length %d): %+v\n", len(group.Forums), group.Forums)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[int]*ForumPerms, group *Group, fids []int) {
|
func (fps *MemoryForumPermsStore) cascadePermSetToGroup(forumPerms map[int]map[int]*ForumPerms, group *Group, fids []int) {
|
||||||
for _, fid := range fids {
|
for _, fid := range fids {
|
||||||
debugDetailf("Forum #%+v\n", fid)
|
DebugDetailf("Forum #%+v\n", fid)
|
||||||
forumPerm, ok := forumPerms[group.ID][fid]
|
forumPerm, ok := forumPerms[group.ID][fid]
|
||||||
if ok {
|
if ok {
|
||||||
//log.Printf("Overriding permissions for forum #%d",fid)
|
//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)
|
group.CanSee = append(group.CanSee, fid)
|
||||||
}
|
}
|
||||||
|
|
||||||
debugDetail("group.ID: ", group.ID)
|
DebugDetail("group.ID: ", group.ID)
|
||||||
debugDetailf("forumPerm: %+v\n", forumPerm)
|
DebugDetailf("forumPerm: %+v\n", forumPerm)
|
||||||
debugDetail("group.CanSee: ", group.CanSee)
|
DebugDetail("group.CanSee: ", group.CanSee)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ func (mfs *MemoryForumStore) LoadForums() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if forum.Name == "" {
|
if forum.Name == "" {
|
||||||
debugLog("Adding a placeholder forum")
|
DebugLog("Adding a placeholder forum")
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Adding the '%s' forum", forum.Name)
|
log.Printf("Adding the '%s' forum", forum.Name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ func (mgs *MemoryGroupStore) LoadGroups() error {
|
||||||
}
|
}
|
||||||
mgs.groupCount = i
|
mgs.groupCount = i
|
||||||
|
|
||||||
debugLog("Binding the Not Loggedin Group")
|
DebugLog("Binding the Not Loggedin Group")
|
||||||
GuestPerms = mgs.dirtyGetUnsafe(6).Perms
|
GuestPerms = mgs.dirtyGetUnsafe(6).Perms
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -162,9 +162,7 @@ func (mgs *MemoryGroupStore) initGroup(group *Group) error {
|
||||||
log.Print("bad group perms: ", group.PermissionsText)
|
log.Print("bad group perms: ", group.PermissionsText)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if Dev.DebugMode {
|
DebugLogf(group.Name+": %+v\n", group.Perms)
|
||||||
log.Printf(group.Name+": %+v\n", group.Perms)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(group.PluginPermsText, &group.PluginPerms)
|
err = json.Unmarshal(group.PluginPermsText, &group.PluginPerms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -172,7 +170,7 @@ func (mgs *MemoryGroupStore) initGroup(group *Group) error {
|
||||||
log.Print("bad group plugin perms: ", group.PluginPermsText)
|
log.Print("bad group plugin perms: ", group.PluginPermsText)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
debugLogf(group.Name+": %+v\n", group.PluginPerms)
|
DebugLogf(group.Name+": %+v\n", group.PluginPerms)
|
||||||
|
|
||||||
//group.Perms.ExtData = make(map[string]bool)
|
//group.Perms.ExtData = make(map[string]bool)
|
||||||
// TODO: Can we optimise the bit where this cascades down to the user now?
|
// 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, "</p>", "", -1)
|
||||||
msg = strings.Replace(msg, "<br>", "\n\n", -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
|
msg = strings.TrimSpace(msg) // There are a few useful cases for having spaces, but I'd like to stop the WYSIWYG from inserting random lines here and there
|
||||||
if Sshooks["preparse_preassign"] != nil {
|
msg = RunSshook("preparse_preassign", msg)
|
||||||
msg = RunSshook("preparse_preassign", msg)
|
|
||||||
}
|
|
||||||
msg = html.EscapeString(msg)
|
msg = html.EscapeString(msg)
|
||||||
msg = strings.Replace(msg, " ", "", -1)
|
msg = strings.Replace(msg, " ", "", -1)
|
||||||
|
|
||||||
|
@ -573,9 +571,7 @@ func ParseMessage(msg string, sectionID int, sectionType string /*, user User*/)
|
||||||
//log.Print("msg",`"`+msg+`"`)
|
//log.Print("msg",`"`+msg+`"`)
|
||||||
|
|
||||||
msg = strings.Replace(msg, "\n", "<br>", -1)
|
msg = strings.Replace(msg, "\n", "<br>", -1)
|
||||||
if Sshooks["parse_assign"] != nil {
|
msg = RunSshook("parse_assign", msg)
|
||||||
msg = RunSshook("parse_assign", msg)
|
|
||||||
}
|
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,8 +136,8 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GuestUser.Perms = GuestPerms
|
GuestUser.Perms = GuestPerms
|
||||||
debugLogf("Guest Perms: %+v\n", GuestPerms)
|
DebugLogf("Guest Perms: %+v\n", GuestPerms)
|
||||||
debugLogf("All Perms: %+v\n", AllPerms)
|
DebugLogf("All Perms: %+v\n", AllPerms)
|
||||||
}
|
}
|
||||||
|
|
||||||
func StripInvalidGroupForumPreset(preset string) string {
|
func StripInvalidGroupForumPreset(preset string) string {
|
||||||
|
|
|
@ -65,9 +65,7 @@ func InitPhrases() error {
|
||||||
|
|
||||||
var ext = filepath.Ext("/langs/" + path)
|
var ext = filepath.Ext("/langs/" + path)
|
||||||
if ext != ".json" {
|
if ext != ".json" {
|
||||||
if Dev.DebugMode {
|
log.Printf("Found a '%s' in /langs/", ext)
|
||||||
log.Printf("Found a '%s' in /langs/", ext)
|
|
||||||
}
|
|
||||||
return nil
|
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
|
// We probably don't need this, but it might be useful in case of bugs in BulkCascadeGetMap
|
||||||
if sidList == "" {
|
if sidList == "" {
|
||||||
|
// TODO: Bulk log this
|
||||||
if Dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("This data is sampled later in the BulkCascadeGetMap function, so it might miss the cached IDs")
|
log.Print("This data is sampled later in the BulkCascadeGetMap function, so it might miss the cached IDs")
|
||||||
log.Print("idCount", idCount)
|
log.Print("idCount", idCount)
|
||||||
|
|
|
@ -52,7 +52,7 @@ func forumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fid int)
|
||||||
return headerVars, rerr
|
return headerVars, rerr
|
||||||
}
|
}
|
||||||
if !Forums.Exists(fid) {
|
if !Forums.Exists(fid) {
|
||||||
return headerVars, NotFound(w, r)
|
return headerVars, NotFound(w, r, headerVars)
|
||||||
}
|
}
|
||||||
|
|
||||||
if VhookSkippable["forum_check_pre_perms"] != nil {
|
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
|
// TODO: Reuse this code more
|
||||||
if r.ContentLength > int64(maxFileSize) {
|
if r.ContentLength > int64(maxFileSize) {
|
||||||
size, unit := ConvertByteUnit(float64(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))
|
r.Body = http.MaxBytesReader(w, r.Body, int64(maxFileSize))
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ func InitThemes() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if theme.FullImage != "" {
|
if theme.FullImage != "" {
|
||||||
debugLog("Adding theme image")
|
DebugLog("Adding theme image")
|
||||||
err = StaticFiles.Add("./themes/"+themeName+"/"+theme.FullImage, "./themes/"+themeName)
|
err = StaticFiles.Add("./themes/"+themeName+"/"+theme.FullImage, "./themes/"+themeName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -206,7 +206,7 @@ func (theme *Theme) LoadStaticFiles() error {
|
||||||
func (theme *Theme) AddThemeStaticFiles() 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?
|
// 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 {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,7 @@ func (theme *Theme) AddThemeStaticFiles() error {
|
||||||
gzipData := compressBytesGzip(data)
|
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)})
|
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
|
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
|
// We probably don't need this, but it might be useful in case of bugs in BulkCascadeGetMap
|
||||||
if sidList == "" {
|
if sidList == "" {
|
||||||
|
// TODO: Bulk log this
|
||||||
if Dev.DebugMode {
|
if Dev.DebugMode {
|
||||||
log.Print("This data is sampled later in the BulkCascadeGetMap function, so it might miss the cached IDs")
|
log.Print("This data is sampled later in the BulkCascadeGetMap function, so it might miss the cached IDs")
|
||||||
log.Print("idCount", idCount)
|
log.Print("idCount", idCount)
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -215,11 +214,9 @@ func InitWidgets() error {
|
||||||
Docks.Footer = footerWidgets
|
Docks.Footer = footerWidgets
|
||||||
widgetUpdateMutex.Unlock()
|
widgetUpdateMutex.Unlock()
|
||||||
|
|
||||||
if Dev.SuperDebug {
|
DebugLog("Docks.LeftSidebar", Docks.LeftSidebar)
|
||||||
log.Print("Docks.LeftSidebar", Docks.LeftSidebar)
|
DebugLog("Docks.RightSidebar", Docks.RightSidebar)
|
||||||
log.Print("Docks.RightSidebar", Docks.RightSidebar)
|
DebugLog("Docks.Footer", Docks.Footer)
|
||||||
log.Print("Docks.Footer", Docks.Footer)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,8 +215,9 @@ func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("Bad guild", w, r, user)
|
return common.LocalError("Bad guild", w, r, user)
|
||||||
}
|
}
|
||||||
|
// TODO: Build and pass headerVars
|
||||||
if !guildItem.Active {
|
if !guildItem.Active {
|
||||||
return common.NotFound(w, r)
|
return common.NotFound(w, r, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return 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}
|
pi := MemberListPage{"Guild Member List", user, headerVars, guildMembers, guildItem, 0, 0}
|
||||||
// A plugin with plugins. Pluginception!
|
// A plugin with plugins. Pluginception!
|
||||||
if common.PreRenderHooks["pre_render_guilds_member_list"] != nil {
|
if common.RunPreRenderHook("pre_render_guilds_member_list", w, r, &user, &pi) {
|
||||||
if common.RunPreRenderHook("pre_render_guilds_member_list", w, r, &user, &pi) {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "guilds_member_list", pi, w)
|
err = common.RunThemeTemplate(headerVars.Theme.Name, "guilds_member_list", pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
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)
|
return true, common.InternalError(errors.New("Unable to find the parent group for a forum"), w, r)
|
||||||
}
|
}
|
||||||
if !guildItem.Active {
|
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))
|
r = r.WithContext(context.WithValue(r.Context(), "guilds_current_group", guildItem))
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,9 +64,7 @@ type Stmts struct {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func _gen_mssql() (err error) {
|
func _gen_mssql() (err error) {
|
||||||
if common.Dev.DebugMode {
|
common.DebugLog("Building the generated statements")
|
||||||
log.Print("Building the generated statements")
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getPassword statement.")
|
log.Print("Preparing getPassword statement.")
|
||||||
stmts.getPassword, err = db.Prepare("SELECT [password],[salt] FROM [users] WHERE [uid] = ?1")
|
stmts.getPassword, err = db.Prepare("SELECT [password],[salt] FROM [users] WHERE [uid] = ?1")
|
||||||
|
|
|
@ -66,9 +66,7 @@ type Stmts struct {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func _gen_mysql() (err error) {
|
func _gen_mysql() (err error) {
|
||||||
if common.Dev.DebugMode {
|
common.DebugLog("Building the generated statements")
|
||||||
log.Print("Building the generated statements")
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing getPassword statement.")
|
log.Print("Preparing getPassword statement.")
|
||||||
stmts.getPassword, err = db.Prepare("SELECT `password`,`salt` FROM `users` WHERE `uid` = ?")
|
stmts.getPassword, err = db.Prepare("SELECT `password`,`salt` FROM `users` WHERE `uid` = ?")
|
||||||
|
|
|
@ -34,9 +34,7 @@ type Stmts struct {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func _gen_pgsql() (err error) {
|
func _gen_pgsql() (err error) {
|
||||||
if common.Dev.DebugMode {
|
common.DebugLog("Building the generated statements")
|
||||||
log.Print("Building the generated statements")
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Print("Preparing editReply statement.")
|
log.Print("Preparing editReply statement.")
|
||||||
stmts.editReply, err = db.Prepare("UPDATE `replies` SET `content` = ?,`parsed_content` = ? WHERE `rid` = ?")
|
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"
|
"net/http"
|
||||||
|
|
||||||
"./common"
|
"./common"
|
||||||
|
"./common/counters"
|
||||||
"./routes"
|
"./routes"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -113,6 +114,7 @@ var RouteMap = map[string]interface{}{
|
||||||
"routes.AccountRegisterSubmit": routes.AccountRegisterSubmit,
|
"routes.AccountRegisterSubmit": routes.AccountRegisterSubmit,
|
||||||
"routeDynamic": routeDynamic,
|
"routeDynamic": routeDynamic,
|
||||||
"routeUploads": routeUploads,
|
"routeUploads": routeUploads,
|
||||||
|
"routes.StaticFile": routes.StaticFile,
|
||||||
"BadRoute": BadRoute,
|
"BadRoute": BadRoute,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +217,8 @@ var routeMapEnum = map[string]int{
|
||||||
"routes.AccountRegisterSubmit": 94,
|
"routes.AccountRegisterSubmit": 94,
|
||||||
"routeDynamic": 95,
|
"routeDynamic": 95,
|
||||||
"routeUploads": 96,
|
"routeUploads": 96,
|
||||||
"BadRoute": 97,
|
"routes.StaticFile": 97,
|
||||||
|
"BadRoute": 98,
|
||||||
}
|
}
|
||||||
var reverseRouteMapEnum = map[int]string{
|
var reverseRouteMapEnum = map[int]string{
|
||||||
0: "routeAPI",
|
0: "routeAPI",
|
||||||
|
@ -315,7 +318,8 @@ var reverseRouteMapEnum = map[int]string{
|
||||||
94: "routes.AccountRegisterSubmit",
|
94: "routes.AccountRegisterSubmit",
|
||||||
95: "routeDynamic",
|
95: "routeDynamic",
|
||||||
96: "routeUploads",
|
96: "routeUploads",
|
||||||
97: "BadRoute",
|
97: "routes.StaticFile",
|
||||||
|
98: "BadRoute",
|
||||||
}
|
}
|
||||||
var osMapEnum = map[string]int{
|
var osMapEnum = map[string]int{
|
||||||
"unknown": 0,
|
"unknown": 0,
|
||||||
|
@ -428,12 +432,12 @@ var markToAgent = map[string]string{
|
||||||
|
|
||||||
// TODO: Stop spilling these into the package scope?
|
// TODO: Stop spilling these into the package scope?
|
||||||
func init() {
|
func init() {
|
||||||
common.SetRouteMapEnum(routeMapEnum)
|
counters.SetRouteMapEnum(routeMapEnum)
|
||||||
common.SetReverseRouteMapEnum(reverseRouteMapEnum)
|
counters.SetReverseRouteMapEnum(reverseRouteMapEnum)
|
||||||
common.SetAgentMapEnum(agentMapEnum)
|
counters.SetAgentMapEnum(agentMapEnum)
|
||||||
common.SetReverseAgentMapEnum(reverseAgentMapEnum)
|
counters.SetReverseAgentMapEnum(reverseAgentMapEnum)
|
||||||
common.SetOSMapEnum(osMapEnum)
|
counters.SetOSMapEnum(osMapEnum)
|
||||||
common.SetReverseOSMapEnum(reverseOSMapEnum)
|
counters.SetReverseOSMapEnum(reverseOSMapEnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
type GenRouter struct {
|
type GenRouter struct {
|
||||||
|
@ -500,7 +504,7 @@ func (router *GenRouter) DumpRequest(req *http.Request) {
|
||||||
func (router *GenRouter) SuspiciousRequest(req *http.Request) {
|
func (router *GenRouter) SuspiciousRequest(req *http.Request) {
|
||||||
log.Print("Suspicious Request")
|
log.Print("Suspicious Request")
|
||||||
router.DumpRequest(req)
|
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
|
// 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(""))
|
w.Write([]byte(""))
|
||||||
log.Print("Malformed Request")
|
log.Print("Malformed Request")
|
||||||
router.DumpRequest(req)
|
router.DumpRequest(req)
|
||||||
common.AgentViewCounter.Bump(25)
|
counters.AgentViewCounter.Bump(25)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,8 +567,11 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
log.Print("before routes.StaticFile")
|
log.Print("before routes.StaticFile")
|
||||||
router.DumpRequest(req)
|
router.DumpRequest(req)
|
||||||
}
|
}
|
||||||
|
// Increment the request counter
|
||||||
|
counters.GlobalViewCounter.Bump()
|
||||||
|
|
||||||
if prefix == "/static" {
|
if prefix == "/static" {
|
||||||
|
counters.RouteViewCounter.Bump(97)
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
routes.StaticFile(w, req)
|
routes.StaticFile(w, req)
|
||||||
return
|
return
|
||||||
|
@ -573,15 +580,12 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
log.Print("before PreRoute")
|
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.
|
// 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: Add a setting to disable this?
|
||||||
// TODO: Use a more efficient detector instead of smashing every possible combination in
|
// 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
|
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 == "" {
|
if ua == "" {
|
||||||
common.AgentViewCounter.Bump(24)
|
counters.AgentViewCounter.Bump(24)
|
||||||
if common.Dev.DebugMode {
|
if common.Dev.DebugMode {
|
||||||
log.Print("Blank UA: ", req.UserAgent())
|
log.Print("Blank UA: ", req.UserAgent())
|
||||||
router.DumpRequest(req)
|
router.DumpRequest(req)
|
||||||
|
@ -681,15 +685,15 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if agent == "" {
|
if agent == "" {
|
||||||
common.AgentViewCounter.Bump(0)
|
counters.AgentViewCounter.Bump(0)
|
||||||
if common.Dev.DebugMode {
|
if common.Dev.DebugMode {
|
||||||
log.Print("Unknown UA: ", req.UserAgent())
|
log.Print("Unknown UA: ", req.UserAgent())
|
||||||
router.DumpRequest(req)
|
router.DumpRequest(req)
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
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]
|
referrer = strings.Split(referrer,"/")[0]
|
||||||
portless := strings.Split(referrer,":")[0]
|
portless := strings.Split(referrer,":")[0]
|
||||||
if portless != "localhost" && portless != "127.0.0.1" && portless != common.Site.Host {
|
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
|
var err common.RouteError
|
||||||
switch(prefix) {
|
switch(prefix) {
|
||||||
case "/api":
|
case "/api":
|
||||||
common.RouteViewCounter.Bump(0)
|
counters.RouteViewCounter.Bump(0)
|
||||||
err = routeAPI(w,req,user)
|
err = routeAPI(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
}
|
}
|
||||||
case "/overview":
|
case "/overview":
|
||||||
common.RouteViewCounter.Bump(1)
|
counters.RouteViewCounter.Bump(1)
|
||||||
err = routes.Overview(w,req,user)
|
err = routes.Overview(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
}
|
}
|
||||||
case "/pages":
|
case "/pages":
|
||||||
common.RouteViewCounter.Bump(2)
|
counters.RouteViewCounter.Bump(2)
|
||||||
err = routes.CustomPage(w,req,user,extraData)
|
err = routes.CustomPage(w,req,user,extraData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
}
|
}
|
||||||
case "/forums":
|
case "/forums":
|
||||||
common.RouteViewCounter.Bump(3)
|
counters.RouteViewCounter.Bump(3)
|
||||||
err = routeForums(w,req,user)
|
err = routeForums(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
}
|
}
|
||||||
case "/forum":
|
case "/forum":
|
||||||
common.RouteViewCounter.Bump(4)
|
counters.RouteViewCounter.Bump(4)
|
||||||
err = routeForum(w,req,user,extraData)
|
err = routeForum(w,req,user,extraData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
|
@ -752,7 +756,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(5)
|
counters.RouteViewCounter.Bump(5)
|
||||||
err = routeChangeTheme(w,req,user)
|
err = routeChangeTheme(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
|
@ -764,14 +768,14 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(6)
|
counters.RouteViewCounter.Bump(6)
|
||||||
err = routeShowAttachment(w,req,user,extraData)
|
err = routeShowAttachment(w,req,user,extraData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
}
|
}
|
||||||
case "/ws":
|
case "/ws":
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
common.RouteViewCounter.Bump(7)
|
counters.RouteViewCounter.Bump(7)
|
||||||
err = routeWebsockets(w,req,user)
|
err = routeWebsockets(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
|
@ -797,7 +801,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(8)
|
counters.RouteViewCounter.Bump(8)
|
||||||
err = routeReportSubmit(w,req,user,extraData)
|
err = routeReportSubmit(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -812,10 +816,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(9)
|
counters.RouteViewCounter.Bump(9)
|
||||||
err = routes.CreateTopic(w,req,user,extraData)
|
err = routes.CreateTopic(w,req,user,extraData)
|
||||||
default:
|
default:
|
||||||
common.RouteViewCounter.Bump(10)
|
counters.RouteViewCounter.Bump(10)
|
||||||
err = routes.TopicList(w,req,user)
|
err = routes.TopicList(w,req,user)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -830,7 +834,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
switch(req.URL.Path) {
|
switch(req.URL.Path) {
|
||||||
case "/panel/forums/":
|
case "/panel/forums/":
|
||||||
common.RouteViewCounter.Bump(11)
|
counters.RouteViewCounter.Bump(11)
|
||||||
err = routePanelForums(w,req,user)
|
err = routePanelForums(w,req,user)
|
||||||
case "/panel/forums/create/":
|
case "/panel/forums/create/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -839,7 +843,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(12)
|
counters.RouteViewCounter.Bump(12)
|
||||||
err = routePanelForumsCreateSubmit(w,req,user)
|
err = routePanelForumsCreateSubmit(w,req,user)
|
||||||
case "/panel/forums/delete/":
|
case "/panel/forums/delete/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -848,7 +852,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(13)
|
counters.RouteViewCounter.Bump(13)
|
||||||
err = routePanelForumsDelete(w,req,user,extraData)
|
err = routePanelForumsDelete(w,req,user,extraData)
|
||||||
case "/panel/forums/delete/submit/":
|
case "/panel/forums/delete/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -857,10 +861,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(14)
|
counters.RouteViewCounter.Bump(14)
|
||||||
err = routePanelForumsDeleteSubmit(w,req,user,extraData)
|
err = routePanelForumsDeleteSubmit(w,req,user,extraData)
|
||||||
case "/panel/forums/edit/":
|
case "/panel/forums/edit/":
|
||||||
common.RouteViewCounter.Bump(15)
|
counters.RouteViewCounter.Bump(15)
|
||||||
err = routePanelForumsEdit(w,req,user,extraData)
|
err = routePanelForumsEdit(w,req,user,extraData)
|
||||||
case "/panel/forums/edit/submit/":
|
case "/panel/forums/edit/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -869,7 +873,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(16)
|
counters.RouteViewCounter.Bump(16)
|
||||||
err = routePanelForumsEditSubmit(w,req,user,extraData)
|
err = routePanelForumsEditSubmit(w,req,user,extraData)
|
||||||
case "/panel/forums/edit/perms/submit/":
|
case "/panel/forums/edit/perms/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -878,10 +882,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(17)
|
counters.RouteViewCounter.Bump(17)
|
||||||
err = routePanelForumsEditPermsSubmit(w,req,user,extraData)
|
err = routePanelForumsEditPermsSubmit(w,req,user,extraData)
|
||||||
case "/panel/forums/edit/perms/":
|
case "/panel/forums/edit/perms/":
|
||||||
common.RouteViewCounter.Bump(18)
|
counters.RouteViewCounter.Bump(18)
|
||||||
err = routePanelForumsEditPermsAdvance(w,req,user,extraData)
|
err = routePanelForumsEditPermsAdvance(w,req,user,extraData)
|
||||||
case "/panel/forums/edit/perms/adv/submit/":
|
case "/panel/forums/edit/perms/adv/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -890,13 +894,13 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(19)
|
counters.RouteViewCounter.Bump(19)
|
||||||
err = routePanelForumsEditPermsAdvanceSubmit(w,req,user,extraData)
|
err = routePanelForumsEditPermsAdvanceSubmit(w,req,user,extraData)
|
||||||
case "/panel/settings/":
|
case "/panel/settings/":
|
||||||
common.RouteViewCounter.Bump(20)
|
counters.RouteViewCounter.Bump(20)
|
||||||
err = routePanelSettings(w,req,user)
|
err = routePanelSettings(w,req,user)
|
||||||
case "/panel/settings/edit/":
|
case "/panel/settings/edit/":
|
||||||
common.RouteViewCounter.Bump(21)
|
counters.RouteViewCounter.Bump(21)
|
||||||
err = routePanelSettingEdit(w,req,user,extraData)
|
err = routePanelSettingEdit(w,req,user,extraData)
|
||||||
case "/panel/settings/edit/submit/":
|
case "/panel/settings/edit/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -905,10 +909,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(22)
|
counters.RouteViewCounter.Bump(22)
|
||||||
err = routePanelSettingEditSubmit(w,req,user,extraData)
|
err = routePanelSettingEditSubmit(w,req,user,extraData)
|
||||||
case "/panel/settings/word-filters/":
|
case "/panel/settings/word-filters/":
|
||||||
common.RouteViewCounter.Bump(23)
|
counters.RouteViewCounter.Bump(23)
|
||||||
err = routePanelWordFilters(w,req,user)
|
err = routePanelWordFilters(w,req,user)
|
||||||
case "/panel/settings/word-filters/create/":
|
case "/panel/settings/word-filters/create/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -917,10 +921,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(24)
|
counters.RouteViewCounter.Bump(24)
|
||||||
err = routePanelWordFiltersCreateSubmit(w,req,user)
|
err = routePanelWordFiltersCreateSubmit(w,req,user)
|
||||||
case "/panel/settings/word-filters/edit/":
|
case "/panel/settings/word-filters/edit/":
|
||||||
common.RouteViewCounter.Bump(25)
|
counters.RouteViewCounter.Bump(25)
|
||||||
err = routePanelWordFiltersEdit(w,req,user,extraData)
|
err = routePanelWordFiltersEdit(w,req,user,extraData)
|
||||||
case "/panel/settings/word-filters/edit/submit/":
|
case "/panel/settings/word-filters/edit/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -929,7 +933,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(26)
|
counters.RouteViewCounter.Bump(26)
|
||||||
err = routePanelWordFiltersEditSubmit(w,req,user,extraData)
|
err = routePanelWordFiltersEditSubmit(w,req,user,extraData)
|
||||||
case "/panel/settings/word-filters/delete/submit/":
|
case "/panel/settings/word-filters/delete/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -938,10 +942,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(27)
|
counters.RouteViewCounter.Bump(27)
|
||||||
err = routePanelWordFiltersDeleteSubmit(w,req,user,extraData)
|
err = routePanelWordFiltersDeleteSubmit(w,req,user,extraData)
|
||||||
case "/panel/themes/":
|
case "/panel/themes/":
|
||||||
common.RouteViewCounter.Bump(28)
|
counters.RouteViewCounter.Bump(28)
|
||||||
err = routePanelThemes(w,req,user)
|
err = routePanelThemes(w,req,user)
|
||||||
case "/panel/themes/default/":
|
case "/panel/themes/default/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -950,10 +954,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(29)
|
counters.RouteViewCounter.Bump(29)
|
||||||
err = routePanelThemesSetDefault(w,req,user,extraData)
|
err = routePanelThemesSetDefault(w,req,user,extraData)
|
||||||
case "/panel/plugins/":
|
case "/panel/plugins/":
|
||||||
common.RouteViewCounter.Bump(30)
|
counters.RouteViewCounter.Bump(30)
|
||||||
err = routePanelPlugins(w,req,user)
|
err = routePanelPlugins(w,req,user)
|
||||||
case "/panel/plugins/activate/":
|
case "/panel/plugins/activate/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -962,7 +966,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(31)
|
counters.RouteViewCounter.Bump(31)
|
||||||
err = routePanelPluginsActivate(w,req,user,extraData)
|
err = routePanelPluginsActivate(w,req,user,extraData)
|
||||||
case "/panel/plugins/deactivate/":
|
case "/panel/plugins/deactivate/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -971,7 +975,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(32)
|
counters.RouteViewCounter.Bump(32)
|
||||||
err = routePanelPluginsDeactivate(w,req,user,extraData)
|
err = routePanelPluginsDeactivate(w,req,user,extraData)
|
||||||
case "/panel/plugins/install/":
|
case "/panel/plugins/install/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -980,13 +984,13 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(33)
|
counters.RouteViewCounter.Bump(33)
|
||||||
err = routePanelPluginsInstall(w,req,user,extraData)
|
err = routePanelPluginsInstall(w,req,user,extraData)
|
||||||
case "/panel/users/":
|
case "/panel/users/":
|
||||||
common.RouteViewCounter.Bump(34)
|
counters.RouteViewCounter.Bump(34)
|
||||||
err = routePanelUsers(w,req,user)
|
err = routePanelUsers(w,req,user)
|
||||||
case "/panel/users/edit/":
|
case "/panel/users/edit/":
|
||||||
common.RouteViewCounter.Bump(35)
|
counters.RouteViewCounter.Bump(35)
|
||||||
err = routePanelUsersEdit(w,req,user,extraData)
|
err = routePanelUsersEdit(w,req,user,extraData)
|
||||||
case "/panel/users/edit/submit/":
|
case "/panel/users/edit/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -995,7 +999,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(36)
|
counters.RouteViewCounter.Bump(36)
|
||||||
err = routePanelUsersEditSubmit(w,req,user,extraData)
|
err = routePanelUsersEditSubmit(w,req,user,extraData)
|
||||||
case "/panel/analytics/views/":
|
case "/panel/analytics/views/":
|
||||||
err = common.ParseForm(w,req,user)
|
err = common.ParseForm(w,req,user)
|
||||||
|
@ -1004,7 +1008,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(37)
|
counters.RouteViewCounter.Bump(37)
|
||||||
err = routePanelAnalyticsViews(w,req,user)
|
err = routePanelAnalyticsViews(w,req,user)
|
||||||
case "/panel/analytics/routes/":
|
case "/panel/analytics/routes/":
|
||||||
err = common.ParseForm(w,req,user)
|
err = common.ParseForm(w,req,user)
|
||||||
|
@ -1013,7 +1017,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(38)
|
counters.RouteViewCounter.Bump(38)
|
||||||
err = routePanelAnalyticsRoutes(w,req,user)
|
err = routePanelAnalyticsRoutes(w,req,user)
|
||||||
case "/panel/analytics/agents/":
|
case "/panel/analytics/agents/":
|
||||||
err = common.ParseForm(w,req,user)
|
err = common.ParseForm(w,req,user)
|
||||||
|
@ -1022,7 +1026,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(39)
|
counters.RouteViewCounter.Bump(39)
|
||||||
err = routePanelAnalyticsAgents(w,req,user)
|
err = routePanelAnalyticsAgents(w,req,user)
|
||||||
case "/panel/analytics/systems/":
|
case "/panel/analytics/systems/":
|
||||||
err = common.ParseForm(w,req,user)
|
err = common.ParseForm(w,req,user)
|
||||||
|
@ -1031,7 +1035,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(40)
|
counters.RouteViewCounter.Bump(40)
|
||||||
err = routePanelAnalyticsSystems(w,req,user)
|
err = routePanelAnalyticsSystems(w,req,user)
|
||||||
case "/panel/analytics/referrers/":
|
case "/panel/analytics/referrers/":
|
||||||
err = common.ParseForm(w,req,user)
|
err = common.ParseForm(w,req,user)
|
||||||
|
@ -1040,19 +1044,19 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(41)
|
counters.RouteViewCounter.Bump(41)
|
||||||
err = routePanelAnalyticsReferrers(w,req,user)
|
err = routePanelAnalyticsReferrers(w,req,user)
|
||||||
case "/panel/analytics/route/":
|
case "/panel/analytics/route/":
|
||||||
common.RouteViewCounter.Bump(42)
|
counters.RouteViewCounter.Bump(42)
|
||||||
err = routePanelAnalyticsRouteViews(w,req,user,extraData)
|
err = routePanelAnalyticsRouteViews(w,req,user,extraData)
|
||||||
case "/panel/analytics/agent/":
|
case "/panel/analytics/agent/":
|
||||||
common.RouteViewCounter.Bump(43)
|
counters.RouteViewCounter.Bump(43)
|
||||||
err = routePanelAnalyticsAgentViews(w,req,user,extraData)
|
err = routePanelAnalyticsAgentViews(w,req,user,extraData)
|
||||||
case "/panel/analytics/system/":
|
case "/panel/analytics/system/":
|
||||||
common.RouteViewCounter.Bump(44)
|
counters.RouteViewCounter.Bump(44)
|
||||||
err = routePanelAnalyticsSystemViews(w,req,user,extraData)
|
err = routePanelAnalyticsSystemViews(w,req,user,extraData)
|
||||||
case "/panel/analytics/referrer/":
|
case "/panel/analytics/referrer/":
|
||||||
common.RouteViewCounter.Bump(45)
|
counters.RouteViewCounter.Bump(45)
|
||||||
err = routePanelAnalyticsReferrerViews(w,req,user,extraData)
|
err = routePanelAnalyticsReferrerViews(w,req,user,extraData)
|
||||||
case "/panel/analytics/posts/":
|
case "/panel/analytics/posts/":
|
||||||
err = common.ParseForm(w,req,user)
|
err = common.ParseForm(w,req,user)
|
||||||
|
@ -1061,7 +1065,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(46)
|
counters.RouteViewCounter.Bump(46)
|
||||||
err = routePanelAnalyticsPosts(w,req,user)
|
err = routePanelAnalyticsPosts(w,req,user)
|
||||||
case "/panel/analytics/topics/":
|
case "/panel/analytics/topics/":
|
||||||
err = common.ParseForm(w,req,user)
|
err = common.ParseForm(w,req,user)
|
||||||
|
@ -1070,16 +1074,16 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(47)
|
counters.RouteViewCounter.Bump(47)
|
||||||
err = routePanelAnalyticsTopics(w,req,user)
|
err = routePanelAnalyticsTopics(w,req,user)
|
||||||
case "/panel/groups/":
|
case "/panel/groups/":
|
||||||
common.RouteViewCounter.Bump(48)
|
counters.RouteViewCounter.Bump(48)
|
||||||
err = routePanelGroups(w,req,user)
|
err = routePanelGroups(w,req,user)
|
||||||
case "/panel/groups/edit/":
|
case "/panel/groups/edit/":
|
||||||
common.RouteViewCounter.Bump(49)
|
counters.RouteViewCounter.Bump(49)
|
||||||
err = routePanelGroupsEdit(w,req,user,extraData)
|
err = routePanelGroupsEdit(w,req,user,extraData)
|
||||||
case "/panel/groups/edit/perms/":
|
case "/panel/groups/edit/perms/":
|
||||||
common.RouteViewCounter.Bump(50)
|
counters.RouteViewCounter.Bump(50)
|
||||||
err = routePanelGroupsEditPerms(w,req,user,extraData)
|
err = routePanelGroupsEditPerms(w,req,user,extraData)
|
||||||
case "/panel/groups/edit/submit/":
|
case "/panel/groups/edit/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1088,7 +1092,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(51)
|
counters.RouteViewCounter.Bump(51)
|
||||||
err = routePanelGroupsEditSubmit(w,req,user,extraData)
|
err = routePanelGroupsEditSubmit(w,req,user,extraData)
|
||||||
case "/panel/groups/edit/perms/submit/":
|
case "/panel/groups/edit/perms/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1097,7 +1101,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(52)
|
counters.RouteViewCounter.Bump(52)
|
||||||
err = routePanelGroupsEditPermsSubmit(w,req,user,extraData)
|
err = routePanelGroupsEditPermsSubmit(w,req,user,extraData)
|
||||||
case "/panel/groups/create/":
|
case "/panel/groups/create/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1106,7 +1110,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(53)
|
counters.RouteViewCounter.Bump(53)
|
||||||
err = routePanelGroupsCreateSubmit(w,req,user)
|
err = routePanelGroupsCreateSubmit(w,req,user)
|
||||||
case "/panel/backups/":
|
case "/panel/backups/":
|
||||||
err = common.SuperAdminOnly(w,req,user)
|
err = common.SuperAdminOnly(w,req,user)
|
||||||
|
@ -1115,10 +1119,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(54)
|
counters.RouteViewCounter.Bump(54)
|
||||||
err = routePanelBackups(w,req,user,extraData)
|
err = routePanelBackups(w,req,user,extraData)
|
||||||
case "/panel/logs/mod/":
|
case "/panel/logs/mod/":
|
||||||
common.RouteViewCounter.Bump(55)
|
counters.RouteViewCounter.Bump(55)
|
||||||
err = routePanelLogsMod(w,req,user)
|
err = routePanelLogsMod(w,req,user)
|
||||||
case "/panel/debug/":
|
case "/panel/debug/":
|
||||||
err = common.AdminOnly(w,req,user)
|
err = common.AdminOnly(w,req,user)
|
||||||
|
@ -1127,10 +1131,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(56)
|
counters.RouteViewCounter.Bump(56)
|
||||||
err = routePanelDebug(w,req,user)
|
err = routePanelDebug(w,req,user)
|
||||||
default:
|
default:
|
||||||
common.RouteViewCounter.Bump(57)
|
counters.RouteViewCounter.Bump(57)
|
||||||
err = routePanelDashboard(w,req,user)
|
err = routePanelDashboard(w,req,user)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1145,7 +1149,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(58)
|
counters.RouteViewCounter.Bump(58)
|
||||||
err = routes.AccountEditCritical(w,req,user)
|
err = routes.AccountEditCritical(w,req,user)
|
||||||
case "/user/edit/critical/submit/":
|
case "/user/edit/critical/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1160,7 +1164,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(59)
|
counters.RouteViewCounter.Bump(59)
|
||||||
err = routeAccountEditCriticalSubmit(w,req,user)
|
err = routeAccountEditCriticalSubmit(w,req,user)
|
||||||
case "/user/edit/avatar/":
|
case "/user/edit/avatar/":
|
||||||
err = common.MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
|
@ -1169,7 +1173,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(60)
|
counters.RouteViewCounter.Bump(60)
|
||||||
err = routeAccountEditAvatar(w,req,user)
|
err = routeAccountEditAvatar(w,req,user)
|
||||||
case "/user/edit/avatar/submit/":
|
case "/user/edit/avatar/submit/":
|
||||||
err = common.MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
|
@ -1189,7 +1193,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(61)
|
counters.RouteViewCounter.Bump(61)
|
||||||
err = routeAccountEditAvatarSubmit(w,req,user)
|
err = routeAccountEditAvatarSubmit(w,req,user)
|
||||||
case "/user/edit/username/":
|
case "/user/edit/username/":
|
||||||
err = common.MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
|
@ -1198,7 +1202,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(62)
|
counters.RouteViewCounter.Bump(62)
|
||||||
err = routeAccountEditUsername(w,req,user)
|
err = routeAccountEditUsername(w,req,user)
|
||||||
case "/user/edit/username/submit/":
|
case "/user/edit/username/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1213,7 +1217,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(63)
|
counters.RouteViewCounter.Bump(63)
|
||||||
err = routeAccountEditUsernameSubmit(w,req,user)
|
err = routeAccountEditUsernameSubmit(w,req,user)
|
||||||
case "/user/edit/email/":
|
case "/user/edit/email/":
|
||||||
err = common.MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
|
@ -1222,7 +1226,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(64)
|
counters.RouteViewCounter.Bump(64)
|
||||||
err = routeAccountEditEmail(w,req,user)
|
err = routeAccountEditEmail(w,req,user)
|
||||||
case "/user/edit/token/":
|
case "/user/edit/token/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1237,11 +1241,11 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(65)
|
counters.RouteViewCounter.Bump(65)
|
||||||
err = routeAccountEditEmailTokenSubmit(w,req,user,extraData)
|
err = routeAccountEditEmailTokenSubmit(w,req,user,extraData)
|
||||||
default:
|
default:
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
common.RouteViewCounter.Bump(66)
|
counters.RouteViewCounter.Bump(66)
|
||||||
err = routeProfile(w,req,user)
|
err = routeProfile(w,req,user)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1262,7 +1266,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(67)
|
counters.RouteViewCounter.Bump(67)
|
||||||
err = routes.BanUserSubmit(w,req,user,extraData)
|
err = routes.BanUserSubmit(w,req,user,extraData)
|
||||||
case "/users/unban/":
|
case "/users/unban/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1277,7 +1281,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(68)
|
counters.RouteViewCounter.Bump(68)
|
||||||
err = routes.UnbanUser(w,req,user,extraData)
|
err = routes.UnbanUser(w,req,user,extraData)
|
||||||
case "/users/activate/":
|
case "/users/activate/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1292,7 +1296,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(69)
|
counters.RouteViewCounter.Bump(69)
|
||||||
err = routes.ActivateUser(w,req,user,extraData)
|
err = routes.ActivateUser(w,req,user,extraData)
|
||||||
case "/users/ips/":
|
case "/users/ips/":
|
||||||
err = common.MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
|
@ -1301,7 +1305,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(70)
|
counters.RouteViewCounter.Bump(70)
|
||||||
err = routes.IPSearch(w,req,user)
|
err = routes.IPSearch(w,req,user)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1327,7 +1331,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(71)
|
counters.RouteViewCounter.Bump(71)
|
||||||
err = routes.CreateTopicSubmit(w,req,user)
|
err = routes.CreateTopicSubmit(w,req,user)
|
||||||
case "/topic/edit/submit/":
|
case "/topic/edit/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1342,7 +1346,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(72)
|
counters.RouteViewCounter.Bump(72)
|
||||||
err = routes.EditTopicSubmit(w,req,user,extraData)
|
err = routes.EditTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/delete/submit/":
|
case "/topic/delete/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1358,7 +1362,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
common.RouteViewCounter.Bump(73)
|
counters.RouteViewCounter.Bump(73)
|
||||||
err = routes.DeleteTopicSubmit(w,req,user)
|
err = routes.DeleteTopicSubmit(w,req,user)
|
||||||
case "/topic/stick/submit/":
|
case "/topic/stick/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1373,7 +1377,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(74)
|
counters.RouteViewCounter.Bump(74)
|
||||||
err = routes.StickTopicSubmit(w,req,user,extraData)
|
err = routes.StickTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/unstick/submit/":
|
case "/topic/unstick/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1388,7 +1392,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(75)
|
counters.RouteViewCounter.Bump(75)
|
||||||
err = routes.UnstickTopicSubmit(w,req,user,extraData)
|
err = routes.UnstickTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/lock/submit/":
|
case "/topic/lock/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1404,7 +1408,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
common.RouteViewCounter.Bump(76)
|
counters.RouteViewCounter.Bump(76)
|
||||||
err = routes.LockTopicSubmit(w,req,user)
|
err = routes.LockTopicSubmit(w,req,user)
|
||||||
case "/topic/unlock/submit/":
|
case "/topic/unlock/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1419,7 +1423,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(77)
|
counters.RouteViewCounter.Bump(77)
|
||||||
err = routes.UnlockTopicSubmit(w,req,user,extraData)
|
err = routes.UnlockTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/move/submit/":
|
case "/topic/move/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1434,7 +1438,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(78)
|
counters.RouteViewCounter.Bump(78)
|
||||||
err = routes.MoveTopicSubmit(w,req,user,extraData)
|
err = routes.MoveTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/like/submit/":
|
case "/topic/like/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1449,10 +1453,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(79)
|
counters.RouteViewCounter.Bump(79)
|
||||||
err = routeLikeTopicSubmit(w,req,user,extraData)
|
err = routeLikeTopicSubmit(w,req,user,extraData)
|
||||||
default:
|
default:
|
||||||
common.RouteViewCounter.Bump(80)
|
counters.RouteViewCounter.Bump(80)
|
||||||
err = routes.ViewTopic(w,req,user, extraData)
|
err = routes.ViewTopic(w,req,user, extraData)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1478,7 +1482,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(81)
|
counters.RouteViewCounter.Bump(81)
|
||||||
err = routeCreateReplySubmit(w,req,user)
|
err = routeCreateReplySubmit(w,req,user)
|
||||||
case "/reply/edit/submit/":
|
case "/reply/edit/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1493,7 +1497,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(82)
|
counters.RouteViewCounter.Bump(82)
|
||||||
err = routes.ReplyEditSubmit(w,req,user,extraData)
|
err = routes.ReplyEditSubmit(w,req,user,extraData)
|
||||||
case "/reply/delete/submit/":
|
case "/reply/delete/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1508,7 +1512,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(83)
|
counters.RouteViewCounter.Bump(83)
|
||||||
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
|
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
|
||||||
case "/reply/like/submit/":
|
case "/reply/like/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1523,7 +1527,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(84)
|
counters.RouteViewCounter.Bump(84)
|
||||||
err = routeReplyLikeSubmit(w,req,user,extraData)
|
err = routeReplyLikeSubmit(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1544,7 +1548,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(85)
|
counters.RouteViewCounter.Bump(85)
|
||||||
err = routeProfileReplyCreateSubmit(w,req,user)
|
err = routeProfileReplyCreateSubmit(w,req,user)
|
||||||
case "/profile/reply/edit/submit/":
|
case "/profile/reply/edit/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1559,7 +1563,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(86)
|
counters.RouteViewCounter.Bump(86)
|
||||||
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
|
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
|
||||||
case "/profile/reply/delete/submit/":
|
case "/profile/reply/delete/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1574,7 +1578,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(87)
|
counters.RouteViewCounter.Bump(87)
|
||||||
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
|
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1595,10 +1599,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(88)
|
counters.RouteViewCounter.Bump(88)
|
||||||
err = routes.PollVote(w,req,user,extraData)
|
err = routes.PollVote(w,req,user,extraData)
|
||||||
case "/poll/results/":
|
case "/poll/results/":
|
||||||
common.RouteViewCounter.Bump(89)
|
counters.RouteViewCounter.Bump(89)
|
||||||
err = routes.PollResults(w,req,user,extraData)
|
err = routes.PollResults(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1607,10 +1611,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
case "/accounts":
|
case "/accounts":
|
||||||
switch(req.URL.Path) {
|
switch(req.URL.Path) {
|
||||||
case "/accounts/login/":
|
case "/accounts/login/":
|
||||||
common.RouteViewCounter.Bump(90)
|
counters.RouteViewCounter.Bump(90)
|
||||||
err = routes.AccountLogin(w,req,user)
|
err = routes.AccountLogin(w,req,user)
|
||||||
case "/accounts/create/":
|
case "/accounts/create/":
|
||||||
common.RouteViewCounter.Bump(91)
|
counters.RouteViewCounter.Bump(91)
|
||||||
err = routes.AccountRegister(w,req,user)
|
err = routes.AccountRegister(w,req,user)
|
||||||
case "/accounts/logout/":
|
case "/accounts/logout/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1625,7 +1629,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(92)
|
counters.RouteViewCounter.Bump(92)
|
||||||
err = routeLogout(w,req,user)
|
err = routeLogout(w,req,user)
|
||||||
case "/accounts/login/submit/":
|
case "/accounts/login/submit/":
|
||||||
err = common.ParseForm(w,req,user)
|
err = common.ParseForm(w,req,user)
|
||||||
|
@ -1634,7 +1638,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(93)
|
counters.RouteViewCounter.Bump(93)
|
||||||
err = routes.AccountLoginSubmit(w,req,user)
|
err = routes.AccountLoginSubmit(w,req,user)
|
||||||
case "/accounts/create/submit/":
|
case "/accounts/create/submit/":
|
||||||
err = common.ParseForm(w,req,user)
|
err = common.ParseForm(w,req,user)
|
||||||
|
@ -1643,7 +1647,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
common.RouteViewCounter.Bump(94)
|
counters.RouteViewCounter.Bump(94)
|
||||||
err = routes.AccountRegisterSubmit(w,req,user)
|
err = routes.AccountRegisterSubmit(w,req,user)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1657,10 +1661,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}*/
|
}*/
|
||||||
case "/uploads":
|
case "/uploads":
|
||||||
if extraData == "" {
|
if extraData == "" {
|
||||||
common.NotFound(w,req)
|
common.NotFound(w,req,nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
common.RouteViewCounter.Bump(96)
|
counters.RouteViewCounter.Bump(96)
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
// TODO: Find a way to propagate errors up from this?
|
// TODO: Find a way to propagate errors up from this?
|
||||||
router.UploadHandler(w,req) // TODO: Count these views
|
router.UploadHandler(w,req) // TODO: Count these views
|
||||||
|
@ -1682,7 +1686,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return*/
|
return*/
|
||||||
}
|
}
|
||||||
if extraData != "" {
|
if extraData != "" {
|
||||||
common.NotFound(w,req)
|
common.NotFound(w,req,nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1690,10 +1694,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
if !ok {
|
if !ok {
|
||||||
// TODO: Make this a startup error not a runtime one
|
// TODO: Make this a startup error not a runtime one
|
||||||
log.Print("Unable to find the default route")
|
log.Print("Unable to find the default route")
|
||||||
common.NotFound(w,req)
|
common.NotFound(w,req,nil)
|
||||||
return
|
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)
|
handle.(func(http.ResponseWriter, *http.Request, common.User) common.RouteError)(w,req,user)
|
||||||
default:
|
default:
|
||||||
|
@ -1703,7 +1707,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
router.RUnlock()
|
router.RUnlock()
|
||||||
|
|
||||||
if ok {
|
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
|
req.URL.Path += extraData
|
||||||
err = handle(w,req,user)
|
err = handle(w,req,user)
|
||||||
if err != nil {
|
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") {
|
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)
|
router.SuspiciousRequest(req)
|
||||||
}
|
}
|
||||||
common.RouteViewCounter.Bump(97)
|
counters.RouteViewCounter.Bump(98)
|
||||||
common.NotFound(w,req)
|
common.NotFound(w,req,nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
19
main.go
19
main.go
|
@ -16,8 +16,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
//"runtime/pprof"
|
|
||||||
"./common"
|
"./common"
|
||||||
|
"./common/counters"
|
||||||
"github.com/fsnotify/fsnotify"
|
"github.com/fsnotify/fsnotify"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -101,35 +102,35 @@ func afterDBInit() (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
common.GlobalViewCounter, err = common.NewGlobalViewCounter()
|
counters.GlobalViewCounter, err = counters.NewGlobalViewCounter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
common.AgentViewCounter, err = common.NewDefaultAgentViewCounter()
|
counters.AgentViewCounter, err = counters.NewDefaultAgentViewCounter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
common.OSViewCounter, err = common.NewDefaultOSViewCounter()
|
counters.OSViewCounter, err = counters.NewDefaultOSViewCounter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
common.RouteViewCounter, err = common.NewDefaultRouteViewCounter()
|
counters.RouteViewCounter, err = counters.NewDefaultRouteViewCounter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
common.PostCounter, err = common.NewPostCounter()
|
counters.PostCounter, err = counters.NewPostCounter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
common.TopicCounter, err = common.NewTopicCounter()
|
counters.TopicCounter, err = counters.NewTopicCounter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
common.TopicViewCounter, err = common.NewDefaultTopicViewCounter()
|
counters.TopicViewCounter, err = counters.NewDefaultTopicViewCounter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
common.ReferrerTracker, err = common.NewDefaultReferrerTracker()
|
counters.ReferrerTracker, err = counters.NewDefaultReferrerTracker()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"./common"
|
"./common"
|
||||||
|
"./common/counters"
|
||||||
)
|
)
|
||||||
|
|
||||||
func routeCreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
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)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
common.PostCounter.Bump()
|
counters.PostCounter.Bump()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +349,7 @@ func routeProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
common.PostCounter.Bump()
|
counters.PostCounter.Bump()
|
||||||
http.Redirect(w, r, "/user/"+strconv.Itoa(uid), http.StatusSeeOther)
|
http.Redirect(w, r, "/user/"+strconv.Itoa(uid), http.StatusSeeOther)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -398,7 +399,7 @@ func routeReportSubmit(w http.ResponseWriter, r *http.Request, user common.User,
|
||||||
} else if itemType == "topic" {
|
} else if itemType == "topic" {
|
||||||
err = stmts.getTopicBasic.QueryRow(itemID).Scan(&title, &content)
|
err = stmts.getTopicBasic.QueryRow(itemID).Scan(&title, &content)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return common.NotFound(w, r)
|
return common.NotFound(w, r, nil)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
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 {
|
if err != nil && err != ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
common.PostCounter.Bump()
|
counters.PostCounter.Bump()
|
||||||
|
|
||||||
http.Redirect(w, r, "/topic/"+strconv.FormatInt(lastID, 10), http.StatusSeeOther)
|
http.Redirect(w, r, "/topic/"+strconv.FormatInt(lastID, 10), http.StatusSeeOther)
|
||||||
return nil
|
return nil
|
||||||
|
@ -479,10 +480,8 @@ func routeAccountEditCriticalSubmit(w http.ResponseWriter, r *http.Request, user
|
||||||
|
|
||||||
headerVars.NoticeList = append(headerVars.NoticeList, "Your password was successfully updated")
|
headerVars.NoticeList = append(headerVars.NoticeList, "Your password was successfully updated")
|
||||||
pi := common.Page{"Edit Password", user, headerVars, tList, nil}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_account_own_edit_critical", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.Templates.ExecuteTemplate(w, "account_own_edit.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "account_own_edit.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -498,10 +497,8 @@ func routeAccountEditAvatar(w http.ResponseWriter, r *http.Request, user common.
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.Page{"Edit Avatar", user, headerVars, tList, nil}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err := common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi)
|
err := common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -573,10 +570,8 @@ func routeAccountEditAvatarSubmit(w http.ResponseWriter, r *http.Request, user c
|
||||||
headerVars.NoticeList = append(headerVars.NoticeList, "Your avatar was successfully updated")
|
headerVars.NoticeList = append(headerVars.NoticeList, "Your avatar was successfully updated")
|
||||||
|
|
||||||
pi := common.Page{"Edit Avatar", user, headerVars, tList, nil}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -592,10 +587,8 @@ func routeAccountEditUsername(w http.ResponseWriter, r *http.Request, user commo
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.Page{"Edit Username", user, headerVars, tList, user.Name}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_account_own_edit_username", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err := common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi)
|
err := common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -619,10 +612,8 @@ func routeAccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user
|
||||||
|
|
||||||
headerVars.NoticeList = append(headerVars.NoticeList, "Your username was successfully updated")
|
headerVars.NoticeList = append(headerVars.NoticeList, "Your username was successfully updated")
|
||||||
pi := common.Page{"Edit Username", user, headerVars, tList, nil}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_account_own_edit_username", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -674,10 +665,8 @@ func routeAccountEditEmail(w http.ResponseWriter, r *http.Request, user common.U
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.Page{"Email Manager", user, headerVars, emailList, nil}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_account_own_edit_email", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.Templates.ExecuteTemplate(w, "account_own_edit_email.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "account_own_edit_email.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -746,10 +735,8 @@ func routeAccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, us
|
||||||
}
|
}
|
||||||
headerVars.NoticeList = append(headerVars.NoticeList, "Your email was successfully verified")
|
headerVars.NoticeList = append(headerVars.NoticeList, "Your email was successfully verified")
|
||||||
pi := common.Page{"Email Manager", user, headerVars, emailList, nil}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_account_own_edit_email", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.Templates.ExecuteTemplate(w, "account_own_edit_email.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "account_own_edit_email.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -786,7 +773,7 @@ func routeShowAttachment(w http.ResponseWriter, r *http.Request, user common.Use
|
||||||
var originID, uploadedBy int
|
var originID, uploadedBy int
|
||||||
err = stmts.getAttachment.QueryRow(filename, sectionID, sectionTable).Scan(§ionID, §ionTable, &originID, &originTable, &uploadedBy, &filename)
|
err = stmts.getAttachment.QueryRow(filename, sectionID, sectionTable).Scan(§ionID, §ionTable, &originID, &originTable, &uploadedBy, &filename)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return common.NotFound(w, r)
|
return common.NotFound(w, r, nil)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
100
panel_routes.go
100
panel_routes.go
|
@ -31,10 +31,8 @@ func panelSuccessRedirect(dest string, w http.ResponseWriter, r *http.Request, i
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func panelRenderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, user common.User, pi interface{}) common.RouteError {
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_"+tmplName, w, r, &user, pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err := common.Templates.ExecuteTemplate(w, tmplName+".html", pi)
|
err := common.Templates.ExecuteTemplate(w, tmplName+".html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -253,10 +251,8 @@ func routePanelForumsDelete(w http.ResponseWriter, r *http.Request, user common.
|
||||||
yousure := common.AreYouSure{"/panel/forums/delete/submit/" + strconv.Itoa(fid), confirmMsg}
|
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}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_panel_delete_forum", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.Templates.ExecuteTemplate(w, "are_you_sure.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "are_you_sure.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -330,10 +326,8 @@ func routePanelForumsEdit(w http.ResponseWriter, r *http.Request, user common.Us
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelEditForumPage{common.GetTitlePhrase("panel_edit_forum"), user, headerVars, stats, "forums", forum.ID, forum.Name, forum.Desc, forum.Active, forum.Preset, gplist}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_panel_edit_forum", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-forum-edit.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "panel-forum-edit.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -493,10 +487,8 @@ func routePanelForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, us
|
||||||
addNameLangToggle("MoveTopic", forumPerms.MoveTopic)
|
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}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_panel_edit_forum", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-forum-edit-perms.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "panel-forum-edit-perms.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -801,6 +793,7 @@ func routePanelAnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user
|
||||||
}
|
}
|
||||||
|
|
||||||
var unixCreatedAt = createdAt.Unix()
|
var unixCreatedAt = createdAt.Unix()
|
||||||
|
// TODO: Bulk log this
|
||||||
if common.Dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("count: ", count)
|
log.Print("count: ", count)
|
||||||
log.Print("createdAt: ", createdAt)
|
log.Print("createdAt: ", createdAt)
|
||||||
|
@ -883,6 +876,7 @@ func routePanelAnalyticsSystemViews(w http.ResponseWriter, r *http.Request, user
|
||||||
}
|
}
|
||||||
|
|
||||||
var unixCreatedAt = createdAt.Unix()
|
var unixCreatedAt = createdAt.Unix()
|
||||||
|
// TODO: Bulk log this
|
||||||
if common.Dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("count: ", count)
|
log.Print("count: ", count)
|
||||||
log.Print("createdAt: ", createdAt)
|
log.Print("createdAt: ", createdAt)
|
||||||
|
@ -964,6 +958,7 @@ func routePanelAnalyticsReferrerViews(w http.ResponseWriter, r *http.Request, us
|
||||||
}
|
}
|
||||||
|
|
||||||
var unixCreatedAt = createdAt.Unix()
|
var unixCreatedAt = createdAt.Unix()
|
||||||
|
// TODO: Bulk log this
|
||||||
if common.Dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("count: ", count)
|
log.Print("count: ", count)
|
||||||
log.Print("createdAt: ", createdAt)
|
log.Print("createdAt: ", createdAt)
|
||||||
|
@ -1038,6 +1033,7 @@ func routePanelAnalyticsTopics(w http.ResponseWriter, r *http.Request, user comm
|
||||||
}
|
}
|
||||||
|
|
||||||
var unixCreatedAt = createdAt.Unix()
|
var unixCreatedAt = createdAt.Unix()
|
||||||
|
// TODO: Bulk log this
|
||||||
if common.Dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("count: ", count)
|
log.Print("count: ", count)
|
||||||
log.Print("createdAt: ", createdAt)
|
log.Print("createdAt: ", createdAt)
|
||||||
|
@ -1171,6 +1167,7 @@ func routePanelAnalyticsRoutes(w http.ResponseWriter, r *http.Request, user comm
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Bulk log this
|
||||||
if common.Dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("count: ", count)
|
log.Print("count: ", count)
|
||||||
log.Print("route: ", route)
|
log.Print("route: ", route)
|
||||||
|
@ -1222,6 +1219,7 @@ func routePanelAnalyticsAgents(w http.ResponseWriter, r *http.Request, user comm
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Bulk log this
|
||||||
if common.Dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("count: ", count)
|
log.Print("count: ", count)
|
||||||
log.Print("agent: ", agent)
|
log.Print("agent: ", agent)
|
||||||
|
@ -1278,6 +1276,7 @@ func routePanelAnalyticsSystems(w http.ResponseWriter, r *http.Request, user com
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Bulk log this
|
||||||
if common.Dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("count: ", count)
|
log.Print("count: ", count)
|
||||||
log.Print("system: ", system)
|
log.Print("system: ", system)
|
||||||
|
@ -1334,6 +1333,7 @@ func routePanelAnalyticsReferrers(w http.ResponseWriter, r *http.Request, user c
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Bulk log this
|
||||||
if common.Dev.SuperDebug {
|
if common.Dev.SuperDebug {
|
||||||
log.Print("count: ", count)
|
log.Print("count: ", count)
|
||||||
log.Print("domain: ", domain)
|
log.Print("domain: ", domain)
|
||||||
|
@ -1850,10 +1850,8 @@ func routePanelUsersEdit(w http.ResponseWriter, r *http.Request, user common.Use
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelPage{common.GetTitlePhrase("panel_edit_user"), user, headerVars, stats, "users", groupList, targetUser}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_panel_edit_user", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-user-edit.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "panel-user-edit.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2015,7 +2013,7 @@ func routePanelGroupsEdit(w http.ResponseWriter, r *http.Request, user common.Us
|
||||||
group, err := common.Groups.Get(gid)
|
group, err := common.Groups.Get(gid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
//log.Print("aaaaa monsters")
|
//log.Print("aaaaa monsters")
|
||||||
return common.NotFound(w, r)
|
return common.NotFound(w, r, headerVars)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -2044,10 +2042,8 @@ func routePanelGroupsEdit(w http.ResponseWriter, r *http.Request, user common.Us
|
||||||
disableRank := !user.Perms.EditGroupGlobalPerms || (group.ID == 6)
|
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}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_panel_edit_group", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-group-edit.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "panel-group-edit.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2073,7 +2069,7 @@ func routePanelGroupsEditPerms(w http.ResponseWriter, r *http.Request, user comm
|
||||||
group, err := common.Groups.Get(gid)
|
group, err := common.Groups.Get(gid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
//log.Print("aaaaa monsters")
|
//log.Print("aaaaa monsters")
|
||||||
return common.NotFound(w, r)
|
return common.NotFound(w, r, headerVars)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -2132,10 +2128,8 @@ func routePanelGroupsEditPerms(w http.ResponseWriter, r *http.Request, user comm
|
||||||
addGlobalPerm("UploadFiles", group.Perms.UploadFiles)
|
addGlobalPerm("UploadFiles", group.Perms.UploadFiles)
|
||||||
|
|
||||||
pi := common.PanelEditGroupPermsPage{common.GetTitlePhrase("panel_edit_group"), user, headerVars, stats, "groups", group.ID, group.Name, localPerms, globalPerms}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_panel_edit_group_perms", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.Templates.ExecuteTemplate(w, "panel-group-edit-perms.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "panel-group-edit-perms.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2161,7 +2155,7 @@ func routePanelGroupsEditSubmit(w http.ResponseWriter, r *http.Request, user com
|
||||||
group, err := common.Groups.Get(gid)
|
group, err := common.Groups.Get(gid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
//log.Print("aaaaa monsters")
|
//log.Print("aaaaa monsters")
|
||||||
return common.NotFound(w, r)
|
return common.NotFound(w, r, nil)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
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)
|
group, err := common.Groups.Get(gid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
//log.Print("aaaaa monsters o.o")
|
//log.Print("aaaaa monsters o.o")
|
||||||
return common.NotFound(w, r)
|
return common.NotFound(w, r, nil)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -2444,7 +2438,7 @@ func routePanelBackups(w http.ResponseWriter, r *http.Request, user common.User,
|
||||||
if ext == ".sql" {
|
if ext == ".sql" {
|
||||||
info, err := os.Stat("./backups/" + backupURL)
|
info, err := os.Stat("./backups/" + backupURL)
|
||||||
if err != nil {
|
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
|
// 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")
|
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)
|
http.ServeFile(w, r, "./backups/"+backupURL)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return common.NotFound(w, r)
|
return common.NotFound(w, r, headerVars)
|
||||||
}
|
}
|
||||||
|
|
||||||
var backupList []common.BackupItem
|
var backupList []common.BackupItem
|
||||||
|
@ -2487,23 +2481,34 @@ func handleUnknownTopic(topic *common.Topic, err error) *common.Topic {
|
||||||
return topic
|
return topic
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Move the log building logic into /common/ and it's own abstraction
|
||||||
|
func topicElementTypeAction(action string, elementType string, elementID int, actor *common.User, topic *common.Topic) (out string) {
|
||||||
|
if action == "delete" {
|
||||||
|
return fmt.Sprintf("Topic #%d was deleted by <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>"
|
||||||
|
case "unlock":
|
||||||
|
out = "<a href='%s'>%s</a> was reopened by <a href='%s'>%s</a>"
|
||||||
|
case "stick":
|
||||||
|
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 "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)
|
||||||
|
}
|
||||||
|
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) {
|
func modlogsElementType(action string, elementType string, elementID int, actor *common.User) (out string) {
|
||||||
switch elementType {
|
switch elementType {
|
||||||
case "topic":
|
case "topic":
|
||||||
topic := handleUnknownTopic(common.Topics.Get(elementID))
|
topic := handleUnknownTopic(common.Topics.Get(elementID))
|
||||||
switch action {
|
out = topicElementTypeAction(action, elementType, elementID, actor, topic)
|
||||||
case "lock":
|
|
||||||
out = "<a href='%s'>%s</a> was locked by <a href='%s'>%s</a>"
|
|
||||||
case "unlock":
|
|
||||||
out = "<a href='%s'>%s</a> was reopened by <a href='%s'>%s</a>"
|
|
||||||
case "stick":
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
out = fmt.Sprintf(out, topic.Link, topic.Title, actor.Link, actor.Name)
|
|
||||||
case "user":
|
case "user":
|
||||||
targetUser := handleUnknownUser(common.Users.Get(elementID))
|
targetUser := handleUnknownUser(common.Users.Get(elementID))
|
||||||
switch action {
|
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)
|
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 == "" {
|
if out == "" {
|
||||||
out = fmt.Sprintf("Unknown action '%s' on elementType '%s' by <a href='%s'>%s</a>", action, elementType, actor.Link, actor.Name)
|
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
|
// nolint
|
||||||
func _gen_mssql() (err error) {
|
func _gen_mssql() (err error) {
|
||||||
if common.Dev.DebugMode {
|
common.DebugLog("Building the generated statements")
|
||||||
log.Print("Building the generated statements")
|
|
||||||
}
|
|
||||||
` + body + `
|
` + body + `
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -684,9 +684,7 @@ type Stmts struct {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func _gen_mysql() (err error) {
|
func _gen_mysql() (err error) {
|
||||||
if common.Dev.DebugMode {
|
common.DebugLog("Building the generated statements")
|
||||||
log.Print("Building the generated statements")
|
|
||||||
}
|
|
||||||
` + body + `
|
` + body + `
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -381,9 +381,7 @@ type Stmts struct {
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func _gen_pgsql() (err error) {
|
func _gen_pgsql() (err error) {
|
||||||
if common.Dev.DebugMode {
|
common.DebugLog("Building the generated statements")
|
||||||
log.Print("Building the generated statements")
|
|
||||||
}
|
|
||||||
` + body + `
|
` + body + `
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,16 +433,14 @@ func createTables(adapter qgen.Adapter) error {
|
||||||
[]qgen.DBTableKey{},
|
[]qgen.DBTableKey{},
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
qgen.Install.CreateTable("viewchunks_forums", "", "",
|
||||||
qgen.Install.CreateTable("viewchunks_forums", "", "",
|
[]qgen.DBTableColumn{
|
||||||
[]qgen.DBTableColumn{
|
qgen.DBTableColumn{"count", "int", 0, false, false, "0"},
|
||||||
qgen.DBTableColumn{"count", "int", 0, false, false, "0"},
|
qgen.DBTableColumn{"createdAt", "datetime", 0, false, false, ""},
|
||||||
qgen.DBTableColumn{"createdAt", "datetime", 0, false, false, ""},
|
qgen.DBTableColumn{"forum", "int", 0, false, false, ""},
|
||||||
qgen.DBTableColumn{"forum", "int", 0, false, false, ""},
|
},
|
||||||
},
|
[]qgen.DBTableKey{},
|
||||||
[]qgen.DBTableKey{},
|
)
|
||||||
)
|
|
||||||
*/
|
|
||||||
|
|
||||||
qgen.Install.CreateTable("topicchunks", "", "",
|
qgen.Install.CreateTable("topicchunks", "", "",
|
||||||
[]qgen.DBTableColumn{
|
[]qgen.DBTableColumn{
|
||||||
|
|
|
@ -63,5 +63,5 @@ func (router *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//log.Print("req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/')]",req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/')])
|
//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
|
var end = len(route.Path) - 1
|
||||||
out += "\n\t\tcase \"" + route.Path[0:end] + "\":"
|
out += "\n\t\tcase \"" + route.Path[0:end] + "\":"
|
||||||
out += runBefore(route.RunBefore, 4)
|
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"
|
out += "\n\t\t\terr = " + route.Name + "(w,req,user"
|
||||||
for _, item := range route.Vars {
|
for _, item := range route.Vars {
|
||||||
out += "," + item
|
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"
|
out += "\n\t\t\t\t\terr = " + route.Name + "(w,req,user"
|
||||||
for _, item := range route.Vars {
|
for _, item := range route.Vars {
|
||||||
out += "," + item
|
out += "," + item
|
||||||
|
@ -140,7 +140,7 @@ func main() {
|
||||||
mapIt(defaultRoute.Name)
|
mapIt(defaultRoute.Name)
|
||||||
out += "\n\t\t\t\tdefault:"
|
out += "\n\t\t\t\tdefault:"
|
||||||
out += runBefore(defaultRoute.RunBefore, 4)
|
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"
|
out += "\n\t\t\t\t\terr = " + defaultRoute.Name + "(w,req,user"
|
||||||
for _, item := range defaultRoute.Vars {
|
for _, item := range defaultRoute.Vars {
|
||||||
out += ", " + item
|
out += ", " + item
|
||||||
|
@ -157,6 +157,7 @@ func main() {
|
||||||
// Stubs for us to refer to these routes through
|
// Stubs for us to refer to these routes through
|
||||||
mapIt("routeDynamic")
|
mapIt("routeDynamic")
|
||||||
mapIt("routeUploads")
|
mapIt("routeUploads")
|
||||||
|
mapIt("routes.StaticFile")
|
||||||
mapIt("BadRoute")
|
mapIt("BadRoute")
|
||||||
tmplVars.AllRouteNames = allRouteNames
|
tmplVars.AllRouteNames = allRouteNames
|
||||||
tmplVars.AllRouteMap = allRouteMap
|
tmplVars.AllRouteMap = allRouteMap
|
||||||
|
@ -224,6 +225,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"./common"
|
"./common"
|
||||||
|
"./common/counters"
|
||||||
"./routes"
|
"./routes"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -287,12 +289,12 @@ var markToAgent = map[string]string{
|
||||||
|
|
||||||
// TODO: Stop spilling these into the package scope?
|
// TODO: Stop spilling these into the package scope?
|
||||||
func init() {
|
func init() {
|
||||||
common.SetRouteMapEnum(routeMapEnum)
|
counters.SetRouteMapEnum(routeMapEnum)
|
||||||
common.SetReverseRouteMapEnum(reverseRouteMapEnum)
|
counters.SetReverseRouteMapEnum(reverseRouteMapEnum)
|
||||||
common.SetAgentMapEnum(agentMapEnum)
|
counters.SetAgentMapEnum(agentMapEnum)
|
||||||
common.SetReverseAgentMapEnum(reverseAgentMapEnum)
|
counters.SetReverseAgentMapEnum(reverseAgentMapEnum)
|
||||||
common.SetOSMapEnum(osMapEnum)
|
counters.SetOSMapEnum(osMapEnum)
|
||||||
common.SetReverseOSMapEnum(reverseOSMapEnum)
|
counters.SetReverseOSMapEnum(reverseOSMapEnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
type GenRouter struct {
|
type GenRouter struct {
|
||||||
|
@ -359,7 +361,7 @@ func (router *GenRouter) DumpRequest(req *http.Request) {
|
||||||
func (router *GenRouter) SuspiciousRequest(req *http.Request) {
|
func (router *GenRouter) SuspiciousRequest(req *http.Request) {
|
||||||
log.Print("Suspicious Request")
|
log.Print("Suspicious Request")
|
||||||
router.DumpRequest(req)
|
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
|
// 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(""))
|
w.Write([]byte(""))
|
||||||
log.Print("Malformed Request")
|
log.Print("Malformed Request")
|
||||||
router.DumpRequest(req)
|
router.DumpRequest(req)
|
||||||
common.AgentViewCounter.Bump({{.AllAgentMap.malformed}})
|
counters.AgentViewCounter.Bump({{.AllAgentMap.malformed}})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,8 +424,11 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
log.Print("before routes.StaticFile")
|
log.Print("before routes.StaticFile")
|
||||||
router.DumpRequest(req)
|
router.DumpRequest(req)
|
||||||
}
|
}
|
||||||
|
// Increment the request counter
|
||||||
|
counters.GlobalViewCounter.Bump()
|
||||||
|
|
||||||
if prefix == "/static" {
|
if prefix == "/static" {
|
||||||
|
counters.RouteViewCounter.Bump({{ index .AllRouteMap "routes.StaticFile" }})
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
routes.StaticFile(w, req)
|
routes.StaticFile(w, req)
|
||||||
return
|
return
|
||||||
|
@ -432,15 +437,12 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
log.Print("before PreRoute")
|
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.
|
// 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: Add a setting to disable this?
|
||||||
// TODO: Use a more efficient detector instead of smashing every possible combination in
|
// 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
|
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 == "" {
|
if ua == "" {
|
||||||
common.AgentViewCounter.Bump({{.AllAgentMap.blank}})
|
counters.AgentViewCounter.Bump({{.AllAgentMap.blank}})
|
||||||
if common.Dev.DebugMode {
|
if common.Dev.DebugMode {
|
||||||
log.Print("Blank UA: ", req.UserAgent())
|
log.Print("Blank UA: ", req.UserAgent())
|
||||||
router.DumpRequest(req)
|
router.DumpRequest(req)
|
||||||
|
@ -540,15 +542,15 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if agent == "" {
|
if agent == "" {
|
||||||
common.AgentViewCounter.Bump({{.AllAgentMap.unknown}})
|
counters.AgentViewCounter.Bump({{.AllAgentMap.unknown}})
|
||||||
if common.Dev.DebugMode {
|
if common.Dev.DebugMode {
|
||||||
log.Print("Unknown UA: ", req.UserAgent())
|
log.Print("Unknown UA: ", req.UserAgent())
|
||||||
router.DumpRequest(req)
|
router.DumpRequest(req)
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
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]
|
referrer = strings.Split(referrer,"/")[0]
|
||||||
portless := strings.Split(referrer,":")[0]
|
portless := strings.Split(referrer,":")[0]
|
||||||
if portless != "localhost" && portless != "127.0.0.1" && portless != common.Site.Host {
|
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":
|
case "/uploads":
|
||||||
if extraData == "" {
|
if extraData == "" {
|
||||||
common.NotFound(w,req)
|
common.NotFound(w,req,nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
common.RouteViewCounter.Bump({{.AllRouteMap.routeUploads}})
|
counters.RouteViewCounter.Bump({{.AllRouteMap.routeUploads}})
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
// TODO: Find a way to propagate errors up from this?
|
// TODO: Find a way to propagate errors up from this?
|
||||||
router.UploadHandler(w,req) // TODO: Count these views
|
router.UploadHandler(w,req) // TODO: Count these views
|
||||||
|
@ -607,7 +609,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return*/
|
return*/
|
||||||
}
|
}
|
||||||
if extraData != "" {
|
if extraData != "" {
|
||||||
common.NotFound(w,req)
|
common.NotFound(w,req,nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,10 +617,10 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
if !ok {
|
if !ok {
|
||||||
// TODO: Make this a startup error not a runtime one
|
// TODO: Make this a startup error not a runtime one
|
||||||
log.Print("Unable to find the default route")
|
log.Print("Unable to find the default route")
|
||||||
common.NotFound(w,req)
|
common.NotFound(w,req,nil)
|
||||||
return
|
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)
|
handle.(func(http.ResponseWriter, *http.Request, common.User) common.RouteError)(w,req,user)
|
||||||
default:
|
default:
|
||||||
|
@ -628,7 +630,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
router.RUnlock()
|
router.RUnlock()
|
||||||
|
|
||||||
if ok {
|
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
|
req.URL.Path += extraData
|
||||||
err = handle(w,req,user)
|
err = handle(w,req,user)
|
||||||
if err != nil {
|
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") {
|
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)
|
router.SuspiciousRequest(req)
|
||||||
}
|
}
|
||||||
common.RouteViewCounter.Bump({{.AllRouteMap.BadRoute}})
|
counters.RouteViewCounter.Bump({{.AllRouteMap.BadRoute}})
|
||||||
common.NotFound(w,req)
|
common.NotFound(w,req,nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
28
routes.go
28
routes.go
|
@ -64,15 +64,15 @@ func routeForum(w http.ResponseWriter, r *http.Request, user common.User, sfid s
|
||||||
if !user.Perms.ViewTopic {
|
if !user.Perms.ViewTopic {
|
||||||
return common.NoPermissions(w, r, user)
|
return common.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
headerVars.Zone = "view_forum"
|
||||||
|
|
||||||
// TODO: Fix this double-check
|
// TODO: Fix this double-check
|
||||||
forum, err := common.Forums.Get(fid)
|
forum, err := common.Forums.Get(fid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return common.NotFound(w, r)
|
return common.NotFound(w, r, headerVars)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
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
|
// 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)
|
offset, page, lastPage := common.PageOffset(forum.TopicCount, page, common.Config.ItemsPerPage)
|
||||||
|
@ -130,10 +130,8 @@ func routeForum(w http.ResponseWriter, r *http.Request, user common.User, sfid s
|
||||||
|
|
||||||
pageList := common.Paginate(forum.TopicCount, common.Config.ItemsPerPage, 5)
|
pageList := common.Paginate(forum.TopicCount, common.Config.ItemsPerPage, 5)
|
||||||
pi := common.ForumPage{forum.Name, user, headerVars, topicList, forum, pageList, page, lastPage}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_forum", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "forum", pi, w)
|
err = common.RunThemeTemplate(headerVars.Theme.Name, "forum", pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -180,18 +178,14 @@ func routeForums(w http.ResponseWriter, r *http.Request, user common.User) commo
|
||||||
} else {
|
} else {
|
||||||
forum.LastTopicTime = ""
|
forum.LastTopicTime = ""
|
||||||
}
|
}
|
||||||
if common.Hooks["forums_frow_assign"] != nil {
|
common.RunHook("forums_frow_assign", &forum)
|
||||||
common.RunHook("forums_frow_assign", &forum)
|
|
||||||
}
|
|
||||||
forumList = append(forumList, forum)
|
forumList = append(forumList, forum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.ForumsPage{common.GetTitlePhrase("forums"), user, headerVars, forumList}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_forum_list", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "forums", pi, w)
|
err = common.RunThemeTemplate(headerVars.Theme.Name, "forums", pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -233,7 +227,7 @@ func routeProfile(w http.ResponseWriter, r *http.Request, user common.User) comm
|
||||||
// TODO: Add a shared function for checking for ErrNoRows and internal erroring if it's not that case?
|
// TODO: Add a shared function for checking for ErrNoRows and internal erroring if it's not that case?
|
||||||
puser, err = common.Users.Get(pid)
|
puser, err = common.Users.Get(pid)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
return common.NotFound(w, r)
|
return common.NotFound(w, r, headerVars)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -288,10 +282,8 @@ func routeProfile(w http.ResponseWriter, r *http.Request, user common.User) comm
|
||||||
|
|
||||||
// TODO: Add a phrase for this title
|
// TODO: Add a phrase for this title
|
||||||
ppage := common.ProfilePage{puser.Name + "'s Profile", user, headerVars, replyList, *puser}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_profile", w, r, &user, &ppage) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "profile", ppage, w)
|
err = common.RunThemeTemplate(headerVars.Theme.Name, "profile", ppage, w)
|
||||||
|
|
|
@ -22,10 +22,8 @@ func AccountLogin(w http.ResponseWriter, r *http.Request, user common.User) comm
|
||||||
return common.LocalError("You're already logged in.", w, r, user)
|
return common.LocalError("You're already logged in.", w, r, user)
|
||||||
}
|
}
|
||||||
pi := common.Page{common.GetTitlePhrase("login"), user, headerVars, tList, nil}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_login", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err := common.Templates.ExecuteTemplate(w, "login.html", pi)
|
err := common.Templates.ExecuteTemplate(w, "login.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -83,10 +81,8 @@ func AccountRegister(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
return common.LocalError("You're already logged in.", w, r, user)
|
return common.LocalError("You're already logged in.", w, r, user)
|
||||||
}
|
}
|
||||||
pi := common.Page{common.GetTitlePhrase("register"), user, headerVars, tList, nil}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_register", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err := common.Templates.ExecuteTemplate(w, "register.html", pi)
|
err := common.Templates.ExecuteTemplate(w, "register.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -124,9 +120,7 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.U
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmPassword := r.PostFormValue("confirm_password")
|
confirmPassword := r.PostFormValue("confirm_password")
|
||||||
if common.Dev.DebugMode {
|
common.DebugLog("Registration Attempt! Username: " + username) // TODO: Add more controls over what is logged when?
|
||||||
log.Print("Registration Attempt! Username: " + username) // TODO: Add more controls over what is logged when?
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do the two inputted passwords match..?
|
// Do the two inputted passwords match..?
|
||||||
if password != confirmPassword {
|
if password != confirmPassword {
|
||||||
|
@ -187,10 +181,8 @@ func AccountEditCritical(w http.ResponseWriter, r *http.Request, user common.Use
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.Page{"Edit Password", user, headerVars, tList, nil}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_account_own_edit_critical", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err := common.Templates.ExecuteTemplate(w, "account_own_edit.html", pi)
|
err := common.Templates.ExecuteTemplate(w, "account_own_edit.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -3,7 +3,6 @@ package routes
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -18,9 +17,7 @@ var cacheControlMaxAge = "max-age=" + strconv.Itoa(common.Day) // TODO: Make thi
|
||||||
func StaticFile(w http.ResponseWriter, r *http.Request) {
|
func StaticFile(w http.ResponseWriter, r *http.Request) {
|
||||||
file, ok := common.StaticFiles.Get(r.URL.Path)
|
file, ok := common.StaticFiles.Get(r.URL.Path)
|
||||||
if !ok {
|
if !ok {
|
||||||
if common.Dev.DebugMode {
|
common.DebugLogf("Failed to find '%s'", r.URL.Path)
|
||||||
log.Printf("Failed to find '%s'", r.URL.Path)
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -55,12 +52,9 @@ func Overview(w http.ResponseWriter, r *http.Request, user common.User) common.R
|
||||||
headerVars.Zone = "overview"
|
headerVars.Zone = "overview"
|
||||||
|
|
||||||
pi := common.Page{common.GetTitlePhrase("overview"), user, headerVars, tList, nil}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_overview", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err := common.Templates.ExecuteTemplate(w, "overview.html", pi)
|
err := common.Templates.ExecuteTemplate(w, "overview.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
|
@ -73,19 +67,17 @@ func CustomPage(w http.ResponseWriter, r *http.Request, user common.User, name s
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
|
headerVars.Zone = "custom_page"
|
||||||
|
|
||||||
// ! Is this safe?
|
// ! Is this safe?
|
||||||
if common.Templates.Lookup("page_"+name+".html") == nil {
|
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}
|
pi := common.Page{common.GetTitlePhrase("page"), user, headerVars, tList, nil}
|
||||||
// TODO: Pass the page name to the pre-render hook?
|
// 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) {
|
||||||
if common.RunPreRenderHook("pre_render_custom_page", w, r, &user, &pi) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err := common.Templates.ExecuteTemplate(w, "page_"+name+".html", pi)
|
err := common.Templates.ExecuteTemplate(w, "page_"+name+".html", pi)
|
||||||
|
|
|
@ -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}
|
pi := common.IPSearchPage{common.GetTitlePhrase("ip-search"), user, headerVars, userList, ip}
|
||||||
if common.PreRenderHooks["pre_render_ip_search"] != nil {
|
if common.RunPreRenderHook("pre_render_ip_search", w, r, &user, &pi) {
|
||||||
if common.RunPreRenderHook("pre_render_ip_search", w, r, &user, &pi) {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "ip-search.html", pi)
|
err = common.Templates.ExecuteTemplate(w, "ip-search.html", pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return common.InternalError(err, w, r)
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"../common"
|
"../common"
|
||||||
|
"../common/counters"
|
||||||
"../query_gen/lib"
|
"../query_gen/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit
|
||||||
// Get the topic...
|
// Get the topic...
|
||||||
topic, err := common.GetTopicUser(tid)
|
topic, err := common.GetTopicUser(tid)
|
||||||
if err == sql.ErrNoRows {
|
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 {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_view_topic", w, r, &user, &tpage) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "topic", tpage, w)
|
err = common.RunThemeTemplate(headerVars.Theme.Name, "topic", tpage, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,6 +255,7 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user common.User, sfid
|
||||||
forum := common.Forums.DirtyGet(ffid)
|
forum := common.Forums.DirtyGet(ffid)
|
||||||
if forum.Name != "" && forum.Active {
|
if forum.Name != "" && forum.Active {
|
||||||
fcopy := forum.Copy()
|
fcopy := forum.Copy()
|
||||||
|
// TODO: Abstract this
|
||||||
if common.Hooks["topic_create_frow_assign"] != nil {
|
if common.Hooks["topic_create_frow_assign"] != nil {
|
||||||
// TODO: Add the skip feature to all the other row based hooks?
|
// TODO: Add the skip feature to all the other row based hooks?
|
||||||
if common.RunHook("topic_create_frow_assign", &fcopy).(bool) {
|
if common.RunHook("topic_create_frow_assign", &fcopy).(bool) {
|
||||||
|
@ -267,10 +267,8 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user common.User, sfid
|
||||||
}
|
}
|
||||||
|
|
||||||
ctpage := common.CreateTopicPage{"Create Topic", user, headerVars, forumList, fid}
|
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) {
|
||||||
if common.RunPreRenderHook("pre_render_create_topic", w, r, &user, &ctpage) {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "create_topic", ctpage, w)
|
err = common.RunThemeTemplate(headerVars.Theme.Name, "create_topic", ctpage, w)
|
||||||
|
@ -382,9 +380,7 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
if common.Dev.DebugMode {
|
common.DebugLog("file.Filename ", file.Filename)
|
||||||
log.Print("file.Filename ", file.Filename)
|
|
||||||
}
|
|
||||||
extarr := strings.Split(file.Filename, ".")
|
extarr := strings.Split(file.Filename, ".")
|
||||||
if len(extarr) < 2 {
|
if len(extarr) < 2 {
|
||||||
return common.LocalError("Bad file", w, r, user)
|
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()
|
counters.PostCounter.Bump()
|
||||||
common.TopicCounter.Bump()
|
counters.TopicCounter.Bump()
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
|
||||||
return nil
|
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("topicList: %+v\n", topicList)
|
||||||
//log.Printf("forumList: %+v\n", forumList)
|
//log.Printf("forumList: %+v\n", forumList)
|
||||||
if len(topicList) == 0 {
|
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}
|
pi := common.TopicsPage{common.GetTitlePhrase("topics"), user, headerVars, topicList, forumList, common.Config.DefaultForum, pageList, page, lastPage}
|
||||||
if common.PreRenderHooks["pre_render_topic_list"] != nil {
|
if common.RunPreRenderHook("pre_render_topic_list", w, r, &user, &pi) {
|
||||||
if common.RunPreRenderHook("pre_render_topic_list", w, r, &user, &pi) {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
err = common.RunThemeTemplate(headerVars.Theme.Name, "topics", pi, w)
|
err = common.RunThemeTemplate(headerVars.Theme.Name, "topics", pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
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 style="clear: both;"></div>
|
||||||
</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(`
|
var forums_22 = []byte(`
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1104,7 +1104,7 @@ var topics_58 = []byte(`</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</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_60 = []byte(` <a href="/topics/create/">Start one?</a>`)
|
||||||
var topics_61 = []byte(`</div>`)
|
var topics_61 = []byte(`</div>`)
|
||||||
var topics_62 = []byte(`
|
var topics_62 = []byte(`
|
||||||
|
@ -1279,7 +1279,7 @@ var forum_50 = []byte(`</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</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_52 = []byte(` <a href="/topics/create/`)
|
||||||
var forum_53 = []byte(`">Start one?</a>`)
|
var forum_53 = []byte(`">Start one?</a>`)
|
||||||
var forum_54 = []byte(`</div>`)
|
var forum_54 = []byte(`</div>`)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="rowitem"><h1>Are you sure?</h1></div>
|
<div class="rowitem"><h1>Are you sure?</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rowblock">
|
<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>
|
<a class="username" href="{{.Something.URL}}?session={{.CurrentUser.Session}}">Continue</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="rowitem"><h1>An error has occured</h1></div>
|
<div class="rowitem"><h1>An error has occured</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rowblock">
|
<div class="rowblock">
|
||||||
<div class="rowitem passive">{{.Something}}</div>
|
<div class="rowitem passive rowmsg">{{.Something}}</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
{{template "footer.html" . }}
|
{{template "footer.html" . }}
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
<span class="rowsmall lastReplyAt">{{.RelativeLastReplyAt}}</span>
|
<span class="rowsmall lastReplyAt">{{.RelativeLastReplyAt}}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
|
||||||
{{if gt .LastPage 1}}
|
{{if gt .LastPage 1}}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
</span>
|
</span>
|
||||||
<div style="clear: both;"></div>
|
<div style="clear: both;"></div>
|
||||||
</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>
|
</div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<a href="/panel/analytics/agent/{{.Agent}}" class="panel_upshift">{{.FriendlyAgent}}</a>
|
<a href="/panel/analytics/agent/{{.Agent}}" class="panel_upshift">{{.FriendlyAgent}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{else}}<div class="rowitem passive rowmsg">No user agents could be found in the selected time range</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
<a class="panel_upshift unix_to_24_hour_time">{{.Time}}</a>
|
<a class="panel_upshift unix_to_24_hour_time">{{.Time}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{else}}<div class="rowitem passive rowmsg">No posts could be found in the selected time range</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<a href="/panel/analytics/referrer/{{.Agent}}" class="panel_upshift">{{.Agent}}</a>
|
<a href="/panel/analytics/referrer/{{.Agent}}" class="panel_upshift">{{.Agent}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{else}}<div class="rowitem passive rowmsg">No referrers could be found in the selected time range</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<a href="/panel/analytics/route/{{.Route}}" class="panel_upshift">{{.Route}}</a>
|
<a href="/panel/analytics/route/{{.Route}}" class="panel_upshift">{{.Route}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{else}}<div class="rowitem passive rowmsg">No route view counts could be found in the selected time range</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<a href="/panel/analytics/system/{{.Agent}}" class="panel_upshift">{{.FriendlyAgent}}</a>
|
<a href="/panel/analytics/system/{{.Agent}}" class="panel_upshift">{{.FriendlyAgent}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
<span class="panel_compacttext to_right">{{.Count}} views</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{else}}<div class="rowitem passive rowmsg">No operating systems could be found in the selected time range</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{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}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="rowitem editable_parent">
|
<div class="rowitem editable_parent rowmsg">
|
||||||
<a>You don't have any word filters yet.</a>
|
<a>You don't have any word filters yet.</a>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -123,7 +123,7 @@
|
||||||
<span class="rowsmall lastReplyAt">{{.RelativeLastReplyAt}}</span>
|
<span class="rowsmall lastReplyAt">{{.RelativeLastReplyAt}}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
|
||||||
{{if gt .LastPage 1}}
|
{{if gt .LastPage 1}}
|
||||||
|
|
|
@ -232,6 +232,7 @@ ul {
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
}
|
}
|
||||||
/* TODO: Reduce the number of nots */
|
/* 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 {
|
.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);
|
background-color: var(--element-background-color);
|
||||||
}
|
}
|
||||||
|
@ -269,6 +270,15 @@ h1, h3 {
|
||||||
margin-bottom: 0px;
|
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 {
|
.colstack {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
@ -692,8 +702,8 @@ textarea {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
display: flex;
|
display: flex;
|
||||||
border: 1px solid var(--element-border-color);
|
border: 1px solid var(--element-border-color);
|
||||||
border-bottom: 2px solid var(--element-border-color);
|
border-bottom: 2px solid var(--element-border-color);
|
||||||
}
|
}
|
||||||
.rowlist .rowitem {
|
.rowlist .rowitem {
|
||||||
background-color: var(--element-background-color);
|
background-color: var(--element-background-color);
|
||||||
|
|
|
@ -39,12 +39,15 @@
|
||||||
}
|
}
|
||||||
.colstack_right {
|
.colstack_right {
|
||||||
margin-right: 14px;
|
margin-right: 14px;
|
||||||
margin-top: -4px;
|
/*margin-top: -4px;*/
|
||||||
margin-bottom: 14px;
|
margin-bottom: 14px;
|
||||||
}
|
}
|
||||||
.footer {
|
.footer {
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
}
|
}
|
||||||
|
.colstack_right .colstack_head:not(:first-child) {
|
||||||
|
margin-top: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
.complex_rowlist {
|
.complex_rowlist {
|
||||||
background-color: inherit !important;
|
background-color: inherit !important;
|
||||||
|
@ -210,4 +213,10 @@
|
||||||
|
|
||||||
.pageset {
|
.pageset {
|
||||||
margin-left: 16px;
|
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 {
|
.edit_button:before {
|
||||||
content: "Edit";
|
content: "Edit";
|
||||||
|
@ -97,6 +103,18 @@
|
||||||
padding-right: 2px;
|
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) {
|
@media(max-width: 1300px) {
|
||||||
.theme_row { background-image: none !important; }
|
.theme_row { background-image: none !important; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
}
|
}
|
||||||
ul {
|
ul {
|
||||||
height: 30px;
|
height: 30px;
|
||||||
margin-top: 8px;
|
margin-top: 14px;
|
||||||
}
|
}
|
||||||
.menu_left, .menu_right { padding-right: 9px; }
|
.menu_left, .menu_right { padding-right: 9px; }
|
||||||
.menu_alerts {
|
.menu_alerts {
|
||||||
|
@ -30,8 +30,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
padding-left: 4px;
|
padding-left: 12px;
|
||||||
padding-right: 4px;
|
padding-right: 12px;
|
||||||
margin: 0px !important;
|
margin: 0px !important;
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
|
|
Loading…
Reference in New Issue