code cleanup

This commit is contained in:
Azareal 2020-02-05 12:48:35 +10:00
parent 07afdd9f71
commit f858797835
15 changed files with 138 additions and 139 deletions

View File

@ -7,10 +7,10 @@ import (
"errors" "errors"
"log" "log"
"sort" "sort"
"sync"
"strconv" "strconv"
"sync"
"github.com/Azareal/Gosora/query_gen" qgen "github.com/Azareal/Gosora/query_gen"
) )
var Groups GroupStore var Groups GroupStore
@ -22,15 +22,15 @@ type GroupStore interface {
Get(id int) (*Group, error) Get(id int) (*Group, error)
GetCopy(id int) (Group, error) GetCopy(id int) (Group, error)
Exists(id int) bool Exists(id int) bool
Create(name string, tag string, isAdmin bool, isMod bool, isBanned bool) (id int, err error) Create(name, tag string, isAdmin, isMod, isBanned bool) (id int, err error)
GetAll() ([]*Group, error) GetAll() ([]*Group, error)
GetRange(lower int, higher int) ([]*Group, error) GetRange(lower, higher int) ([]*Group, error)
Reload(id int) error // ? - Should we move this to GroupCache? It might require us to do some unnecessary casting though Reload(id int) error // ? - Should we move this to GroupCache? It might require us to do some unnecessary casting though
Count() int Count() int
} }
type GroupCache interface { type GroupCache interface {
CacheSet(group *Group) error CacheSet(g *Group) error
SetCanSee(gid int, canSee []int) error SetCanSee(gid int, canSee []int) error
Length() int Length() int
} }
@ -52,10 +52,10 @@ func NewMemoryGroupStore() (*MemoryGroupStore, error) {
return &MemoryGroupStore{ return &MemoryGroupStore{
groups: make(map[int]*Group), groups: make(map[int]*Group),
groupCount: 0, groupCount: 0,
getAll: acc.Select(ug).Columns("gid, name, permissions, plugin_perms, is_mod, is_admin, is_banned, tag").Prepare(), getAll: acc.Select(ug).Columns("gid,name,permissions,plugin_perms,is_mod,is_admin,is_banned,tag").Prepare(),
get: acc.Select(ug).Columns("name, permissions, plugin_perms, is_mod, is_admin, is_banned, tag").Where("gid = ?").Prepare(), get: acc.Select(ug).Columns("name,permissions,plugin_perms,is_mod,is_admin,is_banned,tag").Where("gid=?").Prepare(),
count: acc.Count(ug).Prepare(), count: acc.Count(ug).Prepare(),
userCount: acc.Count("users").Where("group = ?").Prepare(), userCount: acc.Count("users").Where("group=?").Prepare(),
}, acc.FirstError() }, acc.FirstError()
} }
@ -98,8 +98,8 @@ func (s *MemoryGroupStore) LoadGroups() error {
} }
// TODO: Hit the database when the item isn't in memory // TODO: Hit the database when the item isn't in memory
func (s *MemoryGroupStore) dirtyGetUnsafe(gid int) *Group { func (s *MemoryGroupStore) dirtyGetUnsafe(id int) *Group {
group, ok := s.groups[gid] group, ok := s.groups[id]
if !ok { if !ok {
return &blankGroup return &blankGroup
} }
@ -107,9 +107,9 @@ func (s *MemoryGroupStore) dirtyGetUnsafe(gid int) *Group {
} }
// TODO: Hit the database when the item isn't in memory // TODO: Hit the database when the item isn't in memory
func (s *MemoryGroupStore) DirtyGet(gid int) *Group { func (s *MemoryGroupStore) DirtyGet(id int) *Group {
s.RLock() s.RLock()
group, ok := s.groups[gid] group, ok := s.groups[id]
s.RUnlock() s.RUnlock()
if !ok { if !ok {
return &blankGroup return &blankGroup
@ -118,9 +118,9 @@ func (s *MemoryGroupStore) DirtyGet(gid int) *Group {
} }
// TODO: Hit the database when the item isn't in memory // TODO: Hit the database when the item isn't in memory
func (s *MemoryGroupStore) Get(gid int) (*Group, error) { func (s *MemoryGroupStore) Get(id int) (*Group, error) {
s.RLock() s.RLock()
group, ok := s.groups[gid] group, ok := s.groups[id]
s.RUnlock() s.RUnlock()
if !ok { if !ok {
return nil, ErrNoRows return nil, ErrNoRows
@ -129,9 +129,9 @@ func (s *MemoryGroupStore) Get(gid int) (*Group, error) {
} }
// TODO: Hit the database when the item isn't in memory // TODO: Hit the database when the item isn't in memory
func (s *MemoryGroupStore) GetCopy(gid int) (Group, error) { func (s *MemoryGroupStore) GetCopy(id int) (Group, error) {
s.RLock() s.RLock()
group, ok := s.groups[gid] group, ok := s.groups[id]
s.RUnlock() s.RUnlock()
if !ok { if !ok {
return blankGroup, ErrNoRows return blankGroup, ErrNoRows
@ -147,7 +147,7 @@ func (s *MemoryGroupStore) Reload(id int) error {
return nil return nil
} }
canSee := g.CanSee canSee := g.CanSee
g = &Group{ID: id, CanSee: canSee} g = &Group{ID: id, CanSee: canSee}
err = s.get.QueryRow(id).Scan(&g.Name, &g.PermissionsText, &g.PluginPermsText, &g.IsMod, &g.IsAdmin, &g.IsBanned, &g.Tag) err = s.get.QueryRow(id).Scan(&g.Name, &g.PermissionsText, &g.PluginPermsText, &g.IsMod, &g.IsAdmin, &g.IsBanned, &g.Tag)
if err != nil { if err != nil {
@ -159,7 +159,7 @@ func (s *MemoryGroupStore) Reload(id int) error {
LogError(err) LogError(err)
return nil return nil
} }
s.CacheSet(g) s.CacheSet(g)
TopicListThaw.Thaw() TopicListThaw.Thaw()
return nil return nil
@ -218,16 +218,16 @@ func (s *MemoryGroupStore) CacheSet(g *Group) error {
} }
// TODO: Hit the database when the item isn't in memory // TODO: Hit the database when the item isn't in memory
func (s *MemoryGroupStore) Exists(gid int) bool { func (s *MemoryGroupStore) Exists(id int) bool {
s.RLock() s.RLock()
group, ok := s.groups[gid] group, ok := s.groups[id]
s.RUnlock() s.RUnlock()
return ok && group.Name != "" return ok && group.Name != ""
} }
// ? Allow two groups with the same name? // ? Allow two groups with the same name?
// TODO: Refactor this // TODO: Refactor this
func (s *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod bool, isBanned bool) (gid int, err error) { func (s *MemoryGroupStore) Create(name, tag string, isAdmin, isMod, isBanned bool) (gid int, err error) {
permstr := "{}" permstr := "{}"
tx, err := qgen.Builder.Begin() tx, err := qgen.Builder.Begin()
if err != nil { if err != nil {
@ -329,7 +329,7 @@ func (s *MemoryGroupStore) GetAllMap() (map[int]*Group, error) {
// ? - Set the lower and higher numbers to 0 to remove the bounds // ? - Set the lower and higher numbers to 0 to remove the bounds
// TODO: Might be a little slow right now, maybe we can cache the groups in a slice or break the map up into chunks // TODO: Might be a little slow right now, maybe we can cache the groups in a slice or break the map up into chunks
func (s *MemoryGroupStore) GetRange(lower int, higher int) (groups []*Group, err error) { func (s *MemoryGroupStore) GetRange(lower, higher int) (groups []*Group, err error) {
if lower == 0 && higher == 0 { if lower == 0 && higher == 0 {
return s.GetAll() return s.GetAll()
} }

View File

@ -31,8 +31,8 @@ func init() {
DbInits.Add(func(acc *qgen.Accumulator) error { DbInits.Add(func(acc *qgen.Accumulator) error {
rl := "registration_logs" rl := "registration_logs"
regLogStmts = RegLogStmts{ regLogStmts = RegLogStmts{
update: acc.Update(rl).Set("username=?, email=?, failureReason=?, success=?").Where("rlid=?").Prepare(), update: acc.Update(rl).Set("username=?,email=?,failureReason=?,success=?").Where("rlid=?").Prepare(),
create: acc.Insert(rl).Columns("username, email, failureReason, success, ipaddress, doneAt").Fields("?,?,?,?,?,UTC_TIMESTAMP()").Prepare(), create: acc.Insert(rl).Columns("username,email,failureReason,success,ipaddress,doneAt").Fields("?,?,?,?,?,UTC_TIMESTAMP()").Prepare(),
} }
return acc.FirstError() return acc.FirstError()
}) })
@ -69,7 +69,7 @@ func NewRegLogStore(acc *qgen.Accumulator) (*SQLRegLogStore, error) {
rl := "registration_logs" rl := "registration_logs"
return &SQLRegLogStore{ return &SQLRegLogStore{
count: acc.Count(rl).Prepare(), count: acc.Count(rl).Prepare(),
getOffset: acc.Select(rl).Columns("rlid, username, email, failureReason, success, ipaddress, doneAt").Orderby("doneAt DESC").Limit("?,?").Prepare(), getOffset: acc.Select(rl).Columns("rlid,username,email,failureReason,success,ipaddress,doneAt").Orderby("doneAt DESC").Limit("?,?").Prepare(),
}, acc.FirstError() }, acc.FirstError()
} }

View File

@ -18,7 +18,7 @@ type ReplyCache interface {
RemoveUnsafe(id int) error RemoveUnsafe(id int) error
Flush() Flush()
Length() int Length() int
SetCapacity(capacity int) SetCapacity(cap int)
GetCapacity() int GetCapacity() int
} }
@ -32,10 +32,10 @@ type MemoryReplyCache struct {
} }
// NewMemoryReplyCache gives you a new instance of MemoryReplyCache // NewMemoryReplyCache gives you a new instance of MemoryReplyCache
func NewMemoryReplyCache(capacity int) *MemoryReplyCache { func NewMemoryReplyCache(cap int) *MemoryReplyCache {
return &MemoryReplyCache{ return &MemoryReplyCache{
items: make(map[int]*Reply), items: make(map[int]*Reply),
capacity: capacity, capacity: cap,
} }
} }
@ -152,9 +152,9 @@ func (s *MemoryReplyCache) Length() int {
} }
// SetCapacity sets the maximum number of replies which this cache can hold // SetCapacity sets the maximum number of replies which this cache can hold
func (s *MemoryReplyCache) SetCapacity(capacity int) { func (s *MemoryReplyCache) SetCapacity(cap int) {
// Ints are moved in a single instruction, so this should be thread-safe // Ints are moved in a single instruction, so this should be thread-safe
s.capacity = capacity s.capacity = cap
} }
// GetCapacity returns the maximum number of replies this cache can hold // GetCapacity returns the maximum number of replies this cache can hold

View File

@ -13,7 +13,7 @@ type ReplyStore interface {
Get(id int) (*Reply, error) Get(id int) (*Reply, error)
Each(f func(*Reply) error) error Each(f func(*Reply) error) error
Exists(id int) bool Exists(id int) bool
Create(t *Topic, content string, ip string, uid int) (id int, err error) Create(t *Topic, content, ip string, uid int) (id int, err error)
Count() (count int) Count() (count int)
CountUser(uid int) (count int) CountUser(uid int) (count int)
CountMegaUser(uid int) (count int) CountMegaUser(uid int) (count int)

View File

@ -17,7 +17,7 @@ type TopicCache interface {
RemoveUnsafe(id int) error RemoveUnsafe(id int) error
Flush() Flush()
Length() int Length() int
SetCapacity(capacity int) SetCapacity(cap int)
GetCapacity() int GetCapacity() int
} }
@ -31,10 +31,10 @@ type MemoryTopicCache struct {
} }
// NewMemoryTopicCache gives you a new instance of MemoryTopicCache // NewMemoryTopicCache gives you a new instance of MemoryTopicCache
func NewMemoryTopicCache(capacity int) *MemoryTopicCache { func NewMemoryTopicCache(cap int) *MemoryTopicCache {
return &MemoryTopicCache{ return &MemoryTopicCache{
items: make(map[int]*Topic), items: make(map[int]*Topic),
capacity: capacity, capacity: cap,
} }
} }
@ -150,9 +150,9 @@ func (s *MemoryTopicCache) Length() int {
} }
// SetCapacity sets the maximum number of topics which this cache can hold // SetCapacity sets the maximum number of topics which this cache can hold
func (s *MemoryTopicCache) SetCapacity(capacity int) { func (s *MemoryTopicCache) SetCapacity(cap int) {
// Ints are moved in a single instruction, so this should be thread-safe // Ints are moved in a single instruction, so this should be thread-safe
s.capacity = capacity s.capacity = cap
} }
// GetCapacity returns the maximum number of topics this cache can hold // GetCapacity returns the maximum number of topics this cache can hold

View File

@ -250,7 +250,7 @@ func (u *User) setTempGroupTx(tx *sql.Tx, tempGroup int) error {
} }
// Make this more stateless? // Make this more stateless?
func (u *User) ScheduleGroupUpdate(gid int, issuedBy int, duration time.Duration) error { func (u *User) ScheduleGroupUpdate(gid, issuedBy int, duration time.Duration) error {
var temp bool var temp bool
if duration.Nanoseconds() != 0 { if duration.Nanoseconds() != 0 {
temp = true temp = true

View File

@ -18,7 +18,7 @@ type UserCache interface {
RemoveUnsafe(id int) error RemoveUnsafe(id int) error
Flush() Flush()
Length() int Length() int
SetCapacity(capacity int) SetCapacity(cap int)
GetCapacity() int GetCapacity() int
} }
@ -32,10 +32,10 @@ type MemoryUserCache struct {
} }
// NewMemoryUserCache gives you a new instance of MemoryUserCache // NewMemoryUserCache gives you a new instance of MemoryUserCache
func NewMemoryUserCache(capacity int) *MemoryUserCache { func NewMemoryUserCache(cap int) *MemoryUserCache {
return &MemoryUserCache{ return &MemoryUserCache{
items: make(map[int]*User), items: make(map[int]*User),
capacity: capacity, capacity: cap,
} }
} }
@ -219,9 +219,9 @@ func (s *MemoryUserCache) Length() int {
} }
// SetCapacity sets the maximum number of users which this cache can hold // SetCapacity sets the maximum number of users which this cache can hold
func (s *MemoryUserCache) SetCapacity(capacity int) { func (s *MemoryUserCache) SetCapacity(cap int) {
// Ints are moved in a single instruction, so this should be thread-safe // Ints are moved in a single instruction, so this should be thread-safe
s.capacity = capacity s.capacity = cap
} }
// GetCapacity returns the maximum number of users this cache can hold // GetCapacity returns the maximum number of users this cache can hold

View File

@ -25,7 +25,7 @@ type UserStore interface {
//BulkGet(ids []int) ([]*User, error) //BulkGet(ids []int) ([]*User, error)
BulkGetMap(ids []int) (map[int]*User, error) BulkGetMap(ids []int) (map[int]*User, error)
BypassGet(id int) (*User, error) BypassGet(id int) (*User, error)
Create(name string, password string, email string, group int, active bool) (int, error) Create(name, password, email string, group int, active bool) (int, error)
Reload(id int) error Reload(id int) error
Count() int Count() int
@ -56,7 +56,7 @@ func NewDefaultUserStore(cache UserCache) (*DefaultUserStore, error) {
// TODO: Add an admin version of registerStmt with more flexibility? // TODO: Add an admin version of registerStmt with more flexibility?
return &DefaultUserStore{ return &DefaultUserStore{
cache: cache, cache: cache,
get: acc.Select(u).Columns("name, group, active, is_super_admin, session, email, avatar, message, level, score, posts, liked, last_ip, temp_group, enable_embeds").Where("uid = ?").Prepare(), get: acc.Select(u).Columns("name, group, active, is_super_admin, session, email, avatar, message, level, score, posts, liked, last_ip, temp_group, enable_embeds").Where("uid=?").Prepare(),
getByName: acc.Select(u).Columns("uid, name, group, active, is_super_admin, session, email, avatar, message, level, score, posts, liked, last_ip, temp_group, enable_embeds").Where("name = ?").Prepare(), getByName: acc.Select(u).Columns("uid, name, group, active, is_super_admin, session, email, avatar, message, level, score, posts, liked, last_ip, temp_group, enable_embeds").Where("name = ?").Prepare(),
getOffset: acc.Select(u).Columns("uid, name, group, active, is_super_admin, session, email, avatar, message, level, score, posts, liked, last_ip, temp_group, enable_embeds").Orderby("uid ASC").Limit("?,?").Prepare(), getOffset: acc.Select(u).Columns("uid, name, group, active, is_super_admin, session, email, avatar, message, level, score, posts, liked, last_ip, temp_group, enable_embeds").Orderby("uid ASC").Limit("?,?").Prepare(),
getAll: acc.Select(u).Columns("uid, name, group, active, is_super_admin, session, email, avatar, message, level, score, posts, liked, last_ip, temp_group, enable_embeds").Prepare(), getAll: acc.Select(u).Columns("uid, name, group, active, is_super_admin, session, email, avatar, message, level, score, posts, liked, last_ip, temp_group, enable_embeds").Prepare(),

View File

@ -39,8 +39,8 @@ func init() {
//easyjson:json //easyjson:json
type WsTopicList struct { type WsTopicList struct {
Topics []*WsTopicsRow Topics []*WsTopicsRow
LastPage int // Not for WebSockets, but for the JSON endpoint for /topics/ to keep the paginator functional LastPage int // Not for WebSockets, but for the JSON endpoint for /topics/ to keep the paginator functional
LastUpdate int64 LastUpdate int64
} }
@ -214,7 +214,7 @@ func wsPageResume(wsUser *WSUser, conn *websocket.Conn, page string, resume int6
if page == "/" { if page == "/" {
page = Config.DefaultPath page = Config.DefaultPath
} }
switch { switch {
// TODO: Synchronise this bit of resume with tick updating lastTopicList? // TODO: Synchronise this bit of resume with tick updating lastTopicList?
case page == "/topics/": case page == "/topics/":
@ -414,27 +414,27 @@ AdminStatLoop:
w.Write([]byte(msg + "\r")) w.Write([]byte(msg + "\r"))
} }
push := func(id, msg string) { push := func(id, msg string) {
write("set #" + id + " <span>"+msg+"</span>") write("set #" + id + " <span>" + msg + "</span>")
} }
pushc := func(id, classes string) { pushc := func(id, classes string) {
write("set-class #" + id + " " + classes) write("set-class #" + id + " " + classes)
} }
if !noStatUpdates { if !noStatUpdates {
push("dash-totonline",p.GetTmplPhrasef("panel_dashboard_online", totonline, totunit)) push("dash-totonline", p.GetTmplPhrasef("panel_dashboard_online", totonline, totunit))
push("dash-gonline",p.GetTmplPhrasef("panel_dashboard_guests_online", gonline, gunit)) push("dash-gonline", p.GetTmplPhrasef("panel_dashboard_guests_online", gonline, gunit))
push("dash-uonline",p.GetTmplPhrasef("panel_dashboard_users_online", uonline, uunit)) push("dash-uonline", p.GetTmplPhrasef("panel_dashboard_users_online", uonline, uunit))
push("dash-reqs",strconv.Itoa(reqCount) + " reqs / second") push("dash-reqs", strconv.Itoa(reqCount)+" reqs / second")
pushc("dash-totonline","grid_item grid_stat " + onlineColour) pushc("dash-totonline", "grid_item grid_stat "+onlineColour)
pushc("dash-gonline","grid_item grid_stat " + onlineGuestsColour) pushc("dash-gonline", "grid_item grid_stat "+onlineGuestsColour)
pushc("dash-uonline","grid_item grid_stat " + onlineUsersColour) pushc("dash-uonline", "grid_item grid_stat "+onlineUsersColour)
//pushc("dash-reqs","grid_item grid_stat grid_end_group") //pushc("dash-reqs","grid_item grid_stat grid_end_group")
} }
push("dash-cpu",p.GetTmplPhrasef("panel_dashboard_cpu",cpustr) + "%") push("dash-cpu", p.GetTmplPhrasef("panel_dashboard_cpu", cpustr)+"%")
pushc("dash-cpu","grid_item grid_istat " + cpuColour) pushc("dash-cpu", "grid_item grid_istat "+cpuColour)
if !noRAMUpdates { if !noRAMUpdates {
push("dash-ram", p.GetTmplPhrasef("panel_dashboard_ram",ramstr)) push("dash-ram", p.GetTmplPhrasef("panel_dashboard_ram", ramstr))
pushc("dash-ram","grid_item grid_istat " + ramColour) pushc("dash-ram", "grid_item grid_istat "+ramColour)
} }
w.Close() w.Close()
} }

View File

@ -27,7 +27,7 @@ func init() {
w := "widgets" w := "widgets"
widgetStmts = WidgetStmts{ widgetStmts = WidgetStmts{
//getList: acc.Select(w).Columns("wid, position, side, type, active, location, data").Orderby("position ASC").Prepare(), //getList: acc.Select(w).Columns("wid, position, side, type, active, location, data").Orderby("position ASC").Prepare(),
getDockList: acc.Select(w).Columns("wid, position, type, active, location, data").Where("side = ?").Orderby("position ASC").Prepare(), getDockList: acc.Select(w).Columns("wid, position, type, active, location, data").Where("side=?").Orderby("position ASC").Prepare(),
//model: acc.SimpleModel(w,"position,type,active,location,data","wid"), //model: acc.SimpleModel(w,"position,type,active,location,data","wid"),
delete: acc.Delete(w).Where("wid=?").Prepare(), delete: acc.Delete(w).Where("wid=?").Prepare(),
create: acc.Insert(w).Columns("position, side, type, active, location, data").Fields("?,?,?,?,?,?").Prepare(), create: acc.Insert(w).Columns("position, side, type, active, location, data").Fields("?,?,?,?,?,?").Prepare(),
@ -50,7 +50,7 @@ type Widget struct {
Literal bool Literal bool
TickMask atomic.Value TickMask atomic.Value
InitFunc func(w *Widget, schedule *WidgetScheduler) error InitFunc func(w *Widget, sched *WidgetScheduler) error
ShutdownFunc func(w *Widget) error ShutdownFunc func(w *Widget) error
BuildFunc func(w *Widget, hvars interface{}) (string, error) BuildFunc func(w *Widget, hvars interface{}) (string, error)
TickFunc func(w *Widget) error TickFunc func(w *Widget) error

View File

@ -16,24 +16,24 @@ func NewDefaultWidgetStore() *DefaultWidgetStore {
return &DefaultWidgetStore{widgets: make(map[int]*Widget)} return &DefaultWidgetStore{widgets: make(map[int]*Widget)}
} }
func (w *DefaultWidgetStore) Get(id int) (*Widget, error) { func (s *DefaultWidgetStore) Get(id int) (*Widget, error) {
w.RLock() s.RLock()
defer w.RUnlock() defer s.RUnlock()
widget, ok := w.widgets[id] w, ok := s.widgets[id]
if !ok { if !ok {
return widget, sql.ErrNoRows return w, sql.ErrNoRows
} }
return widget, nil return w, nil
} }
func (w *DefaultWidgetStore) set(widget *Widget) { func (s *DefaultWidgetStore) set(w *Widget) {
w.Lock() s.Lock()
defer w.Unlock() defer s.Unlock()
w.widgets[widget.ID] = widget s.widgets[w.ID] = w
} }
func (w *DefaultWidgetStore) delete(id int) { func (s *DefaultWidgetStore) delete(id int) {
w.Lock() s.Lock()
defer w.Unlock() defer s.Unlock()
delete(w.widgets, id) delete(s.widgets, id)
} }

View File

@ -16,8 +16,8 @@ type wolUsers struct {
UserCount int UserCount int
} }
func wolInit(w *Widget, schedule *WidgetScheduler) error { func wolInit(w *Widget, sched *WidgetScheduler) error {
schedule.Add(w) sched.Add(w)
return nil return nil
} }

View File

@ -52,7 +52,7 @@ func (u *WSUser) WriteAll(msg string) error {
return nil return nil
} }
func (u *WSUser) WriteToPage(msg string, page string) error { func (u *WSUser) WriteToPage(msg, page string) error {
return u.WriteToPageBytes([]byte(msg), page) return u.WriteToPageBytes([]byte(msg), page)
} }

View File

@ -1,13 +1,16 @@
package guilds package guilds
import "database/sql" import (
import "github.com/Azareal/Gosora/query_gen" "database/sql"
qgen "github.com/Azareal/Gosora/query_gen"
)
var Gstore GuildStore var Gstore GuildStore
type GuildStore interface { type GuildStore interface {
Get(id int) (guild *Guild, err error) Get(id int) (g *Guild, err error)
Create(name string, desc string, active bool, privacy int, uid int, fid int) (int, error) Create(name, desc string, active bool, privacy, uid, fid int) (int, error)
} }
type SQLGuildStore struct { type SQLGuildStore struct {
@ -18,7 +21,7 @@ type SQLGuildStore struct {
func NewSQLGuildStore() (*SQLGuildStore, error) { func NewSQLGuildStore() (*SQLGuildStore, error) {
acc := qgen.NewAcc() acc := qgen.NewAcc()
return &SQLGuildStore{ return &SQLGuildStore{
get: acc.Select("guilds").Columns("name, desc, active, privacy, joinable, owner, memberCount, mainForum, backdrop, createdAt, lastUpdateTime").Where("guildID = ?").Prepare(), get: acc.Select("guilds").Columns("name, desc, active, privacy, joinable, owner, memberCount, mainForum, backdrop, createdAt, lastUpdateTime").Where("guildID=?").Prepare(),
create: acc.Insert("guilds").Columns("name, desc, active, privacy, joinable, owner, memberCount, mainForum, backdrop, createdAt, lastUpdateTime").Fields("?,?,?,?,1,?,1,?,'',UTC_TIMESTAMP(),UTC_TIMESTAMP()").Prepare(), create: acc.Insert("guilds").Columns("name, desc, active, privacy, joinable, owner, memberCount, mainForum, backdrop, createdAt, lastUpdateTime").Fields("?,?,?,?,1,?,1,?,'',UTC_TIMESTAMP(),UTC_TIMESTAMP()").Prepare(),
}, acc.FirstError() }, acc.FirstError()
} }
@ -28,13 +31,13 @@ func (s *SQLGuildStore) Close() {
_ = s.create.Close() _ = s.create.Close()
} }
func (s *SQLGuildStore) Get(id int) (guild *Guild, err error) { func (s *SQLGuildStore) Get(id int) (g *Guild, err error) {
g = &Guild{ID: id} g = &Guild{ID: id}
err = s.get.QueryRow(guildID).Scan(&g.Name, &g.Desc, &g.Active, &g.Privacy, &g.Joinable, &g.Owner, &g.MemberCount, &g.MainForumID, &g.Backdrop, &g.CreatedAt, &g.LastUpdateTime) err = s.get.QueryRow(id).Scan(&g.Name, &g.Desc, &g.Active, &g.Privacy, &g.Joinable, &g.Owner, &g.MemberCount, &g.MainForumID, &g.Backdrop, &g.CreatedAt, &g.LastUpdateTime)
return g, err return g, err
} }
func (s *SQLGuildStore) Create(name string, desc string, active bool, privacy int, uid int, fid int) (int, error) { func (s *SQLGuildStore) Create(name, desc string, active bool, privacy, uid, fid int) (int, error) {
res, err := s.create.Exec(name, desc, active, privacy, uid, fid) res, err := s.create.Exec(name, desc, active, privacy, uid, fid)
if err != nil { if err != nil {
return 0, err return 0, err

View File

@ -87,7 +87,7 @@ type Member struct {
User c.User User c.User
} }
func PrebuildTmplList(user c.User, h *c.Header) c.CTmpl { func PrebuildTmplList(user *c.User, h *c.Header) c.CTmpl {
guildList := []*Guild{ guildList := []*Guild{
&Guild{ &Guild{
ID: 1, ID: 1,
@ -113,7 +113,7 @@ func PrebuildTmplList(user c.User, h *c.Header) c.CTmpl {
func CommonAreaWidgets(header *c.Header) { func CommonAreaWidgets(header *c.Header) {
// TODO: Hot Groups? Featured Groups? Official Groups? // TODO: Hot Groups? Featured Groups? Official Groups?
var b bytes.Buffer var b bytes.Buffer
var menu = c.WidgetMenu{"Guilds", []c.WidgetMenuItem{ menu := c.WidgetMenu{"Guilds", []c.WidgetMenuItem{
c.WidgetMenuItem{"Create Guild", "/guild/create/", false}, c.WidgetMenuItem{"Create Guild", "/guild/create/", false},
}} }}
@ -162,11 +162,11 @@ func GuildWidgets(header *c.Header, guildItem *Guild) (success bool) {
*/ */
func RouteGuildList(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func RouteGuildList(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
header, ferr := c.UserCheck(w, r, &user) h, ferr := c.UserCheck(w, r, &user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
CommonAreaWidgets(header) CommonAreaWidgets(h)
rows, err := ListStmt.Query() rows, err := ListStmt.Query()
if err != nil && err != c.ErrNoRows { if err != nil && err != c.ErrNoRows {
@ -176,21 +176,20 @@ func RouteGuildList(w http.ResponseWriter, r *http.Request, user c.User) c.Route
var guildList []*Guild var guildList []*Guild
for rows.Next() { for rows.Next() {
guildItem := &Guild{ID: 0} g := &Guild{ID: 0}
err := rows.Scan(&guildItem.ID, &guildItem.Name, &guildItem.Desc, &guildItem.Active, &guildItem.Privacy, &guildItem.Joinable, &guildItem.Owner, &guildItem.MemberCount, &guildItem.CreatedAt, &guildItem.LastUpdateTime) err := rows.Scan(&g.ID, &g.Name, &g.Desc, &g.Active, &g.Privacy, &g.Joinable, &g.Owner, &g.MemberCount, &g.CreatedAt, &g.LastUpdateTime)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
guildItem.Link = BuildGuildURL(c.NameToSlug(guildItem.Name), guildItem.ID) g.Link = BuildGuildURL(c.NameToSlug(g.Name), g.ID)
guildList = append(guildList, guildItem) guildList = append(guildList, g)
} }
err = rows.Err() if err = rows.Err(); err != nil {
if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
pi := ListPage{"Guild List", user, header, guildList} pi := ListPage{"Guild List", user, h, guildList}
return routes.RenderTemplate("guilds_guild_list", w, r, header, pi) return routes.RenderTemplate("guilds_guild_list", w, r, h, pi)
} }
func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
@ -217,18 +216,18 @@ func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
} }
func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
header, ferr := c.UserCheck(w, r, &user) h, ferr := c.UserCheck(w, r, &user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
header.Title = "Create Guild" h.Title = "Create Guild"
// TODO: Add an approval queue mode for group creation // TODO: Add an approval queue mode for group creation
if !user.Loggedin || !user.PluginPerms["CreateGuild"] { if !user.Loggedin || !user.PluginPerms["CreateGuild"] {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
CommonAreaWidgets(header) CommonAreaWidgets(h)
return routes.RenderTemplate("guilds_create_guild", w, r, header, c.Page{header, tList, nil}) return routes.RenderTemplate("guilds_create_guild", w, r, h, c.Page{h, tList, nil})
} }
func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
@ -237,14 +236,13 @@ func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user c.User)
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
var guildActive = true guildActive := true
var guildName = c.SanitiseSingleLine(r.PostFormValue("group_name")) guildName := c.SanitiseSingleLine(r.PostFormValue("group_name"))
// TODO: Allow Markdown / BBCode / Limited HTML in the description? // TODO: Allow Markdown / BBCode / Limited HTML in the description?
var guildDesc = c.SanitiseBody(r.PostFormValue("group_desc")) guildDesc := c.SanitiseBody(r.PostFormValue("group_desc"))
var gprivacy = r.PostFormValue("group_privacy")
var guildPrivacy int var guildPrivacy int
switch gprivacy { switch r.PostFormValue("group_privacy") {
case "0": case "0":
guildPrivacy = 0 // Public guildPrivacy = 0 // Public
case "1": case "1":
@ -292,13 +290,13 @@ func RouteMemberList(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
return c.PreError("Not a valid group ID", w, r) return c.PreError("Not a valid group ID", w, r)
} }
guildItem, err := Gstore.Get(guildID) guild, err := Gstore.Get(guildID)
if err != nil { if err != nil {
return c.LocalError("Bad group", w, r, user) return c.LocalError("Bad group", w, r, user)
} }
guildItem.Link = BuildGuildURL(c.NameToSlug(guildItem.Name), guildItem.ID) guild.Link = BuildGuildURL(c.NameToSlug(guild.Name), guild.ID)
GuildWidgets(header, guildItem) GuildWidgets(header, guild)
rows, err := MemberListJoinStmt.Query(guildID) rows, err := MemberListJoinStmt.Query(guildID)
if err != nil && err != c.ErrNoRows { if err != nil && err != c.ErrNoRows {
@ -307,35 +305,34 @@ func RouteMemberList(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
var guildMembers []Member var guildMembers []Member
for rows.Next() { for rows.Next() {
guildMember := Member{PostCount: 0} gMember := Member{PostCount: 0}
err := rows.Scan(&guildMember.User.ID, &guildMember.Rank, &guildMember.PostCount, &guildMember.JoinedAt, &guildMember.User.Name, &guildMember.User.RawAvatar) err := rows.Scan(&gMember.User.ID, &gMember.Rank, &gMember.PostCount, &gMember.JoinedAt, &gMember.User.Name, &gMember.User.RawAvatar)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
guildMember.Link = c.BuildProfileURL(c.NameToSlug(guildMember.User.Name), guildMember.User.ID) gMember.Link = c.BuildProfileURL(c.NameToSlug(gMember.User.Name), gMember.User.ID)
guildMember.User.Avatar, guildMember.User.MicroAvatar = c.BuildAvatar(guildMember.User.ID, guildMember.User.RawAvatar) gMember.User.Avatar, gMember.User.MicroAvatar = c.BuildAvatar(gMember.User.ID, gMember.User.RawAvatar)
guildMember.JoinedAt, _ = c.RelativeTimeFromString(guildMember.JoinedAt) gMember.JoinedAt, _ = c.RelativeTimeFromString(gMember.JoinedAt)
if guildItem.Owner == guildMember.User.ID { if guild.Owner == gMember.User.ID {
guildMember.RankString = "Owner" gMember.RankString = "Owner"
} else { } else {
switch guildMember.Rank { switch gMember.Rank {
case 0: case 0:
guildMember.RankString = "Member" gMember.RankString = "Member"
case 1: case 1:
guildMember.RankString = "Mod" gMember.RankString = "Mod"
case 2: case 2:
guildMember.RankString = "Admin" gMember.RankString = "Admin"
} }
} }
guildMembers = append(guildMembers, guildMember) guildMembers = append(guildMembers, gMember)
} }
err = rows.Err() if err = rows.Err(); err != nil {
if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
rows.Close() rows.Close()
pi := MemberListPage{"Guild Member List", user, header, guildMembers, guildItem, 0, 0} pi := MemberListPage{"Guild Member List", user, header, gMembers, guild, 0, 0}
// A plugin with plugins. Pluginception! // A plugin with plugins. Pluginception!
if c.RunPreRenderHook("pre_render_guilds_member_list", w, r, &user, &pi) { if c.RunPreRenderHook("pre_render_guilds_member_list", w, r, &user, &pi) {
return nil return nil
@ -347,7 +344,7 @@ func RouteMemberList(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
return nil return nil
} }
func AttachForum(guildID int, fid int) error { func AttachForum(guildID, fid int) error {
_, err := AttachForumStmt.Exec(guildID, fid) _, err := AttachForumStmt.Exec(guildID, fid)
return err return err
} }
@ -410,9 +407,9 @@ func TopicCreatePreLoop(args ...interface{}) interface{} {
// 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 js 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) r := args[1].(*http.Request)
var fid = args[3].(*int) fid := args[3].(*int)
var forum = c.Forums.DirtyGet(*fid) forum := c.Forums.DirtyGet(*fid)
if forum.ParentType == "guild" { if forum.ParentType == "guild" {
var err error var err error
@ -430,8 +427,7 @@ func ForumCheck(args ...interface{}) (skip bool, rerr c.RouteError) {
} }
user := args[2].(*c.User) user := args[2].(*c.User)
var rank int var rank, posts int
var posts int
var joinedAt string var joinedAt string
// TODO: Group privacy settings. For now, groups are all globally visible // TODO: Group privacy settings. For now, groups are all globally visible
@ -475,27 +471,27 @@ func ForumCheck(args ...interface{}) (skip bool, rerr c.RouteError) {
func Widgets(args ...interface{}) interface{} { func Widgets(args ...interface{}) interface{} {
zone := args[0].(string) zone := args[0].(string)
header := args[2].(*c.Header) h := args[2].(*c.Header)
request := args[3].(*http.Request) request := args[3].(*http.Request)
if zone != "view_forum" { if zone != "view_forum" {
return false return false
} }
forum := args[1].(*c.Forum) f := args[1].(*c.Forum)
if forum.ParentType == "guild" { if f.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) guild, ok := request.Context().Value("guilds_current_group").(*Guild)
if !ok { if !ok {
c.LogError(errors.New("Unable to find a parent group in the context data")) c.LogError(errors.New("Unable to find a parent group in the context data"))
return false return false
} }
if header.ExtData.Items == nil { if h.ExtData.Items == nil {
header.ExtData.Items = make(map[string]interface{}) h.ExtData.Items = make(map[string]interface{})
} }
header.ExtData.Items["guilds_current_group"] = guildItem h.ExtData.Items["guilds_current_group"] = guild
return GuildWidgets(header, guildItem) return GuildWidgets(h, guild)
} }
return false return false
} }