Basic group promotions.
Add the users_groups_promotions table. Optimise ConvoViewPage. Shortened some things. Convo CSS fixes. Make sure the user cache is flushed properly after the post stats change. You will need to run the patcher / updater for this commit.
This commit is contained in:
parent
48344ac57d
commit
78c5c62eee
|
@ -69,6 +69,22 @@ func createTables(adapter qgen.Adapter) error {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
qgen.Install.CreateTable("users_groups_promotions", mysqlPre, mysqlCol,
|
||||||
|
[]tC{
|
||||||
|
tC{"pid", "int", 0, false, true, ""},
|
||||||
|
tC{"from_gid", "int", 0, false, false, ""},
|
||||||
|
tC{"to_gid", "int", 0, false, false, ""},
|
||||||
|
tC{"two_way", "boolean",0,false,false,"0"}, // If a user no longer meets the requirements for this promotion then they will be demoted if this flag is set
|
||||||
|
|
||||||
|
// Requirements
|
||||||
|
tC{"level", "int", 0, false, false, ""},
|
||||||
|
tC{"minTime", "int", 0, false, false, ""}, // How long someone needs to have been in their current group before being promoted
|
||||||
|
},
|
||||||
|
[]tblKey{
|
||||||
|
tblKey{"pid", "primary","",false},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
qgen.Install.CreateTable("users_2fa_keys", mysqlPre, mysqlCol,
|
qgen.Install.CreateTable("users_2fa_keys", mysqlPre, mysqlCol,
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"uid", "int", 0, false, false, ""},
|
tC{"uid", "int", 0, false, false, ""},
|
||||||
|
|
|
@ -25,8 +25,8 @@ func NewDefaultActivityStream(acc *qgen.Accumulator) (*DefaultActivityStream, er
|
||||||
}, acc.FirstError()
|
}, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefaultActivityStream) Add(alert Alert) (int, error) {
|
func (s *DefaultActivityStream) Add(a Alert) (int, error) {
|
||||||
res, err := s.add.Exec(alert.ActorID, alert.TargetUserID, alert.Event, alert.ElementType, alert.ElementID)
|
res, err := s.add.Exec(a.ActorID, a.TargetUserID, a.Event, a.ElementType, a.ElementID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ func (s *DefaultActivityStream) Add(alert Alert) (int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefaultActivityStream) Get(id int) (Alert, error) {
|
func (s *DefaultActivityStream) Get(id int) (Alert, error) {
|
||||||
var a = Alert{ASID: id}
|
a := Alert{ASID: id}
|
||||||
err := s.get.QueryRow(id).Scan(&a.ActorID, &a.TargetUserID, &a.Event, &a.ElementType, &a.ElementID, &a.CreatedAt)
|
err := s.get.QueryRow(id).Scan(&a.ActorID, &a.TargetUserID, &a.Event, &a.ElementType, &a.ElementID, &a.CreatedAt)
|
||||||
return a, err
|
return a, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ func BuildAlert(alert Alert, user User /* The current user */) (out string, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var url, area string
|
var url, area string
|
||||||
var phraseName = "." + alert.ElementType
|
phraseName := "." + alert.ElementType
|
||||||
switch alert.ElementType {
|
switch alert.ElementType {
|
||||||
case "topic":
|
case "topic":
|
||||||
topic, err := Topics.Get(alert.ElementID)
|
topic, err := Topics.Get(alert.ElementID)
|
||||||
|
|
|
@ -16,7 +16,7 @@ type Email struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendValidationEmail(username string, email string, token string) error {
|
func SendValidationEmail(username string, email string, token string) error {
|
||||||
var schema = "http"
|
schema := "http"
|
||||||
if Site.EnableSsl {
|
if Site.EnableSsl {
|
||||||
schema += "s"
|
schema += "s"
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ func NewDefaultEmailStore(acc *qgen.Accumulator) (*DefaultEmailStore, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefaultEmailStore) GetEmailsByUser(user *User) (emails []Email, err error) {
|
func (s *DefaultEmailStore) GetEmailsByUser(user *User) (emails []Email, err error) {
|
||||||
email := Email{UserID: user.ID}
|
e := Email{UserID: user.ID}
|
||||||
rows, err := s.getEmailsByUser.Query(user.ID)
|
rows, err := s.getEmailsByUser.Query(user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return emails, err
|
return emails, err
|
||||||
|
@ -36,15 +36,15 @@ func (s *DefaultEmailStore) GetEmailsByUser(user *User) (emails []Email, err err
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
err := rows.Scan(&email.Email, &email.Validated, &email.Token)
|
err := rows.Scan(&e.Email, &e.Validated, &e.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return emails, err
|
return emails, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if email.Email == user.Email {
|
if e.Email == user.Email {
|
||||||
email.Primary = true
|
e.Primary = true
|
||||||
}
|
}
|
||||||
emails = append(emails, email)
|
emails = append(emails, e)
|
||||||
}
|
}
|
||||||
return emails, rows.Err()
|
return emails, rows.Err()
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ func (list SFileList) JSTmplInit() error {
|
||||||
|
|
||||||
fragset := tmpl.GetFrag(shortName)
|
fragset := tmpl.GetFrag(shortName)
|
||||||
if fragset != nil {
|
if fragset != nil {
|
||||||
var sfrags = []byte("let " + shortName + "_frags = [];\n")
|
sfrags := []byte("let " + shortName + "_frags = [];\n")
|
||||||
for _, frags := range fragset {
|
for _, frags := range fragset {
|
||||||
sfrags = append(sfrags, []byte(shortName+"_frags.push(`"+string(frags)+"`);\n")...)
|
sfrags = append(sfrags, []byte(shortName+"_frags.push(`"+string(frags)+"`);\n")...)
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ func (list SFileList) JSTmplInit() error {
|
||||||
|
|
||||||
path = tmplName + ".js"
|
path = tmplName + ".js"
|
||||||
DebugLog("js path: ", path)
|
DebugLog("js path: ", path)
|
||||||
var ext = filepath.Ext("/tmpl_client/" + path)
|
ext := filepath.Ext("/tmpl_client/" + path)
|
||||||
gzipData, err := CompressBytesGzip(data)
|
gzipData, err := CompressBytesGzip(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -306,7 +306,7 @@ func (list SFileList) Add(path string, prefix string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var ext = filepath.Ext(path)
|
ext := filepath.Ext(path)
|
||||||
path = strings.TrimPrefix(path, prefix)
|
path = strings.TrimPrefix(path, prefix)
|
||||||
gzipData, err := CompressBytesGzip(data)
|
gzipData, err := CompressBytesGzip(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -229,8 +229,8 @@ func ForumPermsToGroupForumPreset(fperms *ForumPerms) string {
|
||||||
if !fperms.ViewTopic {
|
if !fperms.ViewTopic {
|
||||||
return "no_access"
|
return "no_access"
|
||||||
}
|
}
|
||||||
var canPost = (fperms.LikeItem && fperms.CreateTopic && fperms.CreateReply)
|
canPost := (fperms.LikeItem && fperms.CreateTopic && fperms.CreateReply)
|
||||||
var canModerate = (canPost && fperms.EditTopic && fperms.DeleteTopic && fperms.EditReply && fperms.DeleteReply && fperms.PinTopic && fperms.CloseTopic && fperms.MoveTopic)
|
canModerate := (canPost && fperms.EditTopic && fperms.DeleteTopic && fperms.EditReply && fperms.DeleteReply && fperms.PinTopic && fperms.CloseTopic && fperms.MoveTopic)
|
||||||
if canModerate {
|
if canModerate {
|
||||||
return "can_moderate"
|
return "can_moderate"
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,14 +329,14 @@ func (s *MemoryForumStore) UpdateLastTopic(tid int, uid int, fid int) error {
|
||||||
return s.Reload(fid)
|
return s.Reload(fid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MemoryForumStore) Create(forumName string, forumDesc string, active bool, preset string) (int, error) {
|
func (s *MemoryForumStore) Create(name string, desc string, active bool, preset string) (int, error) {
|
||||||
if forumName == "" {
|
if name == "" {
|
||||||
return 0, ErrBlankName
|
return 0, ErrBlankName
|
||||||
}
|
}
|
||||||
forumCreateMutex.Lock()
|
forumCreateMutex.Lock()
|
||||||
defer forumCreateMutex.Unlock()
|
defer forumCreateMutex.Unlock()
|
||||||
|
|
||||||
res, err := s.create.Exec(forumName, forumDesc, active, preset)
|
res, err := s.create.Exec(name, desc, active, preset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,8 @@ func NewDefaultIPSearcher() (*DefaultIPSearcher, error) {
|
||||||
|
|
||||||
func (searcher *DefaultIPSearcher) Lookup(ip string) (uids []int, err error) {
|
func (searcher *DefaultIPSearcher) Lookup(ip string) (uids []int, err error) {
|
||||||
var uid int
|
var uid int
|
||||||
var reqUserList = make(map[int]bool)
|
reqUserList := make(map[int]bool)
|
||||||
|
runQuery := func(stmt *sql.Stmt) error {
|
||||||
var runQuery = func(stmt *sql.Stmt) error {
|
|
||||||
rows, err := stmt.Query(ip)
|
rows, err := stmt.Query(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -579,6 +579,20 @@ type PanelEditGroupPermsPage struct {
|
||||||
GlobalPerms []NameLangToggle
|
GlobalPerms []NameLangToggle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GroupPromotionExtend struct {
|
||||||
|
*GroupPromotion
|
||||||
|
FromGroup *Group
|
||||||
|
ToGroup *Group
|
||||||
|
}
|
||||||
|
|
||||||
|
type PanelEditGroupPromotionsPage struct {
|
||||||
|
*BasePanelPage
|
||||||
|
ID int
|
||||||
|
Name string
|
||||||
|
Promotions []*GroupPromotionExtend
|
||||||
|
Groups []*Group
|
||||||
|
}
|
||||||
|
|
||||||
type BackupItem struct {
|
type BackupItem struct {
|
||||||
SQLURL string
|
SQLURL string
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ func (r *DefaultPasswordResetter) ValidateToken(uid int, token string) error {
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
var success = false
|
success := false
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var rtoken string
|
var rtoken string
|
||||||
err := rows.Scan(&rtoken)
|
err := rows.Scan(&rtoken)
|
||||||
|
|
|
@ -46,7 +46,6 @@ func InitPluginLangs() error {
|
||||||
for _, pluginLang := range pluginLangs {
|
for _, pluginLang := range pluginLangs {
|
||||||
pluginLang.Init()
|
pluginLang.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginList, err := GetPluginFiles()
|
pluginList, err := GetPluginFiles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -80,7 +79,7 @@ func InitPluginLangs() error {
|
||||||
return errors.New("Couldn't find a main file for plugin '" + pluginItem + "'")
|
return errors.New("Couldn't find a main file for plugin '" + pluginItem + "'")
|
||||||
}
|
}
|
||||||
|
|
||||||
var ext = filepath.Ext(plugin.Main)
|
ext := filepath.Ext(plugin.Main)
|
||||||
pluginLang, err := ExtToPluginLang(ext)
|
pluginLang, err := ExtToPluginLang(ext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
|
||||||
|
qgen "github.com/Azareal/Gosora/query_gen"
|
||||||
|
)
|
||||||
|
|
||||||
|
var GroupPromotions *DefaultGroupPromotionStore
|
||||||
|
|
||||||
|
type GroupPromotion struct {
|
||||||
|
ID int
|
||||||
|
From int
|
||||||
|
To int
|
||||||
|
TwoWay bool
|
||||||
|
|
||||||
|
Level int
|
||||||
|
MinTime int
|
||||||
|
}
|
||||||
|
|
||||||
|
type GroupPromotionStore interface {
|
||||||
|
GetByGroup() ([]*GroupPromotion, error)
|
||||||
|
Get(id int) (*GroupPromotion, error)
|
||||||
|
PromoteIfEligible(u *User, level int) error
|
||||||
|
Delete(id int) error
|
||||||
|
Create(from int, to int, twoWay bool, level int) (int, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DefaultGroupPromotionStore struct {
|
||||||
|
getByGroup *sql.Stmt
|
||||||
|
get *sql.Stmt
|
||||||
|
delete *sql.Stmt
|
||||||
|
create *sql.Stmt
|
||||||
|
|
||||||
|
getByUser *sql.Stmt
|
||||||
|
updateUser *sql.Stmt
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultGroupPromotionStore(acc *qgen.Accumulator) (*DefaultGroupPromotionStore, error) {
|
||||||
|
ugp := "users_groups_promotions"
|
||||||
|
return &DefaultGroupPromotionStore{
|
||||||
|
getByGroup: acc.Select(ugp).Columns("pid, from_gid, to_gid, two_way, level, minTime").Where("from_gid=? OR to_gid=?").Prepare(),
|
||||||
|
get: acc.Select(ugp).Columns("from_gid, to_gid, two_way, level, minTime").Where("pid = ?").Prepare(),
|
||||||
|
delete: acc.Delete(ugp).Where("pid = ?").Prepare(),
|
||||||
|
create: acc.Insert(ugp).Columns("from_gid, to_gid, two_way, level, minTime").Fields("?,?,?,?,?").Prepare(),
|
||||||
|
|
||||||
|
getByUser: acc.Select(ugp).Columns("pid, to_gid, two_way, level, minTime").Where("from_gid=? AND level>=?").Orderby("level DESC").Limit("1").Prepare(),
|
||||||
|
updateUser: acc.Update("users").Set("group = ?").Where("level >= ?").Prepare(),
|
||||||
|
}, acc.FirstError()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DefaultGroupPromotionStore) GetByGroup(gid int) (gps []*GroupPromotion, err error) {
|
||||||
|
rows, err := s.getByGroup.Query(gid, gid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
g := &GroupPromotion{}
|
||||||
|
err := rows.Scan(&g.ID, &g.From, &g.To, &g.TwoWay, &g.Level, &g.MinTime)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
gps = append(gps, g)
|
||||||
|
}
|
||||||
|
return gps, rows.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Cache the group promotions to avoid hitting the database as much
|
||||||
|
func (s *DefaultGroupPromotionStore) Get(id int) (*GroupPromotion, error) {
|
||||||
|
/*g, err := s.cache.Get(id)
|
||||||
|
if err == nil {
|
||||||
|
return u, nil
|
||||||
|
}*/
|
||||||
|
|
||||||
|
g := &GroupPromotion{ID: id}
|
||||||
|
err := s.get.QueryRow(id).Scan(&g.From, &g.To, &g.TwoWay, &g.Level, &g.MinTime)
|
||||||
|
if err == nil {
|
||||||
|
//s.cache.Set(u)
|
||||||
|
}
|
||||||
|
return g, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DefaultGroupPromotionStore) PromoteIfEligible(u *User, level int) error {
|
||||||
|
g := &GroupPromotion{From: u.Group}
|
||||||
|
err := s.getByUser.QueryRow(u.Group, level).Scan(&g.ID, &g.To, &g.TwoWay, &g.Level, &g.MinTime)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return nil
|
||||||
|
} else if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = s.updateUser.Exec(g.To, g.Level)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DefaultGroupPromotionStore) Delete(id int) error {
|
||||||
|
_, err := s.delete.Exec(id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DefaultGroupPromotionStore) Create(from int, to int, twoWay bool, level int) (int, error) {
|
||||||
|
res, err := s.create.Exec(from, to, twoWay, level, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
lastID, err := res.LastInsertId()
|
||||||
|
return int(lastID), err
|
||||||
|
}
|
|
@ -18,15 +18,15 @@ func NewDefaultStatStore() *DefaultStatStore {
|
||||||
return &DefaultStatStore{}
|
return &DefaultStatStore{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *DefaultStatStore) LookupInt(name string, duration int, unit string) (int, error) {
|
func (s *DefaultStatStore) LookupInt(name string, duration int, unit string) (int, error) {
|
||||||
switch name {
|
switch name {
|
||||||
case "postCount":
|
case "postCount":
|
||||||
return store.countTable("replies", duration, unit)
|
return s.countTable("replies", duration, unit)
|
||||||
}
|
}
|
||||||
return 0, errors.New("The requested stat doesn't exist")
|
return 0, errors.New("The requested stat doesn't exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *DefaultStatStore) countTable(table string, duration int, unit string) (stat int, err error) {
|
func (s *DefaultStatStore) countTable(table string, duration int, unit string) (stat int, err error) {
|
||||||
/*counter := qgen.NewAcc().Count("replies").DateCutoff("createdAt", 1, "day").Prepare()
|
/*counter := qgen.NewAcc().Count("replies").DateCutoff("createdAt", 1, "day").Prepare()
|
||||||
if acc.FirstError() != nil {
|
if acc.FirstError() != nil {
|
||||||
return 0, acc.FirstError()
|
return 0, acc.FirstError()
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import "database/sql"
|
import (
|
||||||
import "github.com/Azareal/Gosora/query_gen"
|
"database/sql"
|
||||||
|
|
||||||
|
qgen "github.com/Azareal/Gosora/query_gen"
|
||||||
|
)
|
||||||
|
|
||||||
var Subscriptions SubscriptionStore
|
var Subscriptions SubscriptionStore
|
||||||
|
|
||||||
|
@ -21,7 +24,7 @@ func NewDefaultSubscriptionStore() (*DefaultSubscriptionStore, error) {
|
||||||
}, acc.FirstError()
|
}, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (store *DefaultSubscriptionStore) Add(uid int, elementID int, elementType string) error {
|
func (s *DefaultSubscriptionStore) Add(uid int, elementID int, elementType string) error {
|
||||||
_, err := store.add.Exec(uid, elementID, elementType)
|
_, err := s.add.Exec(uid, elementID, elementType)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,14 +289,14 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
|
||||||
header.Title = name
|
header.Title = name
|
||||||
return header
|
return header
|
||||||
}
|
}
|
||||||
tmpls := TItemHold(make(map[string]TItem))
|
t := TItemHold(make(map[string]TItem))
|
||||||
err = compileCommons(c, header, header2, forumList, tmpls)
|
err = compileCommons(c, header, header2, forumList, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ppage := ProfilePage{htitle("User 526"), replyList, user, 0, 0} // TODO: Use the score from user to generate the currentScore and nextScore
|
ppage := ProfilePage{htitle("User 526"), replyList, user, 0, 0} // TODO: Use the score from user to generate the currentScore and nextScore
|
||||||
tmpls.Add("profile", "c.ProfilePage", ppage)
|
t.Add("profile", "c.ProfilePage", ppage)
|
||||||
|
|
||||||
var topicsList []*TopicsRow
|
var topicsList []*TopicsRow
|
||||||
topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 1, 0, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil})
|
topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 1, 0, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil})
|
||||||
|
@ -331,38 +331,38 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
|
||||||
}
|
}
|
||||||
|
|
||||||
if typ == "1" {
|
if typ == "1" {
|
||||||
tmpls.Add(sp[0], sp[1], pi)
|
t.Add(sp[0], sp[1], pi)
|
||||||
} else {
|
} else {
|
||||||
tmpls.AddStd(sp[0], sp[1], pi)
|
t.AddStd(sp[0], sp[1], pi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpls.AddStd("login", "c.Page", Page{htitle("Login Page"), tList, nil})
|
t.AddStd("login", "c.Page", Page{htitle("Login Page"), tList, nil})
|
||||||
tmpls.AddStd("register", "c.Page", Page{htitle("Registration Page"), tList, "nananana"})
|
t.AddStd("register", "c.Page", Page{htitle("Registration Page"), tList, "nananana"})
|
||||||
tmpls.AddStd("error", "c.ErrorPage", ErrorPage{htitle("Error"), "A problem has occurred in the system."})
|
t.AddStd("error", "c.ErrorPage", ErrorPage{htitle("Error"), "A problem has occurred in the system."})
|
||||||
|
|
||||||
ipSearchPage := IPSearchPage{htitle("IP Search"), map[int]*User{1: &user2}, "::1"}
|
ipSearchPage := IPSearchPage{htitle("IP Search"), map[int]*User{1: &user2}, "::1"}
|
||||||
tmpls.AddStd("ip_search", "c.IPSearchPage", ipSearchPage)
|
t.AddStd("ip_search", "c.IPSearchPage", ipSearchPage)
|
||||||
|
|
||||||
var inter nobreak
|
var inter nobreak
|
||||||
accountPage := Account{header, "dashboard", "account_own_edit", inter}
|
accountPage := Account{header, "dashboard", "account_own_edit", inter}
|
||||||
tmpls.AddStd("account", "c.Account", accountPage)
|
t.AddStd("account", "c.Account", accountPage)
|
||||||
|
|
||||||
parti := []*User{&user}
|
parti := []*User{&user}
|
||||||
convo := &Conversation{1,user.ID,time.Now(),0,time.Now()}
|
convo := &Conversation{1,user.ID,time.Now(),0,time.Now()}
|
||||||
convoItems := []ConvoViewRow{ConvoViewRow{&ConversationPost{1,1,"hey","",user.ID}, &user, "", 4, true}}
|
convoItems := []ConvoViewRow{ConvoViewRow{&ConversationPost{1,1,"hey","",user.ID}, &user, "", 4, true}}
|
||||||
convoPage := ConvoViewPage{header, convo, convoItems, parti, Paginator{[]int{1}, 1, 1}}
|
convoPage := ConvoViewPage{header, convo, convoItems, parti, Paginator{[]int{1}, 1, 1}}
|
||||||
tmpls.AddStd("convo", "c.ConvoViewPage", convoPage)
|
t.AddStd("convo", "c.ConvoViewPage", convoPage)
|
||||||
|
|
||||||
convos := []*ConversationExtra{&ConversationExtra{&Conversation{},[]*User{&user}}}
|
convos := []*ConversationExtra{&ConversationExtra{&Conversation{},[]*User{&user}}}
|
||||||
convoListPage := ConvoListPage{header, convos, Paginator{[]int{1}, 1, 1}}
|
convoListPage := ConvoListPage{header, convos, Paginator{[]int{1}, 1, 1}}
|
||||||
tmpls.AddStd("convos", "c.ConvoListPage", convoListPage)
|
t.AddStd("convos", "c.ConvoListPage", convoListPage)
|
||||||
|
|
||||||
basePage := &BasePanelPage{header, PanelStats{}, "dashboard", ReportForumID}
|
basePage := &BasePanelPage{header, PanelStats{}, "dashboard", ReportForumID}
|
||||||
tmpls.AddStd("panel", "c.Panel", Panel{basePage, "panel_dashboard_right", "", "panel_dashboard", inter})
|
t.AddStd("panel", "c.Panel", Panel{basePage, "panel_dashboard_right", "", "panel_dashboard", inter})
|
||||||
ges := []GridElement{GridElement{"","", "", 1, "grid_istat", "", "", ""}}
|
ges := []GridElement{GridElement{"","", "", 1, "grid_istat", "", "", ""}}
|
||||||
tmpls.AddStd("panel_dashboard", "c.DashGrids", DashGrids{ges,ges})
|
t.AddStd("panel_dashboard", "c.DashGrids", DashGrids{ges,ges})
|
||||||
//tmpls.AddStd("panel_analytics", "c.PanelAnalytics", Panel{basePage, "panel_dashboard_right","panel_dashboard", inter})
|
//t.AddStd("panel_analytics", "c.PanelAnalytics", Panel{basePage, "panel_dashboard_right","panel_dashboard", inter})
|
||||||
|
|
||||||
writeTemplate := func(name string, content interface{}) {
|
writeTemplate := func(name string, content interface{}) {
|
||||||
log.Print("Writing template '" + name + "'")
|
log.Print("Writing template '" + name + "'")
|
||||||
|
@ -409,7 +409,7 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Writing the templates")
|
log.Print("Writing the templates")
|
||||||
for name, titem := range tmpls {
|
for name, titem := range t {
|
||||||
log.Print("Writing " + name)
|
log.Print("Writing " + name)
|
||||||
varList := make(map[string]tmpl.VarItem)
|
varList := make(map[string]tmpl.VarItem)
|
||||||
if titem.LoggedIn {
|
if titem.LoggedIn {
|
||||||
|
@ -444,15 +444,15 @@ func CompileJSTemplates() error {
|
||||||
}
|
}
|
||||||
log.Printf("overriden: %+v\n", overriden)
|
log.Printf("overriden: %+v\n", overriden)
|
||||||
|
|
||||||
var config tmpl.CTemplateConfig
|
config := tmpl.CTemplateConfig{
|
||||||
config.Minify = Config.MinifyTemplates
|
Minify: Config.MinifyTemplates,
|
||||||
config.Debug = Dev.DebugMode
|
Debug: Dev.DebugMode,
|
||||||
config.SuperDebug = Dev.TemplateDebug
|
SuperDebug: Dev.TemplateDebug,
|
||||||
config.SkipHandles = true
|
SkipHandles: true,
|
||||||
config.SkipTmplPtrMap = true
|
SkipTmplPtrMap: true,
|
||||||
config.SkipInitBlock = false
|
SkipInitBlock: false,
|
||||||
config.PackageName = "tmpl"
|
PackageName: "tmpl",
|
||||||
|
}
|
||||||
c := tmpl.NewCTemplateSet("js")
|
c := tmpl.NewCTemplateSet("js")
|
||||||
c.SetConfig(config)
|
c.SetConfig(config)
|
||||||
c.SetBuildTags("!no_templategen")
|
c.SetBuildTags("!no_templategen")
|
||||||
|
@ -509,10 +509,10 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
|
||||||
// TODO: Fix the import loop so we don't have to use this hack anymore
|
// TODO: Fix the import loop so we don't have to use this hack anymore
|
||||||
c.SetBuildTags("!no_templategen,tmplgentopic")
|
c.SetBuildTags("!no_templategen,tmplgentopic")
|
||||||
|
|
||||||
tmpls := TItemHold(make(map[string]TItem))
|
t := TItemHold(make(map[string]TItem))
|
||||||
|
|
||||||
topicsRow := &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 0, 1, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil}
|
topicsRow := &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 0, 1, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil}
|
||||||
tmpls.AddStd("topics_topic", "c.TopicsRow", topicsRow)
|
t.AddStd("topics_topic", "c.TopicsRow", topicsRow)
|
||||||
|
|
||||||
poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{
|
poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{
|
||||||
PollOption{0, "Nothing"},
|
PollOption{0, "Nothing"},
|
||||||
|
@ -533,19 +533,25 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
|
||||||
header.Title = "Topic Name"
|
header.Title = "Topic Name"
|
||||||
tpage := TopicPage{header, replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, poll, Paginator{[]int{1}, 1, 1}}
|
tpage := TopicPage{header, replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, poll, Paginator{[]int{1}, 1, 1}}
|
||||||
tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID)
|
tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID)
|
||||||
tmpls.AddStd("topic_posts", "c.TopicPage", tpage)
|
t.AddStd("topic_posts", "c.TopicPage", tpage)
|
||||||
tmpls.AddStd("topic_alt_posts", "c.TopicPage", tpage)
|
t.AddStd("topic_alt_posts", "c.TopicPage", tpage)
|
||||||
|
|
||||||
itemsPerPage := 25
|
itemsPerPage := 25
|
||||||
_, page, lastPage := PageOffset(20, 1, itemsPerPage)
|
_, page, lastPage := PageOffset(20, 1, itemsPerPage)
|
||||||
pageList := Paginate(page, lastPage, 5)
|
pageList := Paginate(page, lastPage, 5)
|
||||||
tmpls.AddStd("paginator", "c.Paginator", Paginator{pageList, page, lastPage})
|
t.AddStd("paginator", "c.Paginator", Paginator{pageList, page, lastPage})
|
||||||
|
|
||||||
tmpls.AddStd("topic_c_edit_post", "c.TopicCEditPost", TopicCEditPost{ID: 0, Source: "", Ref: ""})
|
t.AddStd("topic_c_edit_post", "c.TopicCEditPost", TopicCEditPost{ID: 0, Source: "", Ref: ""})
|
||||||
tmpls.AddStd("topic_c_attach_item", "c.TopicCAttachItem", TopicCAttachItem{ID: 1, ImgSrc: "", Path: "", FullPath: ""})
|
t.AddStd("topic_c_attach_item", "c.TopicCAttachItem", TopicCAttachItem{ID: 1, ImgSrc: "", Path: "", FullPath: ""})
|
||||||
tmpls.AddStd("topic_c_poll_input", "c.TopicCPollInput", TopicCPollInput{Index:0})
|
t.AddStd("topic_c_poll_input", "c.TopicCPollInput", TopicCPollInput{Index:0})
|
||||||
|
|
||||||
tmpls.AddStd("notice", "string", "nonono")
|
parti := []*User{&user}
|
||||||
|
convo := &Conversation{1,user.ID,time.Now(),0,time.Now()}
|
||||||
|
convoItems := []ConvoViewRow{ConvoViewRow{&ConversationPost{1,1,"hey","",user.ID}, &user, "", 4, true}}
|
||||||
|
convoPage := ConvoViewPage{header, convo, convoItems, parti, Paginator{[]int{1}, 1, 1}}
|
||||||
|
t.AddStd("convo", "c.ConvoViewPage", convoPage)
|
||||||
|
|
||||||
|
t.AddStd("notice", "string", "nonono")
|
||||||
|
|
||||||
dirPrefix := "./tmpl_client/"
|
dirPrefix := "./tmpl_client/"
|
||||||
writeTemplate := func(name string, content string) {
|
writeTemplate := func(name string, content string) {
|
||||||
|
@ -568,7 +574,7 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Writing the templates")
|
log.Print("Writing the templates")
|
||||||
for name, titem := range tmpls {
|
for name, titem := range t {
|
||||||
log.Print("Writing " + name)
|
log.Print("Writing " + name)
|
||||||
varList := make(map[string]tmpl.VarItem)
|
varList := make(map[string]tmpl.VarItem)
|
||||||
tmpl, err := c.Compile(name+".html", "templates/", titem.Expects, titem.ExpectsInt, varList)
|
tmpl, err := c.Compile(name+".html", "templates/", titem.Expects, titem.ExpectsInt, varList)
|
||||||
|
@ -802,22 +808,22 @@ func initDefaultTmplFuncMap() {
|
||||||
DefaultTemplateFuncMap = fmap
|
DefaultTemplateFuncMap = fmap
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadTemplates(tmpls *template.Template, themeName string) error {
|
func loadTemplates(t *template.Template, themeName string) error {
|
||||||
tmpls.Funcs(DefaultTemplateFuncMap)
|
t.Funcs(DefaultTemplateFuncMap)
|
||||||
templateFiles, err := filepath.Glob("templates/*.html")
|
tFiles, err := filepath.Glob("templates/*.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
templateFileMap := make(map[string]int)
|
tFileMap := make(map[string]int)
|
||||||
for index, path := range templateFiles {
|
for index, path := range tFiles {
|
||||||
path = strings.Replace(path, "\\", "/", -1)
|
path = strings.Replace(path, "\\", "/", -1)
|
||||||
log.Print("templateFile: ", path)
|
log.Print("templateFile: ", path)
|
||||||
if skipCTmpl(path) {
|
if skipCTmpl(path) {
|
||||||
log.Print("skipping")
|
log.Print("skipping")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
templateFileMap[path] = index
|
tFileMap[path] = index
|
||||||
}
|
}
|
||||||
|
|
||||||
overrideFiles, err := filepath.Glob("templates/overrides/*.html")
|
overrideFiles, err := filepath.Glob("templates/overrides/*.html")
|
||||||
|
@ -831,13 +837,13 @@ func loadTemplates(tmpls *template.Template, themeName string) error {
|
||||||
log.Print("skipping")
|
log.Print("skipping")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
index, ok := templateFileMap["templates/"+strings.TrimPrefix(path, "templates/overrides/")]
|
index, ok := tFileMap["templates/"+strings.TrimPrefix(path, "templates/overrides/")]
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Print("not ok: templates/" + strings.TrimPrefix(path, "templates/overrides/"))
|
log.Print("not ok: templates/" + strings.TrimPrefix(path, "templates/overrides/"))
|
||||||
templateFiles = append(templateFiles, path)
|
tFiles = append(tFiles, path)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
templateFiles[index] = path
|
tFiles[index] = path
|
||||||
}
|
}
|
||||||
|
|
||||||
if themeName != "" {
|
if themeName != "" {
|
||||||
|
@ -852,18 +858,18 @@ func loadTemplates(tmpls *template.Template, themeName string) error {
|
||||||
log.Print("skipping")
|
log.Print("skipping")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
index, ok := templateFileMap["templates/"+strings.TrimPrefix(path, "themes/"+themeName+"/overrides/")]
|
index, ok := tFileMap["templates/"+strings.TrimPrefix(path, "themes/"+themeName+"/overrides/")]
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Print("not ok: templates/" + strings.TrimPrefix(path, "themes/"+themeName+"/overrides/"))
|
log.Print("not ok: templates/" + strings.TrimPrefix(path, "themes/"+themeName+"/overrides/"))
|
||||||
templateFiles = append(templateFiles, path)
|
tFiles = append(tFiles, path)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
templateFiles[index] = path
|
tFiles[index] = path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template.Must(tmpls.ParseFiles(templateFiles...))
|
template.Must(t.ParseFiles(tFiles...))
|
||||||
template.Must(tmpls.ParseGlob("pages/*"))
|
template.Must(t.ParseGlob("pages/*"))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,23 +18,23 @@ type SingleServerThaw struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSingleServerThaw() *SingleServerThaw {
|
func NewSingleServerThaw() *SingleServerThaw {
|
||||||
thaw := &SingleServerThaw{}
|
t := &SingleServerThaw{}
|
||||||
if Config.ServerCount == 1 {
|
if Config.ServerCount == 1 {
|
||||||
AddScheduledSecondTask(thaw.Tick)
|
AddScheduledSecondTask(t.Tick)
|
||||||
}
|
}
|
||||||
return thaw
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (thaw *SingleServerThaw) Thawed() bool {
|
func (t *SingleServerThaw) Thawed() bool {
|
||||||
if Config.ServerCount == 1 {
|
if Config.ServerCount == 1 {
|
||||||
return thaw.DefaultThaw.Thawed()
|
return t.DefaultThaw.Thawed()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (thaw *SingleServerThaw) Thaw() {
|
func (t *SingleServerThaw) Thaw() {
|
||||||
if Config.ServerCount == 1 {
|
if Config.ServerCount == 1 {
|
||||||
thaw.DefaultThaw.Thaw()
|
t.DefaultThaw.Thaw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,24 +43,24 @@ type DefaultThaw struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDefaultThaw() *DefaultThaw {
|
func NewDefaultThaw() *DefaultThaw {
|
||||||
thaw := &DefaultThaw{}
|
t := &DefaultThaw{}
|
||||||
AddScheduledSecondTask(thaw.Tick)
|
AddScheduledSecondTask(t.Tick)
|
||||||
return thaw
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrement the thawed counter once a second until it goes cold
|
// Decrement the thawed counter once a second until it goes cold
|
||||||
func (thaw *DefaultThaw) Tick() error {
|
func (t *DefaultThaw) Tick() error {
|
||||||
prior := thaw.thawed
|
prior := t.thawed
|
||||||
if prior > 0 {
|
if prior > 0 {
|
||||||
atomic.StoreInt64(&thaw.thawed, prior-1)
|
atomic.StoreInt64(&t.thawed, prior-1)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (thaw *DefaultThaw) Thawed() bool {
|
func (t *DefaultThaw) Thawed() bool {
|
||||||
return thaw.thawed > 0
|
return t.thawed > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (thaw *DefaultThaw) Thaw() {
|
func (t *DefaultThaw) Thaw() {
|
||||||
atomic.StoreInt64(&thaw.thawed, 5)
|
atomic.StoreInt64(&t.thawed, 5)
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,8 +145,8 @@ func (theme *Theme) AddThemeStaticFiles() error {
|
||||||
var ext = filepath.Ext(path)
|
var ext = filepath.Ext(path)
|
||||||
if ext == ".css" && len(data) != 0 {
|
if ext == ".css" && len(data) != 0 {
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
var pieces = strings.Split(path, "/")
|
pieces := strings.Split(path, "/")
|
||||||
var filename = pieces[len(pieces)-1]
|
filename := pieces[len(pieces)-1]
|
||||||
// TODO: Prepare resource templates for each loaded langpack?
|
// TODO: Prepare resource templates for each loaded langpack?
|
||||||
err = theme.ResourceTemplates.ExecuteTemplate(&b, filename, CSSData{Phrases: phraseMap})
|
err = theme.ResourceTemplates.ExecuteTemplate(&b, filename, CSSData{Phrases: phraseMap})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -376,9 +376,15 @@ func (u *User) IncreasePostStats(wcount int, topic bool) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//log.Print(u.Score + baseScore + mod)
|
//log.Print(u.Score + baseScore + mod)
|
||||||
//log.Print(getLevel(u.Score + baseScore + mod))
|
|
||||||
// TODO: Use a transaction to prevent level desyncs?
|
// TODO: Use a transaction to prevent level desyncs?
|
||||||
_, err = userStmts.updateLevel.Exec(GetLevel(u.Score+baseScore+mod), u.ID)
|
level := GetLevel(u.Score+baseScore+mod)
|
||||||
|
//log.Print(level)
|
||||||
|
_, err = userStmts.updateLevel.Exec(level, u.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = GroupPromotions.PromoteIfEligible(u,level)
|
||||||
|
u.CacheRemove()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,6 +419,7 @@ func (u *User) DecreasePostStats(wcount int, topic bool) (err error) {
|
||||||
}
|
}
|
||||||
// TODO: Use a transaction to prevent level desyncs?
|
// TODO: Use a transaction to prevent level desyncs?
|
||||||
_, err = userStmts.updateLevel.Exec(GetLevel(u.Score-baseScore-mod), u.ID)
|
_, err = userStmts.updateLevel.Exec(GetLevel(u.Score-baseScore-mod), u.ID)
|
||||||
|
u.CacheRemove()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ func (hub *WsHubImpl) Start() {
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
var item = func(lock *sync.RWMutex, userMap map[int]*WSUser) {
|
item := func(lock *sync.RWMutex, userMap map[int]*WSUser) {
|
||||||
lock.RLock()
|
lock.RLock()
|
||||||
defer lock.RUnlock()
|
defer lock.RUnlock()
|
||||||
// TODO: Copy to temporary slice for less contention?
|
// TODO: Copy to temporary slice for less contention?
|
||||||
|
|
|
@ -408,7 +408,7 @@ func TopicCreatePreLoop(args ...interface{}) interface{} {
|
||||||
|
|
||||||
// TODO: Add privacy options
|
// TODO: Add privacy options
|
||||||
// TODO: Add support for multiple boards and add per-board simplified permissions
|
// TODO: Add support for multiple boards and add per-board simplified permissions
|
||||||
// TODO: Take isJs into account for routes which expect JSON responses
|
// TODO: Take js into account for routes which expect JSON responses
|
||||||
func ForumCheck(args ...interface{}) (skip bool, rerr c.RouteError) {
|
func ForumCheck(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||||
var r = args[1].(*http.Request)
|
var r = args[1].(*http.Request)
|
||||||
var fid = args[3].(*int)
|
var fid = args[3].(*int)
|
||||||
|
@ -416,7 +416,7 @@ func ForumCheck(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||||
|
|
||||||
if forum.ParentType == "guild" {
|
if forum.ParentType == "guild" {
|
||||||
var err error
|
var err error
|
||||||
var w = args[0].(http.ResponseWriter)
|
w := args[0].(http.ResponseWriter)
|
||||||
guildItem, ok := r.Context().Value("guilds_current_group").(*Guild)
|
guildItem, ok := r.Context().Value("guilds_current_group").(*Guild)
|
||||||
if !ok {
|
if !ok {
|
||||||
guildItem, err = Gstore.Get(forum.ParentID)
|
guildItem, err = Gstore.Get(forum.ParentID)
|
||||||
|
@ -429,7 +429,7 @@ func ForumCheck(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||||
r = r.WithContext(context.WithValue(r.Context(), "guilds_current_group", guildItem))
|
r = r.WithContext(context.WithValue(r.Context(), "guilds_current_group", guildItem))
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = args[2].(*c.User)
|
user := args[2].(*c.User)
|
||||||
var rank int
|
var rank int
|
||||||
var posts int
|
var posts int
|
||||||
var joinedAt string
|
var joinedAt string
|
||||||
|
@ -474,15 +474,14 @@ func ForumCheck(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||||
// TODO: Override redirects? I don't think this is needed quite yet
|
// TODO: Override redirects? I don't think this is needed quite yet
|
||||||
|
|
||||||
func Widgets(args ...interface{}) interface{} {
|
func Widgets(args ...interface{}) interface{} {
|
||||||
var zone = args[0].(string)
|
zone := args[0].(string)
|
||||||
var header = args[2].(*c.Header)
|
header := args[2].(*c.Header)
|
||||||
var request = args[3].(*http.Request)
|
request := args[3].(*http.Request)
|
||||||
|
|
||||||
if zone != "view_forum" {
|
if zone != "view_forum" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var forum = args[1].(*c.Forum)
|
forum := args[1].(*c.Forum)
|
||||||
if forum.ParentType == "guild" {
|
if forum.ParentType == "guild" {
|
||||||
// This is why I hate using contexts, all the daisy chains and interface casts x.x
|
// This is why I hate using contexts, all the daisy chains and interface casts x.x
|
||||||
guildItem, ok := request.Context().Value("guilds_current_group").(*Guild)
|
guildItem, ok := request.Context().Value("guilds_current_group").(*Guild)
|
||||||
|
|
490
gen_router.go
490
gen_router.go
|
@ -102,6 +102,9 @@ var RouteMap = map[string]interface{}{
|
||||||
"panel.AnalyticsForums": panel.AnalyticsForums,
|
"panel.AnalyticsForums": panel.AnalyticsForums,
|
||||||
"panel.Groups": panel.Groups,
|
"panel.Groups": panel.Groups,
|
||||||
"panel.GroupsEdit": panel.GroupsEdit,
|
"panel.GroupsEdit": panel.GroupsEdit,
|
||||||
|
"panel.GroupsEditPromotions": panel.GroupsEditPromotions,
|
||||||
|
"panel.GroupsPromotionsCreateSubmit": panel.GroupsPromotionsCreateSubmit,
|
||||||
|
"panel.GroupsPromotionsDeleteSubmit": panel.GroupsPromotionsDeleteSubmit,
|
||||||
"panel.GroupsEditPerms": panel.GroupsEditPerms,
|
"panel.GroupsEditPerms": panel.GroupsEditPerms,
|
||||||
"panel.GroupsEditSubmit": panel.GroupsEditSubmit,
|
"panel.GroupsEditSubmit": panel.GroupsEditSubmit,
|
||||||
"panel.GroupsEditPermsSubmit": panel.GroupsEditPermsSubmit,
|
"panel.GroupsEditPermsSubmit": panel.GroupsEditPermsSubmit,
|
||||||
|
@ -262,83 +265,86 @@ var routeMapEnum = map[string]int{
|
||||||
"panel.AnalyticsForums": 76,
|
"panel.AnalyticsForums": 76,
|
||||||
"panel.Groups": 77,
|
"panel.Groups": 77,
|
||||||
"panel.GroupsEdit": 78,
|
"panel.GroupsEdit": 78,
|
||||||
"panel.GroupsEditPerms": 79,
|
"panel.GroupsEditPromotions": 79,
|
||||||
"panel.GroupsEditSubmit": 80,
|
"panel.GroupsPromotionsCreateSubmit": 80,
|
||||||
"panel.GroupsEditPermsSubmit": 81,
|
"panel.GroupsPromotionsDeleteSubmit": 81,
|
||||||
"panel.GroupsCreateSubmit": 82,
|
"panel.GroupsEditPerms": 82,
|
||||||
"panel.Backups": 83,
|
"panel.GroupsEditSubmit": 83,
|
||||||
"panel.LogsRegs": 84,
|
"panel.GroupsEditPermsSubmit": 84,
|
||||||
"panel.LogsMod": 85,
|
"panel.GroupsCreateSubmit": 85,
|
||||||
"panel.Debug": 86,
|
"panel.Backups": 86,
|
||||||
"panel.Dashboard": 87,
|
"panel.LogsRegs": 87,
|
||||||
"routes.AccountEdit": 88,
|
"panel.LogsMod": 88,
|
||||||
"routes.AccountEditPassword": 89,
|
"panel.Debug": 89,
|
||||||
"routes.AccountEditPasswordSubmit": 90,
|
"panel.Dashboard": 90,
|
||||||
"routes.AccountEditAvatarSubmit": 91,
|
"routes.AccountEdit": 91,
|
||||||
"routes.AccountEditRevokeAvatarSubmit": 92,
|
"routes.AccountEditPassword": 92,
|
||||||
"routes.AccountEditUsernameSubmit": 93,
|
"routes.AccountEditPasswordSubmit": 93,
|
||||||
"routes.AccountEditMFA": 94,
|
"routes.AccountEditAvatarSubmit": 94,
|
||||||
"routes.AccountEditMFASetup": 95,
|
"routes.AccountEditRevokeAvatarSubmit": 95,
|
||||||
"routes.AccountEditMFASetupSubmit": 96,
|
"routes.AccountEditUsernameSubmit": 96,
|
||||||
"routes.AccountEditMFADisableSubmit": 97,
|
"routes.AccountEditMFA": 97,
|
||||||
"routes.AccountEditEmail": 98,
|
"routes.AccountEditMFASetup": 98,
|
||||||
"routes.AccountEditEmailTokenSubmit": 99,
|
"routes.AccountEditMFASetupSubmit": 99,
|
||||||
"routes.AccountLogins": 100,
|
"routes.AccountEditMFADisableSubmit": 100,
|
||||||
"routes.LevelList": 101,
|
"routes.AccountEditEmail": 101,
|
||||||
"routes.Convos": 102,
|
"routes.AccountEditEmailTokenSubmit": 102,
|
||||||
"routes.ConvosCreate": 103,
|
"routes.AccountLogins": 103,
|
||||||
"routes.Convo": 104,
|
"routes.LevelList": 104,
|
||||||
"routes.ConvosCreateSubmit": 105,
|
"routes.Convos": 105,
|
||||||
"routes.ConvosCreateReplySubmit": 106,
|
"routes.ConvosCreate": 106,
|
||||||
"routes.ConvosDeleteReplySubmit": 107,
|
"routes.Convo": 107,
|
||||||
"routes.ConvosEditReplySubmit": 108,
|
"routes.ConvosCreateSubmit": 108,
|
||||||
"routes.ViewProfile": 109,
|
"routes.ConvosCreateReplySubmit": 109,
|
||||||
"routes.BanUserSubmit": 110,
|
"routes.ConvosDeleteReplySubmit": 110,
|
||||||
"routes.UnbanUser": 111,
|
"routes.ConvosEditReplySubmit": 111,
|
||||||
"routes.ActivateUser": 112,
|
"routes.ViewProfile": 112,
|
||||||
"routes.IPSearch": 113,
|
"routes.BanUserSubmit": 113,
|
||||||
"routes.CreateTopicSubmit": 114,
|
"routes.UnbanUser": 114,
|
||||||
"routes.EditTopicSubmit": 115,
|
"routes.ActivateUser": 115,
|
||||||
"routes.DeleteTopicSubmit": 116,
|
"routes.IPSearch": 116,
|
||||||
"routes.StickTopicSubmit": 117,
|
"routes.CreateTopicSubmit": 117,
|
||||||
"routes.UnstickTopicSubmit": 118,
|
"routes.EditTopicSubmit": 118,
|
||||||
"routes.LockTopicSubmit": 119,
|
"routes.DeleteTopicSubmit": 119,
|
||||||
"routes.UnlockTopicSubmit": 120,
|
"routes.StickTopicSubmit": 120,
|
||||||
"routes.MoveTopicSubmit": 121,
|
"routes.UnstickTopicSubmit": 121,
|
||||||
"routes.LikeTopicSubmit": 122,
|
"routes.LockTopicSubmit": 122,
|
||||||
"routes.AddAttachToTopicSubmit": 123,
|
"routes.UnlockTopicSubmit": 123,
|
||||||
"routes.RemoveAttachFromTopicSubmit": 124,
|
"routes.MoveTopicSubmit": 124,
|
||||||
"routes.ViewTopic": 125,
|
"routes.LikeTopicSubmit": 125,
|
||||||
"routes.CreateReplySubmit": 126,
|
"routes.AddAttachToTopicSubmit": 126,
|
||||||
"routes.ReplyEditSubmit": 127,
|
"routes.RemoveAttachFromTopicSubmit": 127,
|
||||||
"routes.ReplyDeleteSubmit": 128,
|
"routes.ViewTopic": 128,
|
||||||
"routes.ReplyLikeSubmit": 129,
|
"routes.CreateReplySubmit": 129,
|
||||||
"routes.AddAttachToReplySubmit": 130,
|
"routes.ReplyEditSubmit": 130,
|
||||||
"routes.RemoveAttachFromReplySubmit": 131,
|
"routes.ReplyDeleteSubmit": 131,
|
||||||
"routes.ProfileReplyCreateSubmit": 132,
|
"routes.ReplyLikeSubmit": 132,
|
||||||
"routes.ProfileReplyEditSubmit": 133,
|
"routes.AddAttachToReplySubmit": 133,
|
||||||
"routes.ProfileReplyDeleteSubmit": 134,
|
"routes.RemoveAttachFromReplySubmit": 134,
|
||||||
"routes.PollVote": 135,
|
"routes.ProfileReplyCreateSubmit": 135,
|
||||||
"routes.PollResults": 136,
|
"routes.ProfileReplyEditSubmit": 136,
|
||||||
"routes.AccountLogin": 137,
|
"routes.ProfileReplyDeleteSubmit": 137,
|
||||||
"routes.AccountRegister": 138,
|
"routes.PollVote": 138,
|
||||||
"routes.AccountLogout": 139,
|
"routes.PollResults": 139,
|
||||||
"routes.AccountLoginSubmit": 140,
|
"routes.AccountLogin": 140,
|
||||||
"routes.AccountLoginMFAVerify": 141,
|
"routes.AccountRegister": 141,
|
||||||
"routes.AccountLoginMFAVerifySubmit": 142,
|
"routes.AccountLogout": 142,
|
||||||
"routes.AccountRegisterSubmit": 143,
|
"routes.AccountLoginSubmit": 143,
|
||||||
"routes.AccountPasswordReset": 144,
|
"routes.AccountLoginMFAVerify": 144,
|
||||||
"routes.AccountPasswordResetSubmit": 145,
|
"routes.AccountLoginMFAVerifySubmit": 145,
|
||||||
"routes.AccountPasswordResetToken": 146,
|
"routes.AccountRegisterSubmit": 146,
|
||||||
"routes.AccountPasswordResetTokenSubmit": 147,
|
"routes.AccountPasswordReset": 147,
|
||||||
"routes.DynamicRoute": 148,
|
"routes.AccountPasswordResetSubmit": 148,
|
||||||
"routes.UploadedFile": 149,
|
"routes.AccountPasswordResetToken": 149,
|
||||||
"routes.StaticFile": 150,
|
"routes.AccountPasswordResetTokenSubmit": 150,
|
||||||
"routes.RobotsTxt": 151,
|
"routes.DynamicRoute": 151,
|
||||||
"routes.SitemapXml": 152,
|
"routes.UploadedFile": 152,
|
||||||
"routes.OpenSearchXml": 153,
|
"routes.StaticFile": 153,
|
||||||
"routes.BadRoute": 154,
|
"routes.RobotsTxt": 154,
|
||||||
"routes.HTTPSRedirect": 155,
|
"routes.SitemapXml": 155,
|
||||||
|
"routes.OpenSearchXml": 156,
|
||||||
|
"routes.BadRoute": 157,
|
||||||
|
"routes.HTTPSRedirect": 158,
|
||||||
}
|
}
|
||||||
var reverseRouteMapEnum = map[int]string{
|
var reverseRouteMapEnum = map[int]string{
|
||||||
0: "routes.Overview",
|
0: "routes.Overview",
|
||||||
|
@ -420,83 +426,86 @@ var reverseRouteMapEnum = map[int]string{
|
||||||
76: "panel.AnalyticsForums",
|
76: "panel.AnalyticsForums",
|
||||||
77: "panel.Groups",
|
77: "panel.Groups",
|
||||||
78: "panel.GroupsEdit",
|
78: "panel.GroupsEdit",
|
||||||
79: "panel.GroupsEditPerms",
|
79: "panel.GroupsEditPromotions",
|
||||||
80: "panel.GroupsEditSubmit",
|
80: "panel.GroupsPromotionsCreateSubmit",
|
||||||
81: "panel.GroupsEditPermsSubmit",
|
81: "panel.GroupsPromotionsDeleteSubmit",
|
||||||
82: "panel.GroupsCreateSubmit",
|
82: "panel.GroupsEditPerms",
|
||||||
83: "panel.Backups",
|
83: "panel.GroupsEditSubmit",
|
||||||
84: "panel.LogsRegs",
|
84: "panel.GroupsEditPermsSubmit",
|
||||||
85: "panel.LogsMod",
|
85: "panel.GroupsCreateSubmit",
|
||||||
86: "panel.Debug",
|
86: "panel.Backups",
|
||||||
87: "panel.Dashboard",
|
87: "panel.LogsRegs",
|
||||||
88: "routes.AccountEdit",
|
88: "panel.LogsMod",
|
||||||
89: "routes.AccountEditPassword",
|
89: "panel.Debug",
|
||||||
90: "routes.AccountEditPasswordSubmit",
|
90: "panel.Dashboard",
|
||||||
91: "routes.AccountEditAvatarSubmit",
|
91: "routes.AccountEdit",
|
||||||
92: "routes.AccountEditRevokeAvatarSubmit",
|
92: "routes.AccountEditPassword",
|
||||||
93: "routes.AccountEditUsernameSubmit",
|
93: "routes.AccountEditPasswordSubmit",
|
||||||
94: "routes.AccountEditMFA",
|
94: "routes.AccountEditAvatarSubmit",
|
||||||
95: "routes.AccountEditMFASetup",
|
95: "routes.AccountEditRevokeAvatarSubmit",
|
||||||
96: "routes.AccountEditMFASetupSubmit",
|
96: "routes.AccountEditUsernameSubmit",
|
||||||
97: "routes.AccountEditMFADisableSubmit",
|
97: "routes.AccountEditMFA",
|
||||||
98: "routes.AccountEditEmail",
|
98: "routes.AccountEditMFASetup",
|
||||||
99: "routes.AccountEditEmailTokenSubmit",
|
99: "routes.AccountEditMFASetupSubmit",
|
||||||
100: "routes.AccountLogins",
|
100: "routes.AccountEditMFADisableSubmit",
|
||||||
101: "routes.LevelList",
|
101: "routes.AccountEditEmail",
|
||||||
102: "routes.Convos",
|
102: "routes.AccountEditEmailTokenSubmit",
|
||||||
103: "routes.ConvosCreate",
|
103: "routes.AccountLogins",
|
||||||
104: "routes.Convo",
|
104: "routes.LevelList",
|
||||||
105: "routes.ConvosCreateSubmit",
|
105: "routes.Convos",
|
||||||
106: "routes.ConvosCreateReplySubmit",
|
106: "routes.ConvosCreate",
|
||||||
107: "routes.ConvosDeleteReplySubmit",
|
107: "routes.Convo",
|
||||||
108: "routes.ConvosEditReplySubmit",
|
108: "routes.ConvosCreateSubmit",
|
||||||
109: "routes.ViewProfile",
|
109: "routes.ConvosCreateReplySubmit",
|
||||||
110: "routes.BanUserSubmit",
|
110: "routes.ConvosDeleteReplySubmit",
|
||||||
111: "routes.UnbanUser",
|
111: "routes.ConvosEditReplySubmit",
|
||||||
112: "routes.ActivateUser",
|
112: "routes.ViewProfile",
|
||||||
113: "routes.IPSearch",
|
113: "routes.BanUserSubmit",
|
||||||
114: "routes.CreateTopicSubmit",
|
114: "routes.UnbanUser",
|
||||||
115: "routes.EditTopicSubmit",
|
115: "routes.ActivateUser",
|
||||||
116: "routes.DeleteTopicSubmit",
|
116: "routes.IPSearch",
|
||||||
117: "routes.StickTopicSubmit",
|
117: "routes.CreateTopicSubmit",
|
||||||
118: "routes.UnstickTopicSubmit",
|
118: "routes.EditTopicSubmit",
|
||||||
119: "routes.LockTopicSubmit",
|
119: "routes.DeleteTopicSubmit",
|
||||||
120: "routes.UnlockTopicSubmit",
|
120: "routes.StickTopicSubmit",
|
||||||
121: "routes.MoveTopicSubmit",
|
121: "routes.UnstickTopicSubmit",
|
||||||
122: "routes.LikeTopicSubmit",
|
122: "routes.LockTopicSubmit",
|
||||||
123: "routes.AddAttachToTopicSubmit",
|
123: "routes.UnlockTopicSubmit",
|
||||||
124: "routes.RemoveAttachFromTopicSubmit",
|
124: "routes.MoveTopicSubmit",
|
||||||
125: "routes.ViewTopic",
|
125: "routes.LikeTopicSubmit",
|
||||||
126: "routes.CreateReplySubmit",
|
126: "routes.AddAttachToTopicSubmit",
|
||||||
127: "routes.ReplyEditSubmit",
|
127: "routes.RemoveAttachFromTopicSubmit",
|
||||||
128: "routes.ReplyDeleteSubmit",
|
128: "routes.ViewTopic",
|
||||||
129: "routes.ReplyLikeSubmit",
|
129: "routes.CreateReplySubmit",
|
||||||
130: "routes.AddAttachToReplySubmit",
|
130: "routes.ReplyEditSubmit",
|
||||||
131: "routes.RemoveAttachFromReplySubmit",
|
131: "routes.ReplyDeleteSubmit",
|
||||||
132: "routes.ProfileReplyCreateSubmit",
|
132: "routes.ReplyLikeSubmit",
|
||||||
133: "routes.ProfileReplyEditSubmit",
|
133: "routes.AddAttachToReplySubmit",
|
||||||
134: "routes.ProfileReplyDeleteSubmit",
|
134: "routes.RemoveAttachFromReplySubmit",
|
||||||
135: "routes.PollVote",
|
135: "routes.ProfileReplyCreateSubmit",
|
||||||
136: "routes.PollResults",
|
136: "routes.ProfileReplyEditSubmit",
|
||||||
137: "routes.AccountLogin",
|
137: "routes.ProfileReplyDeleteSubmit",
|
||||||
138: "routes.AccountRegister",
|
138: "routes.PollVote",
|
||||||
139: "routes.AccountLogout",
|
139: "routes.PollResults",
|
||||||
140: "routes.AccountLoginSubmit",
|
140: "routes.AccountLogin",
|
||||||
141: "routes.AccountLoginMFAVerify",
|
141: "routes.AccountRegister",
|
||||||
142: "routes.AccountLoginMFAVerifySubmit",
|
142: "routes.AccountLogout",
|
||||||
143: "routes.AccountRegisterSubmit",
|
143: "routes.AccountLoginSubmit",
|
||||||
144: "routes.AccountPasswordReset",
|
144: "routes.AccountLoginMFAVerify",
|
||||||
145: "routes.AccountPasswordResetSubmit",
|
145: "routes.AccountLoginMFAVerifySubmit",
|
||||||
146: "routes.AccountPasswordResetToken",
|
146: "routes.AccountRegisterSubmit",
|
||||||
147: "routes.AccountPasswordResetTokenSubmit",
|
147: "routes.AccountPasswordReset",
|
||||||
148: "routes.DynamicRoute",
|
148: "routes.AccountPasswordResetSubmit",
|
||||||
149: "routes.UploadedFile",
|
149: "routes.AccountPasswordResetToken",
|
||||||
150: "routes.StaticFile",
|
150: "routes.AccountPasswordResetTokenSubmit",
|
||||||
151: "routes.RobotsTxt",
|
151: "routes.DynamicRoute",
|
||||||
152: "routes.SitemapXml",
|
152: "routes.UploadedFile",
|
||||||
153: "routes.OpenSearchXml",
|
153: "routes.StaticFile",
|
||||||
154: "routes.BadRoute",
|
154: "routes.RobotsTxt",
|
||||||
155: "routes.HTTPSRedirect",
|
155: "routes.SitemapXml",
|
||||||
|
156: "routes.OpenSearchXml",
|
||||||
|
157: "routes.BadRoute",
|
||||||
|
158: "routes.HTTPSRedirect",
|
||||||
}
|
}
|
||||||
var osMapEnum = map[string]int{
|
var osMapEnum = map[string]int{
|
||||||
"unknown": 0,
|
"unknown": 0,
|
||||||
|
@ -654,7 +663,7 @@ type HTTPSRedirect struct {}
|
||||||
|
|
||||||
func (red *HTTPSRedirect) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (red *HTTPSRedirect) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
w.Header().Set("Connection", "close")
|
w.Header().Set("Connection", "close")
|
||||||
counters.RouteViewCounter.Bump(155)
|
counters.RouteViewCounter.Bump(158)
|
||||||
dest := "https://" + req.Host + req.URL.String()
|
dest := "https://" + req.Host + req.URL.String()
|
||||||
http.Redirect(w, req, dest, http.StatusTemporaryRedirect)
|
http.Redirect(w, req, dest, http.StatusTemporaryRedirect)
|
||||||
}
|
}
|
||||||
|
@ -863,7 +872,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
counters.GlobalViewCounter.Bump()
|
counters.GlobalViewCounter.Bump()
|
||||||
|
|
||||||
if prefix == "/s" { //old prefix: /static
|
if prefix == "/s" { //old prefix: /static
|
||||||
counters.RouteViewCounter.Bump(150)
|
counters.RouteViewCounter.Bump(153)
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
routes.StaticFile(w, req)
|
routes.StaticFile(w, req)
|
||||||
return
|
return
|
||||||
|
@ -1611,8 +1620,27 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
case "/panel/groups/edit/":
|
case "/panel/groups/edit/":
|
||||||
counters.RouteViewCounter.Bump(78)
|
counters.RouteViewCounter.Bump(78)
|
||||||
err = panel.GroupsEdit(w,req,user,extraData)
|
err = panel.GroupsEdit(w,req,user,extraData)
|
||||||
case "/panel/groups/edit/perms/":
|
case "/panel/groups/edit/promotions/":
|
||||||
counters.RouteViewCounter.Bump(79)
|
counters.RouteViewCounter.Bump(79)
|
||||||
|
err = panel.GroupsEditPromotions(w,req,user,extraData)
|
||||||
|
case "/panel/groups/promotions/create/submit/":
|
||||||
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
counters.RouteViewCounter.Bump(80)
|
||||||
|
err = panel.GroupsPromotionsCreateSubmit(w,req,user,extraData)
|
||||||
|
case "/panel/groups/promotions/delete/submit/":
|
||||||
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
counters.RouteViewCounter.Bump(81)
|
||||||
|
err = panel.GroupsPromotionsDeleteSubmit(w,req,user,extraData)
|
||||||
|
case "/panel/groups/edit/perms/":
|
||||||
|
counters.RouteViewCounter.Bump(82)
|
||||||
err = panel.GroupsEditPerms(w,req,user,extraData)
|
err = panel.GroupsEditPerms(w,req,user,extraData)
|
||||||
case "/panel/groups/edit/submit/":
|
case "/panel/groups/edit/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1620,7 +1648,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(80)
|
counters.RouteViewCounter.Bump(83)
|
||||||
err = panel.GroupsEditSubmit(w,req,user,extraData)
|
err = panel.GroupsEditSubmit(w,req,user,extraData)
|
||||||
case "/panel/groups/edit/perms/submit/":
|
case "/panel/groups/edit/perms/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1628,7 +1656,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(81)
|
counters.RouteViewCounter.Bump(84)
|
||||||
err = panel.GroupsEditPermsSubmit(w,req,user,extraData)
|
err = panel.GroupsEditPermsSubmit(w,req,user,extraData)
|
||||||
case "/panel/groups/create/":
|
case "/panel/groups/create/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1636,7 +1664,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(82)
|
counters.RouteViewCounter.Bump(85)
|
||||||
err = panel.GroupsCreateSubmit(w,req,user)
|
err = panel.GroupsCreateSubmit(w,req,user)
|
||||||
case "/panel/backups/":
|
case "/panel/backups/":
|
||||||
err = c.SuperAdminOnly(w,req,user)
|
err = c.SuperAdminOnly(w,req,user)
|
||||||
|
@ -1650,13 +1678,13 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
w.Header().Del("Content-Type")
|
w.Header().Del("Content-Type")
|
||||||
w.Header().Del("Content-Encoding")
|
w.Header().Del("Content-Encoding")
|
||||||
}
|
}
|
||||||
counters.RouteViewCounter.Bump(83)
|
counters.RouteViewCounter.Bump(86)
|
||||||
err = panel.Backups(w,req,user,extraData)
|
err = panel.Backups(w,req,user,extraData)
|
||||||
case "/panel/logs/regs/":
|
case "/panel/logs/regs/":
|
||||||
counters.RouteViewCounter.Bump(84)
|
counters.RouteViewCounter.Bump(87)
|
||||||
err = panel.LogsRegs(w,req,user)
|
err = panel.LogsRegs(w,req,user)
|
||||||
case "/panel/logs/mod/":
|
case "/panel/logs/mod/":
|
||||||
counters.RouteViewCounter.Bump(85)
|
counters.RouteViewCounter.Bump(88)
|
||||||
err = panel.LogsMod(w,req,user)
|
err = panel.LogsMod(w,req,user)
|
||||||
case "/panel/debug/":
|
case "/panel/debug/":
|
||||||
err = c.AdminOnly(w,req,user)
|
err = c.AdminOnly(w,req,user)
|
||||||
|
@ -1664,10 +1692,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(86)
|
counters.RouteViewCounter.Bump(89)
|
||||||
err = panel.Debug(w,req,user)
|
err = panel.Debug(w,req,user)
|
||||||
default:
|
default:
|
||||||
counters.RouteViewCounter.Bump(87)
|
counters.RouteViewCounter.Bump(90)
|
||||||
err = panel.Dashboard(w,req,user)
|
err = panel.Dashboard(w,req,user)
|
||||||
}
|
}
|
||||||
case "/user":
|
case "/user":
|
||||||
|
@ -1678,7 +1706,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(88)
|
counters.RouteViewCounter.Bump(91)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1690,7 +1718,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(89)
|
counters.RouteViewCounter.Bump(92)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1707,7 +1735,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(90)
|
counters.RouteViewCounter.Bump(93)
|
||||||
err = routes.AccountEditPasswordSubmit(w,req,user)
|
err = routes.AccountEditPasswordSubmit(w,req,user)
|
||||||
case "/user/edit/avatar/submit/":
|
case "/user/edit/avatar/submit/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -1724,7 +1752,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(91)
|
counters.RouteViewCounter.Bump(94)
|
||||||
err = routes.AccountEditAvatarSubmit(w,req,user)
|
err = routes.AccountEditAvatarSubmit(w,req,user)
|
||||||
case "/user/edit/avatar/revoke/submit/":
|
case "/user/edit/avatar/revoke/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1737,7 +1765,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(92)
|
counters.RouteViewCounter.Bump(95)
|
||||||
err = routes.AccountEditRevokeAvatarSubmit(w,req,user)
|
err = routes.AccountEditRevokeAvatarSubmit(w,req,user)
|
||||||
case "/user/edit/username/submit/":
|
case "/user/edit/username/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1750,7 +1778,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(93)
|
counters.RouteViewCounter.Bump(96)
|
||||||
err = routes.AccountEditUsernameSubmit(w,req,user)
|
err = routes.AccountEditUsernameSubmit(w,req,user)
|
||||||
case "/user/edit/mfa/":
|
case "/user/edit/mfa/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -1758,7 +1786,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(94)
|
counters.RouteViewCounter.Bump(97)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1770,7 +1798,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(95)
|
counters.RouteViewCounter.Bump(98)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1787,7 +1815,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(96)
|
counters.RouteViewCounter.Bump(99)
|
||||||
err = routes.AccountEditMFASetupSubmit(w,req,user)
|
err = routes.AccountEditMFASetupSubmit(w,req,user)
|
||||||
case "/user/edit/mfa/disable/submit/":
|
case "/user/edit/mfa/disable/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1800,7 +1828,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(97)
|
counters.RouteViewCounter.Bump(100)
|
||||||
err = routes.AccountEditMFADisableSubmit(w,req,user)
|
err = routes.AccountEditMFADisableSubmit(w,req,user)
|
||||||
case "/user/edit/email/":
|
case "/user/edit/email/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -1808,14 +1836,14 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(98)
|
counters.RouteViewCounter.Bump(101)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = routes.AccountEditEmail(w,req,user,head)
|
err = routes.AccountEditEmail(w,req,user,head)
|
||||||
case "/user/edit/token/":
|
case "/user/edit/token/":
|
||||||
counters.RouteViewCounter.Bump(99)
|
counters.RouteViewCounter.Bump(102)
|
||||||
err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData)
|
err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData)
|
||||||
case "/user/edit/logins/":
|
case "/user/edit/logins/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -1823,7 +1851,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(100)
|
counters.RouteViewCounter.Bump(103)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1835,7 +1863,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(101)
|
counters.RouteViewCounter.Bump(104)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1847,7 +1875,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(102)
|
counters.RouteViewCounter.Bump(105)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1859,7 +1887,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(103)
|
counters.RouteViewCounter.Bump(106)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1871,7 +1899,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(104)
|
counters.RouteViewCounter.Bump(107)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1888,7 +1916,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(105)
|
counters.RouteViewCounter.Bump(108)
|
||||||
err = routes.ConvosCreateSubmit(w,req,user)
|
err = routes.ConvosCreateSubmit(w,req,user)
|
||||||
case "/user/convo/create/submit/":
|
case "/user/convo/create/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1901,7 +1929,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(106)
|
counters.RouteViewCounter.Bump(109)
|
||||||
err = routes.ConvosCreateReplySubmit(w,req,user,extraData)
|
err = routes.ConvosCreateReplySubmit(w,req,user,extraData)
|
||||||
case "/user/convo/delete/submit/":
|
case "/user/convo/delete/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1914,7 +1942,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(107)
|
counters.RouteViewCounter.Bump(110)
|
||||||
err = routes.ConvosDeleteReplySubmit(w,req,user,extraData)
|
err = routes.ConvosDeleteReplySubmit(w,req,user,extraData)
|
||||||
case "/user/convo/edit/submit/":
|
case "/user/convo/edit/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1927,11 +1955,11 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(108)
|
counters.RouteViewCounter.Bump(111)
|
||||||
err = routes.ConvosEditReplySubmit(w,req,user,extraData)
|
err = routes.ConvosEditReplySubmit(w,req,user,extraData)
|
||||||
default:
|
default:
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
counters.RouteViewCounter.Bump(109)
|
counters.RouteViewCounter.Bump(112)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1951,7 +1979,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(110)
|
counters.RouteViewCounter.Bump(113)
|
||||||
err = routes.BanUserSubmit(w,req,user,extraData)
|
err = routes.BanUserSubmit(w,req,user,extraData)
|
||||||
case "/users/unban/":
|
case "/users/unban/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1964,7 +1992,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(111)
|
counters.RouteViewCounter.Bump(114)
|
||||||
err = routes.UnbanUser(w,req,user,extraData)
|
err = routes.UnbanUser(w,req,user,extraData)
|
||||||
case "/users/activate/":
|
case "/users/activate/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1977,7 +2005,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(112)
|
counters.RouteViewCounter.Bump(115)
|
||||||
err = routes.ActivateUser(w,req,user,extraData)
|
err = routes.ActivateUser(w,req,user,extraData)
|
||||||
case "/users/ips/":
|
case "/users/ips/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -1985,7 +2013,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(113)
|
counters.RouteViewCounter.Bump(116)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2009,7 +2037,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(114)
|
counters.RouteViewCounter.Bump(117)
|
||||||
err = routes.CreateTopicSubmit(w,req,user)
|
err = routes.CreateTopicSubmit(w,req,user)
|
||||||
case "/topic/edit/submit/":
|
case "/topic/edit/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2022,7 +2050,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(115)
|
counters.RouteViewCounter.Bump(118)
|
||||||
err = routes.EditTopicSubmit(w,req,user,extraData)
|
err = routes.EditTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/delete/submit/":
|
case "/topic/delete/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2036,7 +2064,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
}
|
}
|
||||||
|
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
counters.RouteViewCounter.Bump(116)
|
counters.RouteViewCounter.Bump(119)
|
||||||
err = routes.DeleteTopicSubmit(w,req,user)
|
err = routes.DeleteTopicSubmit(w,req,user)
|
||||||
case "/topic/stick/submit/":
|
case "/topic/stick/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2049,7 +2077,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(117)
|
counters.RouteViewCounter.Bump(120)
|
||||||
err = routes.StickTopicSubmit(w,req,user,extraData)
|
err = routes.StickTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/unstick/submit/":
|
case "/topic/unstick/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2062,7 +2090,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(118)
|
counters.RouteViewCounter.Bump(121)
|
||||||
err = routes.UnstickTopicSubmit(w,req,user,extraData)
|
err = routes.UnstickTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/lock/submit/":
|
case "/topic/lock/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2076,7 +2104,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
}
|
}
|
||||||
|
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
counters.RouteViewCounter.Bump(119)
|
counters.RouteViewCounter.Bump(122)
|
||||||
err = routes.LockTopicSubmit(w,req,user)
|
err = routes.LockTopicSubmit(w,req,user)
|
||||||
case "/topic/unlock/submit/":
|
case "/topic/unlock/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2089,7 +2117,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(120)
|
counters.RouteViewCounter.Bump(123)
|
||||||
err = routes.UnlockTopicSubmit(w,req,user,extraData)
|
err = routes.UnlockTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/move/submit/":
|
case "/topic/move/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2102,7 +2130,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(121)
|
counters.RouteViewCounter.Bump(124)
|
||||||
err = routes.MoveTopicSubmit(w,req,user,extraData)
|
err = routes.MoveTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/like/submit/":
|
case "/topic/like/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2115,7 +2143,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(122)
|
counters.RouteViewCounter.Bump(125)
|
||||||
err = routes.LikeTopicSubmit(w,req,user,extraData)
|
err = routes.LikeTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/attach/add/submit/":
|
case "/topic/attach/add/submit/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -2132,7 +2160,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(123)
|
counters.RouteViewCounter.Bump(126)
|
||||||
err = routes.AddAttachToTopicSubmit(w,req,user,extraData)
|
err = routes.AddAttachToTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/attach/remove/submit/":
|
case "/topic/attach/remove/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2145,10 +2173,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(124)
|
counters.RouteViewCounter.Bump(127)
|
||||||
err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData)
|
err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData)
|
||||||
default:
|
default:
|
||||||
counters.RouteViewCounter.Bump(125)
|
counters.RouteViewCounter.Bump(128)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2172,7 +2200,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(126)
|
counters.RouteViewCounter.Bump(129)
|
||||||
err = routes.CreateReplySubmit(w,req,user)
|
err = routes.CreateReplySubmit(w,req,user)
|
||||||
case "/reply/edit/submit/":
|
case "/reply/edit/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2185,7 +2213,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(127)
|
counters.RouteViewCounter.Bump(130)
|
||||||
err = routes.ReplyEditSubmit(w,req,user,extraData)
|
err = routes.ReplyEditSubmit(w,req,user,extraData)
|
||||||
case "/reply/delete/submit/":
|
case "/reply/delete/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2198,7 +2226,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(128)
|
counters.RouteViewCounter.Bump(131)
|
||||||
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
|
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
|
||||||
case "/reply/like/submit/":
|
case "/reply/like/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2211,7 +2239,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(129)
|
counters.RouteViewCounter.Bump(132)
|
||||||
err = routes.ReplyLikeSubmit(w,req,user,extraData)
|
err = routes.ReplyLikeSubmit(w,req,user,extraData)
|
||||||
case "/reply/attach/add/submit/":
|
case "/reply/attach/add/submit/":
|
||||||
err = c.MemberOnly(w,req,user)
|
err = c.MemberOnly(w,req,user)
|
||||||
|
@ -2228,7 +2256,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(130)
|
counters.RouteViewCounter.Bump(133)
|
||||||
err = routes.AddAttachToReplySubmit(w,req,user,extraData)
|
err = routes.AddAttachToReplySubmit(w,req,user,extraData)
|
||||||
case "/reply/attach/remove/submit/":
|
case "/reply/attach/remove/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2241,7 +2269,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(131)
|
counters.RouteViewCounter.Bump(134)
|
||||||
err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData)
|
err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
case "/profile":
|
case "/profile":
|
||||||
|
@ -2257,7 +2285,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(132)
|
counters.RouteViewCounter.Bump(135)
|
||||||
err = routes.ProfileReplyCreateSubmit(w,req,user)
|
err = routes.ProfileReplyCreateSubmit(w,req,user)
|
||||||
case "/profile/reply/edit/submit/":
|
case "/profile/reply/edit/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2270,7 +2298,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(133)
|
counters.RouteViewCounter.Bump(136)
|
||||||
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
|
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
|
||||||
case "/profile/reply/delete/submit/":
|
case "/profile/reply/delete/submit/":
|
||||||
err = c.NoSessionMismatch(w,req,user)
|
err = c.NoSessionMismatch(w,req,user)
|
||||||
|
@ -2283,7 +2311,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(134)
|
counters.RouteViewCounter.Bump(137)
|
||||||
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
|
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
case "/poll":
|
case "/poll":
|
||||||
|
@ -2299,23 +2327,23 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(135)
|
counters.RouteViewCounter.Bump(138)
|
||||||
err = routes.PollVote(w,req,user,extraData)
|
err = routes.PollVote(w,req,user,extraData)
|
||||||
case "/poll/results/":
|
case "/poll/results/":
|
||||||
counters.RouteViewCounter.Bump(136)
|
counters.RouteViewCounter.Bump(139)
|
||||||
err = routes.PollResults(w,req,user,extraData)
|
err = routes.PollResults(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
case "/accounts":
|
case "/accounts":
|
||||||
switch(req.URL.Path) {
|
switch(req.URL.Path) {
|
||||||
case "/accounts/login/":
|
case "/accounts/login/":
|
||||||
counters.RouteViewCounter.Bump(137)
|
counters.RouteViewCounter.Bump(140)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = routes.AccountLogin(w,req,user,head)
|
err = routes.AccountLogin(w,req,user,head)
|
||||||
case "/accounts/create/":
|
case "/accounts/create/":
|
||||||
counters.RouteViewCounter.Bump(138)
|
counters.RouteViewCounter.Bump(141)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2332,7 +2360,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(139)
|
counters.RouteViewCounter.Bump(142)
|
||||||
err = routes.AccountLogout(w,req,user)
|
err = routes.AccountLogout(w,req,user)
|
||||||
case "/accounts/login/submit/":
|
case "/accounts/login/submit/":
|
||||||
err = c.ParseForm(w,req,user)
|
err = c.ParseForm(w,req,user)
|
||||||
|
@ -2340,10 +2368,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(140)
|
counters.RouteViewCounter.Bump(143)
|
||||||
err = routes.AccountLoginSubmit(w,req,user)
|
err = routes.AccountLoginSubmit(w,req,user)
|
||||||
case "/accounts/mfa_verify/":
|
case "/accounts/mfa_verify/":
|
||||||
counters.RouteViewCounter.Bump(141)
|
counters.RouteViewCounter.Bump(144)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2355,7 +2383,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(142)
|
counters.RouteViewCounter.Bump(145)
|
||||||
err = routes.AccountLoginMFAVerifySubmit(w,req,user)
|
err = routes.AccountLoginMFAVerifySubmit(w,req,user)
|
||||||
case "/accounts/create/submit/":
|
case "/accounts/create/submit/":
|
||||||
err = c.ParseForm(w,req,user)
|
err = c.ParseForm(w,req,user)
|
||||||
|
@ -2363,10 +2391,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(143)
|
counters.RouteViewCounter.Bump(146)
|
||||||
err = routes.AccountRegisterSubmit(w,req,user)
|
err = routes.AccountRegisterSubmit(w,req,user)
|
||||||
case "/accounts/password-reset/":
|
case "/accounts/password-reset/":
|
||||||
counters.RouteViewCounter.Bump(144)
|
counters.RouteViewCounter.Bump(147)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2378,10 +2406,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(145)
|
counters.RouteViewCounter.Bump(148)
|
||||||
err = routes.AccountPasswordResetSubmit(w,req,user)
|
err = routes.AccountPasswordResetSubmit(w,req,user)
|
||||||
case "/accounts/password-reset/token/":
|
case "/accounts/password-reset/token/":
|
||||||
counters.RouteViewCounter.Bump(146)
|
counters.RouteViewCounter.Bump(149)
|
||||||
head, err := c.UserCheck(w,req,&user)
|
head, err := c.UserCheck(w,req,&user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2393,7 +2421,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(147)
|
counters.RouteViewCounter.Bump(150)
|
||||||
err = routes.AccountPasswordResetTokenSubmit(w,req,user)
|
err = routes.AccountPasswordResetTokenSubmit(w,req,user)
|
||||||
}
|
}
|
||||||
/*case "/sitemaps": // TODO: Count these views
|
/*case "/sitemaps": // TODO: Count these views
|
||||||
|
@ -2410,7 +2438,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
h.Del("Content-Type")
|
h.Del("Content-Type")
|
||||||
h.Del("Content-Encoding")
|
h.Del("Content-Encoding")
|
||||||
}
|
}
|
||||||
counters.RouteViewCounter.Bump(149)
|
counters.RouteViewCounter.Bump(152)
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
// TODO: Find a way to propagate errors up from this?
|
// TODO: Find a way to propagate errors up from this?
|
||||||
r.UploadHandler(w,req) // TODO: Count these views
|
r.UploadHandler(w,req) // TODO: Count these views
|
||||||
|
@ -2420,7 +2448,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
// TODO: Add support for favicons and robots.txt files
|
// TODO: Add support for favicons and robots.txt files
|
||||||
switch(extraData) {
|
switch(extraData) {
|
||||||
case "robots.txt":
|
case "robots.txt":
|
||||||
counters.RouteViewCounter.Bump(151)
|
counters.RouteViewCounter.Bump(154)
|
||||||
return routes.RobotsTxt(w,req)
|
return routes.RobotsTxt(w,req)
|
||||||
case "favicon.ico":
|
case "favicon.ico":
|
||||||
gzw, ok := w.(c.GzipResponseWriter)
|
gzw, ok := w.(c.GzipResponseWriter)
|
||||||
|
@ -2434,10 +2462,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
routes.StaticFile(w,req)
|
routes.StaticFile(w,req)
|
||||||
return nil
|
return nil
|
||||||
case "opensearch.xml":
|
case "opensearch.xml":
|
||||||
counters.RouteViewCounter.Bump(153)
|
counters.RouteViewCounter.Bump(156)
|
||||||
return routes.OpenSearchXml(w,req)
|
return routes.OpenSearchXml(w,req)
|
||||||
/*case "sitemap.xml":
|
/*case "sitemap.xml":
|
||||||
counters.RouteViewCounter.Bump(152)
|
counters.RouteViewCounter.Bump(155)
|
||||||
return routes.SitemapXml(w,req)*/
|
return routes.SitemapXml(w,req)*/
|
||||||
}
|
}
|
||||||
return c.NotFound(w,req,nil)
|
return c.NotFound(w,req,nil)
|
||||||
|
@ -2448,7 +2476,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
r.RUnlock()
|
r.RUnlock()
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
counters.RouteViewCounter.Bump(148) // TODO: Be more specific about *which* dynamic route it is
|
counters.RouteViewCounter.Bump(151) // TODO: Be more specific about *which* dynamic route it is
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
return handle(w,req,user)
|
return handle(w,req,user)
|
||||||
}
|
}
|
||||||
|
@ -2459,7 +2487,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
|
||||||
} else {
|
} else {
|
||||||
r.DumpRequest(req,"Bad Route")
|
r.DumpRequest(req,"Bad Route")
|
||||||
}
|
}
|
||||||
counters.RouteViewCounter.Bump(154)
|
counters.RouteViewCounter.Bump(157)
|
||||||
return c.NotFound(w,req,nil)
|
return c.NotFound(w,req,nil)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -2,24 +2,27 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
var dbTablePrimaryKeys = map[string]string{
|
var dbTablePrimaryKeys = map[string]string{
|
||||||
"users_groups":"gid",
|
"polls":"pollID",
|
||||||
"users_avatar_queue":"uid",
|
"widgets":"wid",
|
||||||
|
"users_groups_promotions":"pid",
|
||||||
|
"topics":"tid",
|
||||||
|
"attachments":"attachID",
|
||||||
"word_filters":"wfid",
|
"word_filters":"wfid",
|
||||||
|
"menu_items":"miid",
|
||||||
|
"users_groups":"gid",
|
||||||
|
"users_2fa_keys":"uid",
|
||||||
|
"activity_stream":"asid",
|
||||||
|
"conversations_posts":"pid",
|
||||||
"menus":"mid",
|
"menus":"mid",
|
||||||
"login_logs":"lid",
|
"login_logs":"lid",
|
||||||
"polls":"pollID",
|
|
||||||
"activity_stream":"asid",
|
|
||||||
"pages":"pid",
|
|
||||||
"forums":"fid",
|
"forums":"fid",
|
||||||
"topics":"tid",
|
"users_replies":"rid",
|
||||||
|
"conversations":"cid",
|
||||||
"replies":"rid",
|
"replies":"rid",
|
||||||
"attachments":"attachID",
|
|
||||||
"revisions":"reviseID",
|
"revisions":"reviseID",
|
||||||
"users_2fa_keys":"uid",
|
"pages":"pid",
|
||||||
"users_groups_scheduler":"uid",
|
|
||||||
"menu_items":"miid",
|
|
||||||
"registration_logs":"rlid",
|
"registration_logs":"rlid",
|
||||||
"users":"uid",
|
"users":"uid",
|
||||||
"users_replies":"rid",
|
"users_groups_scheduler":"uid",
|
||||||
"widgets":"wid",
|
"users_avatar_queue":"uid",
|
||||||
}
|
}
|
||||||
|
|
4
main.go
4
main.go
|
@ -138,6 +138,10 @@ func storeInit() (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.WithStack(err)
|
return errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
c.GroupPromotions, err = c.NewDefaultGroupPromotionStore(acc)
|
||||||
|
if err != nil {
|
||||||
|
return errors.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
err = phrases.InitPhrases(c.Site.Language)
|
err = phrases.InitPhrases(c.Site.Language)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -37,6 +37,7 @@ func init() {
|
||||||
addPatch(21, patch21)
|
addPatch(21, patch21)
|
||||||
addPatch(22, patch22)
|
addPatch(22, patch22)
|
||||||
addPatch(23, patch23)
|
addPatch(23, patch23)
|
||||||
|
addPatch(24, patch24)
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch0(scanner *bufio.Scanner) (err error) {
|
func patch0(scanner *bufio.Scanner) (err error) {
|
||||||
|
@ -712,3 +713,25 @@ func patch23(scanner *bufio.Scanner) error {
|
||||||
}, nil,
|
}, nil,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func patch24(scanner *bufio.Scanner) error {
|
||||||
|
err := execStmt(qgen.Builder.DropTable("users_groups_promotions"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return execStmt(qgen.Builder.CreateTable("users_groups_promotions", "", "",
|
||||||
|
[]tC{
|
||||||
|
tC{"pid", "int", 0, false, true, ""},
|
||||||
|
tC{"from_gid", "int", 0, false, false, ""},
|
||||||
|
tC{"to_gid", "int", 0, false, false, ""},
|
||||||
|
tC{"two_way", "boolean",0,false,false,"0"}, // If a user no longer meets the requirements for this promotion then they will be demoted if this flag is set
|
||||||
|
|
||||||
|
// Requirements
|
||||||
|
tC{"level", "int", 0, false, false, ""},
|
||||||
|
tC{"minTime", "int", 0, false, false, ""}, // How long someone needs to have been in their current group before being promoted
|
||||||
|
},
|
||||||
|
[]tblKey{
|
||||||
|
tblKey{"pid", "primary","",false},
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
|
@ -248,6 +248,9 @@ func panelRoutes() *RouteGroup {
|
||||||
|
|
||||||
View("panel.Groups", "/panel/groups/"),
|
View("panel.Groups", "/panel/groups/"),
|
||||||
View("panel.GroupsEdit", "/panel/groups/edit/", "extraData"),
|
View("panel.GroupsEdit", "/panel/groups/edit/", "extraData"),
|
||||||
|
View("panel.GroupsEditPromotions", "/panel/groups/edit/promotions/", "extraData"),
|
||||||
|
Action("panel.GroupsPromotionsCreateSubmit", "/panel/groups/promotions/create/submit/","extraData"),
|
||||||
|
Action("panel.GroupsPromotionsDeleteSubmit", "/panel/groups/promotions/delete/submit/","extraData"),
|
||||||
View("panel.GroupsEditPerms", "/panel/groups/edit/perms/", "extraData"),
|
View("panel.GroupsEditPerms", "/panel/groups/edit/perms/", "extraData"),
|
||||||
Action("panel.GroupsEditSubmit", "/panel/groups/edit/submit/", "extraData"),
|
Action("panel.GroupsEditSubmit", "/panel/groups/edit/submit/", "extraData"),
|
||||||
Action("panel.GroupsEditPermsSubmit", "/panel/groups/edit/perms/submit/", "extraData"),
|
Action("panel.GroupsEditPermsSubmit", "/panel/groups/edit/perms/submit/", "extraData"),
|
||||||
|
|
|
@ -263,7 +263,7 @@ func ConvosEditReplySubmit(w http.ResponseWriter, r *http.Request, user c.User,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
|
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
|
||||||
}
|
}
|
||||||
isJs := (r.PostFormValue("js") == "1")
|
js := (r.PostFormValue("js") == "1")
|
||||||
|
|
||||||
post := &c.ConversationPost{ID: cpid}
|
post := &c.ConversationPost{ID: cpid}
|
||||||
err = post.Fetch()
|
err = post.Fetch()
|
||||||
|
@ -296,7 +296,7 @@ func ConvosEditReplySubmit(w http.ResponseWriter, r *http.Request, user c.User,
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isJs {
|
if !js {
|
||||||
http.Redirect(w, r, "/user/convo/"+strconv.Itoa(post.CID), http.StatusSeeOther)
|
http.Redirect(w, r, "/user/convo/"+strconv.Itoa(post.CID), http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
w.Write(successJSONBytes)
|
w.Write(successJSONBytes)
|
||||||
|
|
|
@ -29,8 +29,7 @@ type dashStmts struct {
|
||||||
// TODO: Stop hard-coding these queries
|
// TODO: Stop hard-coding these queries
|
||||||
func dashMySQLStmts() (stmts dashStmts, err error) {
|
func dashMySQLStmts() (stmts dashStmts, err error) {
|
||||||
db := qgen.Builder.GetConn()
|
db := qgen.Builder.GetConn()
|
||||||
|
prepareStmt := func(table string, ext string, dur string) *sql.Stmt {
|
||||||
var prepareStmt = func(table string, ext string, dur string) *sql.Stmt {
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -51,8 +50,7 @@ func dashMySQLStmts() (stmts dashStmts, err error) {
|
||||||
// TODO: Stop hard-coding these queries
|
// TODO: Stop hard-coding these queries
|
||||||
func dashMSSQLStmts() (stmts dashStmts, err error) {
|
func dashMSSQLStmts() (stmts dashStmts, err error) {
|
||||||
db := qgen.Builder.GetConn()
|
db := qgen.Builder.GetConn()
|
||||||
|
prepareStmt := func(table string, ext string, dur string) *sql.Stmt {
|
||||||
var prepareStmt = func(table string, ext string, dur string) *sql.Stmt {
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -134,7 +132,7 @@ func Dashboard(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
|
||||||
|
|
||||||
// TODO: Add a stat store for this?
|
// TODO: Add a stat store for this?
|
||||||
var intErr error
|
var intErr error
|
||||||
var extractStat = func(stmt *sql.Stmt, args ...interface{}) (stat int) {
|
extractStat := func(stmt *sql.Stmt, args ...interface{}) (stat int) {
|
||||||
err := stmt.QueryRow(args...).Scan(&stat)
|
err := stmt.QueryRow(args...).Scan(&stat)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
intErr = err
|
intErr = err
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
CREATE TABLE [users_groups_promotions] (
|
||||||
|
[pid] int not null IDENTITY,
|
||||||
|
[from_gid] int not null,
|
||||||
|
[to_gid] int not null,
|
||||||
|
[two_way] bit DEFAULT 0 not null,
|
||||||
|
[level] int not null,
|
||||||
|
[minTime] int not null,
|
||||||
|
primary key([pid])
|
||||||
|
);
|
|
@ -0,0 +1,9 @@
|
||||||
|
CREATE TABLE `users_groups_promotions` (
|
||||||
|
`pid` int not null AUTO_INCREMENT,
|
||||||
|
`from_gid` int not null,
|
||||||
|
`to_gid` int not null,
|
||||||
|
`two_way` boolean DEFAULT 0 not null,
|
||||||
|
`level` int not null,
|
||||||
|
`minTime` int not null,
|
||||||
|
primary key(`pid`)
|
||||||
|
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
|
|
@ -0,0 +1,9 @@
|
||||||
|
CREATE TABLE "users_groups_promotions" (
|
||||||
|
`pid` serial not null,
|
||||||
|
`from_gid` int not null,
|
||||||
|
`to_gid` int not null,
|
||||||
|
`two_way` boolean DEFAULT 0 not null,
|
||||||
|
`level` int not null,
|
||||||
|
`minTime` int not null,
|
||||||
|
primary key(`pid`)
|
||||||
|
);
|
|
@ -30,7 +30,7 @@
|
||||||
<a href="/user/convo/{{.ID}}">{{range .Users}}<span class="convos_item_user">{{.Name}}</span> {{end}}</a></span></a>
|
<a href="/user/convo/{{.ID}}">{{range .Users}}<span class="convos_item_user">{{.Name}}</span> {{end}}</a></span></a>
|
||||||
</span>
|
</span>
|
||||||
<span title="{{abstime .LastReplyAt}}" class="to_right">{{reltime .LastReplyAt}}</span>
|
<span title="{{abstime .LastReplyAt}}" class="to_right">{{reltime .LastReplyAt}}</span>
|
||||||
</div>{{end}}
|
|
||||||
<div style="clear:both;"></div>
|
<div style="clear:both;"></div>
|
||||||
|
</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{template "paginator.html" . }}
|
{{template "paginator.html" . }}
|
|
@ -0,0 +1,69 @@
|
||||||
|
{{template "header.html" . }}
|
||||||
|
<div class="colstack panel_stack">
|
||||||
|
{{template "panel_group_menu.html" . }}
|
||||||
|
<main class="colstack_right">
|
||||||
|
{{template "panel_before_head.html" . }}
|
||||||
|
<div class="colstack_item colstack_head">
|
||||||
|
<div class="rowitem"><h1>{{.Name}}{{lang "panel_group_head_suffix"}}</h1></div>
|
||||||
|
</div>
|
||||||
|
<form action="/panel/groups/edit/promotions/submit/{{.ID}}?s={{.CurrentUser.Session}}" method="post">
|
||||||
|
<div class="colstack_item panel_group_promotions">
|
||||||
|
{{range .Promotions}}
|
||||||
|
<div class="rowitem">
|
||||||
|
<a href="#p-{{.ID}}">{{.FromGroup.Name}} -> {{.ToGroup.Name}}{{if .TwoWay}} (two way){{end}}</a>
|
||||||
|
<span> - level {{.Level}}</span>
|
||||||
|
<div class="to_right">
|
||||||
|
<a href="/panel/groups/promotions/delete/submit/{{$.ID}}-{{.ID}}?s={{$.CurrentUser.Session}}"><button form="nn">Delete</button></a>
|
||||||
|
</div>
|
||||||
|
</div>{{end}}
|
||||||
|
<div class="rowitem">
|
||||||
|
<button name="panel-button" class="formbutton form_middle_button">{{lang "panel_group_update_button"}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{{if .CurrentUser.Perms.EditGroup}}
|
||||||
|
<div class="colstack_item colstack_head">
|
||||||
|
<div class="rowitem"><h1>Add Promotion</h1></div>
|
||||||
|
</div>
|
||||||
|
<div class="colstack_item the_form">
|
||||||
|
<form action="/panel/groups/promotions/create/submit/{{.ID}}?s={{.CurrentUser.Session}}" method="post">
|
||||||
|
<div class="formrow">
|
||||||
|
<div class="formitem formlabel"><a>From</a></div>
|
||||||
|
<div class="formitem">
|
||||||
|
<select name="from">
|
||||||
|
{{range .Groups}}<option value="{{.ID}}">{{.Name}}</option>{{end}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="formrow">
|
||||||
|
<div class="formitem formlabel"><a>To</a></div>
|
||||||
|
<div class="formitem">
|
||||||
|
<select name="to">
|
||||||
|
{{range .Groups}}<option value="{{.ID}}">{{.Name}}</option>{{end}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="formrow">
|
||||||
|
<div class="formitem formlabel"><a>Two Way</a></div>
|
||||||
|
<div class="formitem">
|
||||||
|
<select name="two-way" disabled>
|
||||||
|
<option value=1>{{lang "option_yes"}}</option>
|
||||||
|
<option selected value=0>{{lang "option_no"}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="formrow">
|
||||||
|
<div class="formitem formlabel"><a>Level</a></div>
|
||||||
|
<div class="formitem"><input name="level" type="number" value=0 /></div>
|
||||||
|
</div>
|
||||||
|
<div class="formrow form_button_row">
|
||||||
|
<div class="formitem"><button name="panel-button" class="formbutton">{{lang "panel_groups_create_create_group_button"}}</button></div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
{{template "footer.html" . }}
|
|
@ -4,7 +4,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="colstack_item rowmenu">
|
<div class="colstack_item rowmenu">
|
||||||
<div class="rowitem passive"><a href="/panel/groups/edit/{{.ID}}">{{lang "panel_group_menu_general"}}</a></div>
|
<div class="rowitem passive"><a href="/panel/groups/edit/{{.ID}}">{{lang "panel_group_menu_general"}}</a></div>
|
||||||
<div class="rowitem passive"><a>{{lang "panel_group_menu_promotions"}}</a></div>
|
<div class="rowitem passive"><a href="/panel/groups/edit/promotions/{{.ID}}">{{lang "panel_group_menu_promotions"}}</a></div>
|
||||||
<div class="rowitem passive"><a href="/panel/groups/edit/perms/{{.ID}}">{{lang "panel_group_menu_permissions"}}</a></div>
|
<div class="rowitem passive"><a href="/panel/groups/edit/perms/{{.ID}}">{{lang "panel_group_menu_permissions"}}</a></div>
|
||||||
</div>
|
</div>
|
||||||
{{template "panel_inner_menu.html" . }}
|
{{template "panel_inner_menu.html" . }}
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<article {{scope "opening_post"}} itemscope itemtype="http://schema.org/CreativeWork" class="rowblock post_container top_post" aria-label="{{lang "topic.opening_post_aria"}}">
|
<article {{scope "opening_post"}} itemscope itemtype="http://schema.org/CreativeWork" class="rowblock post_container top_post" aria-label="{{lang "topic.opening_post_aria"}}">
|
||||||
<div class="rowitem passive editable_parent post_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}), url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;">
|
<div class="rowitem passive editable_parent post_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}), url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat,repeat-y;">
|
||||||
<div class="hide_on_edit topic_content user_content" itemprop="text">{{.Topic.ContentHTML}}</div>
|
<div class="hide_on_edit topic_content user_content" itemprop="text">{{.Topic.ContentHTML}}</div>
|
||||||
{{if .CurrentUser.Loggedin}}<textarea name="topic_content" class="show_on_edit topic_content_input edit_source">{{.Topic.Content}}</textarea>{{end}}
|
{{if .CurrentUser.Loggedin}}<textarea name="topic_content" class="show_on_edit topic_content_input edit_source">{{.Topic.Content}}</textarea>{{end}}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
{{if .CurrentUser.Loggedin}}
|
{{if .CurrentUser.Loggedin}}
|
||||||
{{if .CurrentUser.Perms.LikeItem}}<a href="/topic/like/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="mod_button" {{if .Topic.Liked}}title="{{lang "topic.unlike_tooltip"}}" aria-label="{{lang "topic.unlike_aria"}}"{{else}}title="{{lang "topic.like_tooltip"}}" aria-label="{{lang "topic.like_aria"}}"{{end}}>
|
{{if .CurrentUser.Perms.LikeItem}}<a href="/topic/like/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="mod_button" {{if .Topic.Liked}}title="{{lang "topic.unlike_tooltip"}}" aria-label="{{lang "topic.unlike_aria"}}"{{else}}title="{{lang "topic.like_tooltip"}}" aria-label="{{lang "topic.like_aria"}}"{{end}}>
|
||||||
<button class="username like_label {{if .Topic.Liked}}remove_like{{else}}add_like{{end}}"></button></a>{{end}}
|
<button class="username like_label {{if .Topic.Liked}}remove{{else}}add{{end}}_like"></button></a>{{end}}
|
||||||
|
|
||||||
<a href="" class="mod_button quote_item" title="{{lang "topic.quote_tooltip"}}" aria-label="{{lang "topic.quote_aria"}}"><button class="username quote_label"></button></a>
|
<a href="" class="mod_button quote_item" title="{{lang "topic.quote_tooltip"}}" aria-label="{{lang "topic.quote_aria"}}"><button class="username quote_label"></button></a>
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<div class="rowblock post_container" aria-label="{{lang "topic.current_page_aria"}}" style="overflow: hidden;">{{range .ItemList}}
|
<div class="rowblock post_container" aria-label="{{lang "topic.current_page_aria"}}" style="overflow:hidden;">{{range .ItemList}}
|
||||||
{{if .ActionType}}
|
{{if .ActionType}}
|
||||||
<article {{scope "post_action"}} id="post-{{.ID}}" itemscope itemtype="http://schema.org/CreativeWork" class="rowitem passive deletable_block editable_parent post_item action_item">
|
<article {{scope "post_action"}} id="post-{{.ID}}" itemscope itemtype="http://schema.org/CreativeWork" class="rowitem passive deletable_block editable_parent post_item action_item">
|
||||||
<span class="action_icon">{{.ActionIcon}}</span>
|
<span class="action_icon">{{.ActionIcon}}</span>
|
||||||
<span itemprop="text">{{.ActionType}}</span>
|
<span itemprop="text">{{.ActionType}}</span>
|
||||||
</article>
|
</article>
|
||||||
{{else}}
|
{{else}}
|
||||||
<article {{scope "post"}} id="post-{{.ID}}" itemscope itemtype="http://schema.org/CreativeWork" class="rowitem passive deletable_block editable_parent post_item {{.ClassName}}" style="background-image:url({{.Avatar}}), url(/s/{{$.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;">
|
<article {{scope "post"}} id="post-{{.ID}}" itemscope itemtype="http://schema.org/CreativeWork" class="rowitem passive deletable_block editable_parent post_item {{.ClassName}}" style="background-image:url({{.Avatar}}),url(/s/{{$.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;">
|
||||||
{{/** TODO: We might end up with <br>s in the inline editor, fix this **/}}
|
{{/** TODO: We might end up with <br>s in the inline editor, fix this **/}}
|
||||||
<div class="editable_block user_content" itemprop="text">{{.ContentHtml}}</div>
|
<div class="editable_block user_content" itemprop="text">{{.ContentHtml}}</div>
|
||||||
{{if $.CurrentUser.Loggedin}}<div class="auto_hide edit_source">{{.Content}}</div>{{end}}
|
{{if $.CurrentUser.Loggedin}}<div class="auto_hide edit_source">{{.Content}}</div>{{end}}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<input form="quick_post_form" id="has_poll_input" name="has_poll" value="0" type="hidden" />
|
<input form="quick_post_form" id="has_poll_input" name="has_poll" value=0 type="hidden" />
|
||||||
<div class="formrow topic_content_row">
|
<div class="formrow topic_content_row">
|
||||||
<div class="formitem">
|
<div class="formitem">
|
||||||
<textarea form="quick_post_form" id="input_content" name="topic-content" placeholder="{{lang "quick_topic.content_placeholder"}}" required></textarea>
|
<textarea form="quick_post_form" id="input_content" name="topic-content" placeholder="{{lang "quick_topic.content_placeholder"}}" required></textarea>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="colstack_item rowmenu">
|
<div class="colstack_item rowmenu">
|
||||||
<div class="rowitem passive"><a href="/panel/groups/edit/{{.ID}}">{{lang "panel_group_menu_general"}}</a></div>
|
<div class="rowitem passive"><a href="/panel/groups/edit/{{.ID}}">{{lang "panel_group_menu_general"}}</a></div>
|
||||||
<div class="rowitem passive"><a>{{lang "panel_group_menu_promotions"}}</a></div>
|
<div class="rowitem passive"><a href="/panel/groups/edit/promotions/{{.ID}}">{{lang "panel_group_menu_promotions"}}</a></div>
|
||||||
<div class="rowitem passive"><a href="/panel/groups/edit/perms/{{.ID}}">{{lang "panel_group_menu_permissions"}}</a></div>
|
<div class="rowitem passive"><a href="/panel/groups/edit/perms/{{.ID}}">{{lang "panel_group_menu_permissions"}}</a></div>
|
||||||
</div>
|
</div>
|
||||||
{{template "panel_inner_menu.html" . }}
|
{{template "panel_inner_menu.html" . }}
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
background-color: rgb(72, 72, 72);
|
background-color: rgb(72, 72, 72);
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
padding-right: 20px;
|
padding-right: 22px;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
}
|
}
|
||||||
.above_right img {
|
.above_right img {
|
||||||
|
@ -275,6 +275,9 @@ select + .timeRangeSelector {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
.panel_group_promotions .formitem {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
.perm_preset_no_access:before {
|
.perm_preset_no_access:before {
|
||||||
content: "{{lang "panel_perms_no_access" . }}";
|
content: "{{lang "panel_perms_no_access" . }}";
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
.convos_item_user:not(:last-child):after {
|
.convos_item_user:not(:last-child):after {
|
||||||
content: ",";
|
content: ",";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.parti {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
.parti .rowitem {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.parti_user:not(:last-child):after {
|
||||||
|
content: ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
.convo_row_box .rowitem {
|
||||||
|
background-repeat: no-repeat, repeat-y;
|
||||||
|
background-size: 128px;
|
||||||
|
padding-left: 136px;
|
||||||
|
}
|
|
@ -1,3 +1,22 @@
|
||||||
.convos_item_user:not(:last-child):after {
|
.convos_item_user:not(:last-child):after {
|
||||||
content: ",";
|
content: ",";
|
||||||
}
|
}
|
||||||
|
.to_left:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*.parti {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}*/
|
||||||
|
.parti .rowitem {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.parti_user:not(:last-child):after {
|
||||||
|
content: ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
.convo_row_box .rowitem {
|
||||||
|
background-repeat: no-repeat, repeat-y;
|
||||||
|
background-size: 128px;
|
||||||
|
padding-left: 136px;
|
||||||
|
}
|
Loading…
Reference in New Issue