Shortening some things.
Fix the ordering of the lock in WsHubImpl.GuestCount.
This commit is contained in:
parent
85b0522955
commit
ff48ec9d86
|
@ -198,7 +198,7 @@ func ReplaceForumPermsForGroupTx(tx *sql.Tx, gid int, presetSets map[int]string,
|
|||
return err
|
||||
}
|
||||
|
||||
addForumPermsToGroupTx, err := qgen.Builder.SimpleInsertTx(tx, "forums_permissions", "gid, fid, preset, permissions", "?,?,?,?")
|
||||
addForumPermsToGroupTx, err := qgen.Builder.SimpleInsertTx(tx, "forums_permissions", "gid,fid,preset,permissions", "?,?,?,?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -222,19 +222,19 @@ func ReplaceForumPermsForGroupTx(tx *sql.Tx, gid int, presetSets map[int]string,
|
|||
|
||||
// TODO: Refactor this and write tests for it
|
||||
// TODO: We really need to improve the thread safety of this
|
||||
func ForumPermsToGroupForumPreset(fperms *ForumPerms) string {
|
||||
if !fperms.Overrides {
|
||||
func ForumPermsToGroupForumPreset(fp *ForumPerms) string {
|
||||
if !fp.Overrides {
|
||||
return "default"
|
||||
}
|
||||
if !fperms.ViewTopic {
|
||||
if !fp.ViewTopic {
|
||||
return "no_access"
|
||||
}
|
||||
canPost := (fperms.LikeItem && fperms.CreateTopic && fperms.CreateReply)
|
||||
canModerate := (canPost && fperms.EditTopic && fperms.DeleteTopic && fperms.EditReply && fperms.DeleteReply && fperms.PinTopic && fperms.CloseTopic && fperms.MoveTopic)
|
||||
canPost := (fp.LikeItem && fp.CreateTopic && fp.CreateReply)
|
||||
canModerate := (canPost && fp.EditTopic && fp.DeleteTopic && fp.EditReply && fp.DeleteReply && fp.PinTopic && fp.CloseTopic && fp.MoveTopic)
|
||||
if canModerate {
|
||||
return "can_moderate"
|
||||
}
|
||||
if fperms.EditTopic || fperms.DeleteTopic || fperms.EditReply || fperms.DeleteReply || fperms.PinTopic || fperms.CloseTopic || fperms.MoveTopic {
|
||||
if fp.EditTopic || fp.DeleteTopic || fp.EditReply || fp.DeleteReply || fp.PinTopic || fp.CloseTopic || fp.MoveTopic {
|
||||
//if !canPost {
|
||||
return "custom"
|
||||
//}
|
||||
|
@ -244,7 +244,7 @@ func ForumPermsToGroupForumPreset(fperms *ForumPerms) string {
|
|||
if canPost {
|
||||
return "can_post"
|
||||
}
|
||||
if fperms.ViewTopic && !fperms.LikeItem && !fperms.CreateTopic && !fperms.CreateReply {
|
||||
if fp.ViewTopic && !fp.LikeItem && !fp.CreateTopic && !fp.CreateReply {
|
||||
return "read_only"
|
||||
}
|
||||
return "custom"
|
||||
|
|
|
@ -35,9 +35,9 @@ func NewSQLSearcher(acc *qgen.Accumulator) (*SQLSearcher, error) {
|
|||
}, acc.FirstError()
|
||||
}
|
||||
|
||||
func (search *SQLSearcher) queryAll(q string) ([]int, error) {
|
||||
func (s *SQLSearcher) queryAll(q string) ([]int, error) {
|
||||
var ids []int
|
||||
var run = func(stmt *sql.Stmt, q ...interface{}) error {
|
||||
run := func(stmt *sql.Stmt, q ...interface{}) error {
|
||||
rows, err := stmt.Query(q...)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil
|
||||
|
@ -57,11 +57,11 @@ func (search *SQLSearcher) queryAll(q string) ([]int, error) {
|
|||
return rows.Err()
|
||||
}
|
||||
|
||||
err := run(search.queryReplies, q)
|
||||
err := run(s.queryReplies, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = run(search.queryTopics, q, q)
|
||||
err = run(s.queryTopics, q, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -71,11 +71,11 @@ func (search *SQLSearcher) queryAll(q string) ([]int, error) {
|
|||
return ids, err
|
||||
}
|
||||
|
||||
func (search *SQLSearcher) Query(q string, zones []int) (ids []int, err error) {
|
||||
func (s *SQLSearcher) Query(q string, zones []int) (ids []int, err error) {
|
||||
if len(zones) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
var run = func(rows *sql.Rows, err error) error {
|
||||
run := func(rows *sql.Rows, err error) error {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
|
@ -95,7 +95,7 @@ func (search *SQLSearcher) Query(q string, zones []int) (ids []int, err error) {
|
|||
}
|
||||
|
||||
if len(zones) == 1 {
|
||||
err = run(search.queryZone.Query(q, q, q, zones[0]))
|
||||
err = run(s.queryZone.Query(q, q, q, zones[0]))
|
||||
} else {
|
||||
var zList string
|
||||
for _, zone := range zones {
|
||||
|
@ -128,6 +128,6 @@ func NewElasticSearchSearcher() (*ElasticSearchSearcher, error) {
|
|||
return &ElasticSearchSearcher{}, nil
|
||||
}
|
||||
|
||||
func (search *ElasticSearchSearcher) Query(q string, zones []int) ([]int, error) {
|
||||
func (s *ElasticSearchSearcher) Query(q string, zones []int) ([]int, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ func init() {
|
|||
|
||||
func NewThemeList() (themes ThemeList, err error) {
|
||||
themes = make(map[string]*Theme)
|
||||
|
||||
themeFiles, err := ioutil.ReadDir("./themes")
|
||||
if err != nil {
|
||||
return themes, err
|
||||
|
@ -76,7 +75,7 @@ func NewThemeList() (themes ThemeList, err error) {
|
|||
return themes, err
|
||||
}
|
||||
|
||||
var theme = &Theme{Name: ""}
|
||||
theme := &Theme{Name: ""}
|
||||
err = json.Unmarshal(themeFile, theme)
|
||||
if err != nil {
|
||||
return themes, err
|
||||
|
@ -151,7 +150,7 @@ func NewThemeList() (themes ThemeList, err error) {
|
|||
if override.IsDir() {
|
||||
continue
|
||||
}
|
||||
var ext = filepath.Ext(themePath + "/overrides/" + override.Name())
|
||||
ext := filepath.Ext(themePath + "/overrides/" + override.Name())
|
||||
log.Print("attempting to add " + themePath + "/overrides/" + override.Name())
|
||||
if ext != ".html" {
|
||||
log.Print("not a html file")
|
||||
|
@ -192,7 +191,7 @@ func NewThemeList() (themes ThemeList, err error) {
|
|||
|
||||
// TODO: Make the initThemes and LoadThemes functions less confusing
|
||||
// ? - Delete themes which no longer exist in the themes folder from the database?
|
||||
func (themes ThemeList) LoadActiveStatus() error {
|
||||
func (t ThemeList) LoadActiveStatus() error {
|
||||
ChangeDefaultThemeMutex.Lock()
|
||||
defer ChangeDefaultThemeMutex.Unlock()
|
||||
|
||||
|
@ -211,7 +210,7 @@ func (themes ThemeList) LoadActiveStatus() error {
|
|||
}
|
||||
|
||||
// Was the theme deleted at some point?
|
||||
theme, ok := themes[uname]
|
||||
theme, ok := t[uname]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
@ -226,13 +225,13 @@ func (themes ThemeList) LoadActiveStatus() error {
|
|||
theme.Active = false
|
||||
}
|
||||
|
||||
themes[uname] = theme
|
||||
t[uname] = theme
|
||||
}
|
||||
return rows.Err()
|
||||
}
|
||||
|
||||
func (themes ThemeList) LoadStaticFiles() error {
|
||||
for _, theme := range themes {
|
||||
func (t ThemeList) LoadStaticFiles() error {
|
||||
for _, theme := range t {
|
||||
err := theme.LoadStaticFiles()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -290,10 +290,10 @@ var adminStatsMutex sync.RWMutex
|
|||
func adminStatsTicker() {
|
||||
time.Sleep(time.Second)
|
||||
|
||||
var lastUonline = -1
|
||||
var lastGonline = -1
|
||||
var lastTotonline = -1
|
||||
var lastCPUPerc = -1
|
||||
lastUonline := -1
|
||||
lastGonline := -1
|
||||
lastTotonline := -1
|
||||
lastCPUPerc := -1
|
||||
var lastAvailableRAM int64 = -1
|
||||
var noStatUpdates, noRAMUpdates bool
|
||||
|
||||
|
|
|
@ -32,9 +32,9 @@ func widgetSearchAndFilter(widget *Widget, hvars interface{}) (out string, err e
|
|||
}
|
||||
|
||||
for _, fid := range canSee {
|
||||
forum := Forums.DirtyGet(fid)
|
||||
if forum.ParentID == 0 && forum.Name != "" && forum.Active {
|
||||
forums = append(forums, filterForum{forum, (header.Zone == "view_forum" || header.Zone == "topics") && header.ZoneID == forum.ID})
|
||||
f := Forums.DirtyGet(fid)
|
||||
if f.ParentID == 0 && f.Name != "" && f.Active {
|
||||
forums = append(forums, filterForum{f, (header.Zone == "view_forum" || header.Zone == "topics") && header.ZoneID == f.ID})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
185
common/ws_hub.go
185
common/ws_hub.go
|
@ -2,9 +2,9 @@ package common
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
"log"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
@ -38,7 +38,7 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
func (hub *WsHubImpl) Start() {
|
||||
func (h *WsHubImpl) Start() {
|
||||
log.Print("Setting up the WebSocket ticks")
|
||||
ticker := time.NewTicker(time.Minute * 5)
|
||||
defer func() {
|
||||
|
@ -47,9 +47,9 @@ func (hub *WsHubImpl) Start() {
|
|||
|
||||
go func() {
|
||||
for {
|
||||
item := func(lock *sync.RWMutex, userMap map[int]*WSUser) {
|
||||
lock.RLock()
|
||||
defer lock.RUnlock()
|
||||
item := func(l *sync.RWMutex, userMap map[int]*WSUser) {
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
// TODO: Copy to temporary slice for less contention?
|
||||
for _, user := range userMap {
|
||||
user.Ping()
|
||||
|
@ -57,26 +57,26 @@ func (hub *WsHubImpl) Start() {
|
|||
}
|
||||
select {
|
||||
case <-ticker.C:
|
||||
item(&hub.evenUserLock, hub.evenOnlineUsers)
|
||||
item(&hub.oddUserLock, hub.oddOnlineUsers)
|
||||
item(&h.evenUserLock, h.evenOnlineUsers)
|
||||
item(&h.oddUserLock, h.oddOnlineUsers)
|
||||
}
|
||||
}
|
||||
}()
|
||||
if Config.DisableLiveTopicList {
|
||||
return
|
||||
}
|
||||
hub.lastTick = time.Now()
|
||||
AddScheduledSecondTask(hub.Tick)
|
||||
h.lastTick = time.Now()
|
||||
AddScheduledSecondTask(h.Tick)
|
||||
}
|
||||
|
||||
// This Tick is separate from the admin one, as we want to process that in parallel with this due to the blocking calls to gopsutil
|
||||
func (hub *WsHubImpl) Tick() error {
|
||||
return wsTopicListTick(hub)
|
||||
func (h *WsHubImpl) Tick() error {
|
||||
return wsTopicListTick(h)
|
||||
}
|
||||
|
||||
func wsTopicListTick(hub *WsHubImpl) error {
|
||||
func wsTopicListTick(h *WsHubImpl) error {
|
||||
// Avoid hitting GetList when the topic list hasn't changed
|
||||
if !TopicListThaw.Thawed() && hub.lastTopicList != nil {
|
||||
if !TopicListThaw.Thawed() && h.lastTopicList != nil {
|
||||
return nil
|
||||
}
|
||||
tickStart := time.Now()
|
||||
|
@ -85,12 +85,12 @@ func wsTopicListTick(hub *WsHubImpl) error {
|
|||
// TODO: Get a topic list method which strips stickies?
|
||||
tList, _, _, err := TopicList.GetList(1, "", nil)
|
||||
if err != nil {
|
||||
hub.lastTick = tickStart
|
||||
h.lastTick = tickStart
|
||||
return err // TODO: Do we get ErrNoRows here?
|
||||
}
|
||||
defer func() {
|
||||
hub.lastTick = tickStart
|
||||
hub.lastTopicList = tList
|
||||
h.lastTick = tickStart
|
||||
h.lastTopicList = tList
|
||||
}()
|
||||
if len(tList) == 0 {
|
||||
return nil
|
||||
|
@ -99,11 +99,11 @@ func wsTopicListTick(hub *WsHubImpl) error {
|
|||
// TODO: Optimise this by only sniffing the top non-sticky
|
||||
// TODO: Optimise this by getting back an unsorted list so we don't have to hop around the stickies
|
||||
// TODO: Add support for new stickies / replies to them
|
||||
if len(tList) == len(hub.lastTopicList) {
|
||||
var hasItem = false
|
||||
if len(tList) == len(h.lastTopicList) {
|
||||
hasItem := false
|
||||
for j, tItem := range tList {
|
||||
if !tItem.Sticky {
|
||||
if tItem.ID != hub.lastTopicList[j].ID || !tItem.LastReplyAt.Equal(hub.lastTopicList[j].LastReplyAt) {
|
||||
if tItem.ID != h.lastTopicList[j].ID || !tItem.LastReplyAt.Equal(h.lastTopicList[j].LastReplyAt) {
|
||||
hasItem = true
|
||||
}
|
||||
}
|
||||
|
@ -122,9 +122,9 @@ func wsTopicListTick(hub *WsHubImpl) error {
|
|||
}
|
||||
|
||||
// Copy these over so we close this loop as fast as possible so we can release the read lock, especially if the group gets are backed by calls to the database
|
||||
var groupIDs = make(map[int]bool)
|
||||
var currentWatchers = make([]*WSUser, len(topicListWatchers))
|
||||
var i = 0
|
||||
groupIDs := make(map[int]bool)
|
||||
currentWatchers := make([]*WSUser, len(topicListWatchers))
|
||||
i := 0
|
||||
for wsUser, _ := range topicListWatchers {
|
||||
currentWatchers[i] = wsUser
|
||||
groupIDs[wsUser.User.Group] = true
|
||||
|
@ -132,8 +132,8 @@ func wsTopicListTick(hub *WsHubImpl) error {
|
|||
}
|
||||
topicListMutex.RUnlock()
|
||||
|
||||
var groups = make(map[int]*Group)
|
||||
var canSeeMap = make(map[string][]int)
|
||||
groups := make(map[int]*Group)
|
||||
canSeeMap := make(map[string][]int)
|
||||
for groupID, _ := range groupIDs {
|
||||
group, err := Groups.Get(groupID)
|
||||
if err != nil {
|
||||
|
@ -142,14 +142,14 @@ func wsTopicListTick(hub *WsHubImpl) error {
|
|||
}
|
||||
groups[group.ID] = group
|
||||
|
||||
var canSee = make([]byte, len(group.CanSee))
|
||||
canSee := make([]byte, len(group.CanSee))
|
||||
for i, item := range group.CanSee {
|
||||
canSee[i] = byte(item)
|
||||
}
|
||||
canSeeMap[string(canSee)] = group.CanSee
|
||||
}
|
||||
|
||||
var canSeeRenders = make(map[string][]byte)
|
||||
canSeeRenders := make(map[string][]byte)
|
||||
for name, canSee := range canSeeMap {
|
||||
topicList, forumList, _, err := TopicList.GetListByCanSee(canSee, 1, "", nil)
|
||||
if err != nil {
|
||||
|
@ -161,7 +161,7 @@ func wsTopicListTick(hub *WsHubImpl) error {
|
|||
_ = forumList // Might use this later after we get the base feature working
|
||||
|
||||
if topicList[0].Sticky {
|
||||
var lastSticky = 0
|
||||
lastSticky := 0
|
||||
for i, row := range topicList {
|
||||
if !row.Sticky {
|
||||
lastSticky = i
|
||||
|
@ -175,7 +175,7 @@ func wsTopicListTick(hub *WsHubImpl) error {
|
|||
}
|
||||
|
||||
// TODO: Compare to previous tick to eliminate unnecessary work and data
|
||||
var wsTopicList = make([]*WsTopicsRow, len(topicList))
|
||||
wsTopicList := make([]*WsTopicsRow, len(topicList))
|
||||
for i, topicRow := range topicList {
|
||||
wsTopicList[i] = topicRow.WebSockets()
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ func wsTopicListTick(hub *WsHubImpl) error {
|
|||
//fmt.Println("writing to the clients")
|
||||
for _, wsUser := range currentWatchers {
|
||||
group := groups[wsUser.User.Group]
|
||||
var canSee = make([]byte, len(group.CanSee))
|
||||
canSee := make([]byte, len(group.CanSee))
|
||||
for i, item := range group.CanSee {
|
||||
canSee[i] = byte(item)
|
||||
}
|
||||
|
@ -213,38 +213,39 @@ func wsTopicListTick(hub *WsHubImpl) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (hub *WsHubImpl) GuestCount() int {
|
||||
defer hub.GuestLock.RUnlock()
|
||||
hub.GuestLock.RLock()
|
||||
return len(hub.OnlineGuests)
|
||||
func (h *WsHubImpl) GuestCount() int {
|
||||
h.GuestLock.RLock()
|
||||
defer h.GuestLock.RUnlock()
|
||||
return len(h.OnlineGuests)
|
||||
}
|
||||
|
||||
func (hub *WsHubImpl) UserCount() (count int) {
|
||||
hub.evenUserLock.RLock()
|
||||
count += len(hub.evenOnlineUsers)
|
||||
hub.evenUserLock.RUnlock()
|
||||
hub.oddUserLock.RLock()
|
||||
count += len(hub.oddOnlineUsers)
|
||||
hub.oddUserLock.RUnlock()
|
||||
func (h *WsHubImpl) UserCount() (count int) {
|
||||
h.evenUserLock.RLock()
|
||||
count += len(h.evenOnlineUsers)
|
||||
h.evenUserLock.RUnlock()
|
||||
h.oddUserLock.RLock()
|
||||
count += len(h.oddOnlineUsers)
|
||||
h.oddUserLock.RUnlock()
|
||||
return count
|
||||
}
|
||||
|
||||
func (hub *WsHubImpl) HasUser(uid int) (exists bool) {
|
||||
hub.evenUserLock.RLock()
|
||||
_, exists = hub.evenOnlineUsers[uid]
|
||||
hub.evenUserLock.RUnlock()
|
||||
func (h *WsHubImpl) HasUser(uid int) (exists bool) {
|
||||
h.evenUserLock.RLock()
|
||||
_, exists = h.evenOnlineUsers[uid]
|
||||
h.evenUserLock.RUnlock()
|
||||
if exists {
|
||||
return exists
|
||||
}
|
||||
hub.oddUserLock.RLock()
|
||||
_, exists = hub.oddOnlineUsers[uid]
|
||||
hub.oddUserLock.RUnlock()
|
||||
h.oddUserLock.RLock()
|
||||
_, exists = h.oddOnlineUsers[uid]
|
||||
h.oddUserLock.RUnlock()
|
||||
return exists
|
||||
}
|
||||
|
||||
func (hub *WsHubImpl) broadcastMessage(msg string) error {
|
||||
var userLoop = func(users map[int]*WSUser, mutex *sync.RWMutex) error {
|
||||
defer mutex.RUnlock()
|
||||
func (h *WsHubImpl) broadcastMessage(msg string) error {
|
||||
userLoop := func(users map[int]*WSUser, m *sync.RWMutex) error {
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
for _, wsUser := range users {
|
||||
err := wsUser.WriteAll(msg)
|
||||
if err != nil {
|
||||
|
@ -254,25 +255,23 @@ func (hub *WsHubImpl) broadcastMessage(msg string) error {
|
|||
return nil
|
||||
}
|
||||
// TODO: Can we move this RLock inside the closure safely?
|
||||
hub.evenUserLock.RLock()
|
||||
err := userLoop(hub.evenOnlineUsers, &hub.evenUserLock)
|
||||
err := userLoop(h.evenOnlineUsers, &h.evenUserLock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hub.oddUserLock.RLock()
|
||||
return userLoop(hub.oddOnlineUsers, &hub.oddUserLock)
|
||||
return userLoop(h.oddOnlineUsers, &h.oddUserLock)
|
||||
}
|
||||
|
||||
func (hub *WsHubImpl) getUser(uid int) (wsUser *WSUser, err error) {
|
||||
func (h *WsHubImpl) getUser(uid int) (wsUser *WSUser, err error) {
|
||||
var ok bool
|
||||
if uid%2 == 0 {
|
||||
hub.evenUserLock.RLock()
|
||||
wsUser, ok = hub.evenOnlineUsers[uid]
|
||||
hub.evenUserLock.RUnlock()
|
||||
h.evenUserLock.RLock()
|
||||
wsUser, ok = h.evenOnlineUsers[uid]
|
||||
h.evenUserLock.RUnlock()
|
||||
} else {
|
||||
hub.oddUserLock.RLock()
|
||||
wsUser, ok = hub.oddOnlineUsers[uid]
|
||||
hub.oddUserLock.RUnlock()
|
||||
h.oddUserLock.RLock()
|
||||
wsUser, ok = h.oddOnlineUsers[uid]
|
||||
h.oddUserLock.RUnlock()
|
||||
}
|
||||
if !ok {
|
||||
return nil, errWsNouser
|
||||
|
@ -281,20 +280,20 @@ func (hub *WsHubImpl) getUser(uid int) (wsUser *WSUser, err error) {
|
|||
}
|
||||
|
||||
// Warning: For efficiency, some of the *WSUsers may be nil pointers, DO NOT EXPORT
|
||||
func (hub *WsHubImpl) getUsers(uids []int) (wsUsers []*WSUser, err error) {
|
||||
func (h *WsHubImpl) getUsers(uids []int) (wsUsers []*WSUser, err error) {
|
||||
if len(uids) == 0 {
|
||||
return nil, errWsNouser
|
||||
}
|
||||
var appender = func(lock *sync.RWMutex, users map[int]*WSUser) {
|
||||
lock.RLock()
|
||||
defer lock.RUnlock()
|
||||
appender := func(l *sync.RWMutex, users map[int]*WSUser) {
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
// We don't want to keep a lock on this for too long, so we'll accept some nil pointers
|
||||
for _, uid := range uids {
|
||||
wsUsers = append(wsUsers, users[uid])
|
||||
}
|
||||
}
|
||||
appender(&hub.evenUserLock, hub.evenOnlineUsers)
|
||||
appender(&hub.oddUserLock, hub.oddOnlineUsers)
|
||||
appender(&h.evenUserLock, h.evenOnlineUsers)
|
||||
appender(&h.oddUserLock, h.oddOnlineUsers)
|
||||
if len(wsUsers) == 0 {
|
||||
return nil, errWsNouser
|
||||
}
|
||||
|
@ -302,32 +301,32 @@ func (hub *WsHubImpl) getUsers(uids []int) (wsUsers []*WSUser, err error) {
|
|||
}
|
||||
|
||||
// For Widget WOL, please avoid using this as it might wind up being really long and slow without the right safeguards
|
||||
func (hub *WsHubImpl) AllUsers() (users []*User) {
|
||||
var appender = func(lock *sync.RWMutex, userMap map[int]*WSUser) {
|
||||
lock.RLock()
|
||||
defer lock.RUnlock()
|
||||
func (h *WsHubImpl) AllUsers() (users []*User) {
|
||||
appender := func(l *sync.RWMutex, userMap map[int]*WSUser) {
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
for _, user := range userMap {
|
||||
users = append(users, user.User)
|
||||
}
|
||||
}
|
||||
appender(&hub.evenUserLock, hub.evenOnlineUsers)
|
||||
appender(&hub.oddUserLock, hub.oddOnlineUsers)
|
||||
appender(&h.evenUserLock, h.evenOnlineUsers)
|
||||
appender(&h.oddUserLock, h.oddOnlineUsers)
|
||||
return users
|
||||
}
|
||||
|
||||
func (hub *WsHubImpl) removeUser(uid int) {
|
||||
func (h *WsHubImpl) removeUser(uid int) {
|
||||
if uid%2 == 0 {
|
||||
hub.evenUserLock.Lock()
|
||||
delete(hub.evenOnlineUsers, uid)
|
||||
hub.evenUserLock.Unlock()
|
||||
h.evenUserLock.Lock()
|
||||
delete(h.evenOnlineUsers, uid)
|
||||
h.evenUserLock.Unlock()
|
||||
} else {
|
||||
hub.oddUserLock.Lock()
|
||||
delete(hub.oddOnlineUsers, uid)
|
||||
hub.oddUserLock.Unlock()
|
||||
h.oddUserLock.Lock()
|
||||
delete(h.oddOnlineUsers, uid)
|
||||
h.oddUserLock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (hub *WsHubImpl) AddConn(user User, conn *websocket.Conn) (*WSUser, error) {
|
||||
func (h *WsHubImpl) AddConn(user User, conn *websocket.Conn) (*WSUser, error) {
|
||||
if user.ID == 0 {
|
||||
wsUser := new(WSUser)
|
||||
wsUser.User = new(User)
|
||||
|
@ -348,11 +347,11 @@ func (hub *WsHubImpl) AddConn(user User, conn *websocket.Conn) (*WSUser, error)
|
|||
var mutex *sync.RWMutex
|
||||
var theMap map[int]*WSUser
|
||||
if user.ID%2 == 0 {
|
||||
mutex = &hub.evenUserLock
|
||||
theMap = hub.evenOnlineUsers
|
||||
mutex = &h.evenUserLock
|
||||
theMap = h.evenOnlineUsers
|
||||
} else {
|
||||
mutex = &hub.oddUserLock
|
||||
theMap = hub.oddOnlineUsers
|
||||
mutex = &h.oddUserLock
|
||||
theMap = h.oddOnlineUsers
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
|
@ -370,25 +369,25 @@ func (hub *WsHubImpl) AddConn(user User, conn *websocket.Conn) (*WSUser, error)
|
|||
return wsUser, nil
|
||||
}
|
||||
|
||||
func (hub *WsHubImpl) RemoveConn(wsUser *WSUser, conn *websocket.Conn) {
|
||||
func (h *WsHubImpl) RemoveConn(wsUser *WSUser, conn *websocket.Conn) {
|
||||
wsUser.RemoveSocket(conn)
|
||||
wsUser.Lock()
|
||||
if len(wsUser.Sockets) == 0 {
|
||||
hub.removeUser(wsUser.User.ID)
|
||||
h.removeUser(wsUser.User.ID)
|
||||
}
|
||||
wsUser.Unlock()
|
||||
}
|
||||
|
||||
func (hub *WsHubImpl) PushMessage(targetUser int, msg string) error {
|
||||
wsUser, err := hub.getUser(targetUser)
|
||||
func (h *WsHubImpl) PushMessage(targetUser int, msg string) error {
|
||||
wsUser, err := h.getUser(targetUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return wsUser.WriteAll(msg)
|
||||
}
|
||||
|
||||
func (hub *WsHubImpl) pushAlert(targetUser int, alert Alert) error {
|
||||
wsUser, err := hub.getUser(targetUser)
|
||||
func (h *WsHubImpl) pushAlert(targetUser int, alert Alert) error {
|
||||
wsUser, err := h.getUser(targetUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -399,8 +398,8 @@ func (hub *WsHubImpl) pushAlert(targetUser int, alert Alert) error {
|
|||
return wsUser.WriteAll(astr)
|
||||
}
|
||||
|
||||
func (hub *WsHubImpl) pushAlerts(users []int, alert Alert) error {
|
||||
wsUsers, err := hub.getUsers(users)
|
||||
func (h *WsHubImpl) pushAlerts(users []int, alert Alert) error {
|
||||
wsUsers, err := h.getUsers(users)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@ type WSUserSocket struct {
|
|||
Page string
|
||||
}
|
||||
|
||||
func (wsUser *WSUser) Ping() error {
|
||||
for _, socket := range wsUser.Sockets {
|
||||
func (u *WSUser) Ping() error {
|
||||
for _, socket := range u.Sockets {
|
||||
if socket == nil {
|
||||
continue
|
||||
}
|
||||
|
@ -36,9 +36,9 @@ func (wsUser *WSUser) Ping() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (wsUser *WSUser) WriteAll(msg string) error {
|
||||
func (u *WSUser) WriteAll(msg string) error {
|
||||
msgbytes := []byte(msg)
|
||||
for _, socket := range wsUser.Sockets {
|
||||
for _, socket := range u.Sockets {
|
||||
if socket == nil {
|
||||
continue
|
||||
}
|
||||
|
@ -52,14 +52,14 @@ func (wsUser *WSUser) WriteAll(msg string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (wsUser *WSUser) WriteToPage(msg string, page string) error {
|
||||
return wsUser.WriteToPageBytes([]byte(msg), page)
|
||||
func (u *WSUser) WriteToPage(msg string, page string) error {
|
||||
return u.WriteToPageBytes([]byte(msg), page)
|
||||
}
|
||||
|
||||
// Inefficient as it looks for sockets for a page even if there are none
|
||||
func (wsUser *WSUser) WriteToPageBytes(msg []byte, page string) error {
|
||||
func (u *WSUser) WriteToPageBytes(msg []byte, page string) error {
|
||||
var success bool
|
||||
for _, socket := range wsUser.Sockets {
|
||||
for _, socket := range u.Sockets {
|
||||
if socket == nil {
|
||||
continue
|
||||
}
|
||||
|
@ -80,34 +80,34 @@ func (wsUser *WSUser) WriteToPageBytes(msg []byte, page string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (wsUser *WSUser) AddSocket(conn *websocket.Conn, page string) {
|
||||
wsUser.Lock()
|
||||
func (u *WSUser) AddSocket(conn *websocket.Conn, page string) {
|
||||
u.Lock()
|
||||
// If the number of the sockets is small, then we can keep the size of the slice mostly static and just walk through it looking for empty slots
|
||||
if len(wsUser.Sockets) < 6 {
|
||||
for i, socket := range wsUser.Sockets {
|
||||
if len(u.Sockets) < 6 {
|
||||
for i, socket := range u.Sockets {
|
||||
if socket == nil {
|
||||
wsUser.Sockets[i] = &WSUserSocket{conn, page}
|
||||
wsUser.Unlock()
|
||||
//fmt.Printf("%+v\n", wsUser.Sockets)
|
||||
u.Sockets[i] = &WSUserSocket{conn, page}
|
||||
u.Unlock()
|
||||
//fmt.Printf("%+v\n", u.Sockets)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
wsUser.Sockets = append(wsUser.Sockets, &WSUserSocket{conn, page})
|
||||
//fmt.Printf("%+v\n", wsUser.Sockets)
|
||||
wsUser.Unlock()
|
||||
u.Sockets = append(u.Sockets, &WSUserSocket{conn, page})
|
||||
//fmt.Printf("%+v\n", u.Sockets)
|
||||
u.Unlock()
|
||||
}
|
||||
|
||||
func (wsUser *WSUser) RemoveSocket(conn *websocket.Conn) {
|
||||
wsUser.Lock()
|
||||
if len(wsUser.Sockets) < 6 {
|
||||
for i, socket := range wsUser.Sockets {
|
||||
func (u *WSUser) RemoveSocket(conn *websocket.Conn) {
|
||||
u.Lock()
|
||||
if len(u.Sockets) < 6 {
|
||||
for i, socket := range u.Sockets {
|
||||
if socket == nil {
|
||||
continue
|
||||
}
|
||||
if socket.conn == conn {
|
||||
wsUser.Sockets[i] = nil
|
||||
wsUser.Unlock()
|
||||
u.Sockets[i] = nil
|
||||
u.Unlock()
|
||||
//fmt.Printf("%+v\n", wsUser.Sockets)
|
||||
return
|
||||
}
|
||||
|
@ -115,25 +115,25 @@ func (wsUser *WSUser) RemoveSocket(conn *websocket.Conn) {
|
|||
}
|
||||
|
||||
var key int
|
||||
for i, socket := range wsUser.Sockets {
|
||||
for i, socket := range u.Sockets {
|
||||
if socket.conn == conn {
|
||||
key = i
|
||||
break
|
||||
}
|
||||
}
|
||||
wsUser.Sockets = append(wsUser.Sockets[:key], wsUser.Sockets[key+1:]...)
|
||||
//fmt.Printf("%+v\n", wsUser.Sockets)
|
||||
u.Sockets = append(u.Sockets[:key], u.Sockets[key+1:]...)
|
||||
//fmt.Printf("%+v\n", u.Sockets)
|
||||
|
||||
wsUser.Unlock()
|
||||
u.Unlock()
|
||||
}
|
||||
|
||||
func (wsUser *WSUser) SetPageForSocket(conn *websocket.Conn, page string) error {
|
||||
func (u *WSUser) SetPageForSocket(conn *websocket.Conn, page string) error {
|
||||
if conn == nil {
|
||||
return ErrInvalidSocket
|
||||
}
|
||||
|
||||
wsUser.Lock()
|
||||
for _, socket := range wsUser.Sockets {
|
||||
u.Lock()
|
||||
for _, socket := range u.Sockets {
|
||||
if socket == nil {
|
||||
continue
|
||||
}
|
||||
|
@ -141,15 +141,15 @@ func (wsUser *WSUser) SetPageForSocket(conn *websocket.Conn, page string) error
|
|||
socket.Page = page
|
||||
}
|
||||
}
|
||||
wsUser.Unlock()
|
||||
u.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wsUser *WSUser) InPage(page string) bool {
|
||||
wsUser.Lock()
|
||||
defer wsUser.Unlock()
|
||||
for _, socket := range wsUser.Sockets {
|
||||
func (u *WSUser) InPage(page string) bool {
|
||||
u.Lock()
|
||||
defer u.Unlock()
|
||||
for _, socket := range u.Sockets {
|
||||
if socket == nil {
|
||||
continue
|
||||
}
|
||||
|
@ -160,10 +160,10 @@ func (wsUser *WSUser) InPage(page string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (wsUser *WSUser) FinalizePage(page string, handle func()) {
|
||||
wsUser.Lock()
|
||||
defer wsUser.Unlock()
|
||||
for _, socket := range wsUser.Sockets {
|
||||
func (u *WSUser) FinalizePage(page string, handle func()) {
|
||||
u.Lock()
|
||||
defer u.Unlock()
|
||||
for _, socket := range u.Sockets {
|
||||
if socket == nil {
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ func SitemapXml(w http.ResponseWriter, r *http.Request) c.RouteError {
|
|||
if c.Site.EnableSsl {
|
||||
sslBit = "s"
|
||||
}
|
||||
var sitemapItem = func(path string) {
|
||||
sitemapItem := func(path string) {
|
||||
w.Write([]byte(`<sitemap>
|
||||
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
|
||||
</sitemap>
|
||||
|
@ -72,10 +72,10 @@ var fuzzySitemapRoutes = map[string]FuzzyRoute{
|
|||
}
|
||||
|
||||
func sitemapSwitch(w http.ResponseWriter, r *http.Request) c.RouteError {
|
||||
var path = r.URL.Path[len("/sitemaps/"):]
|
||||
path := r.URL.Path[len("/sitemaps/"):]
|
||||
for name, fuzzy := range fuzzySitemapRoutes {
|
||||
if strings.HasPrefix(path, name) && strings.HasSuffix(path, ".xml") {
|
||||
var spath = strings.TrimPrefix(path, name)
|
||||
spath := strings.TrimPrefix(path, name)
|
||||
spath = strings.TrimSuffix(spath, ".xml")
|
||||
page, err := strconv.Atoi(spath)
|
||||
if err != nil {
|
||||
|
@ -99,7 +99,7 @@ func SitemapForums(w http.ResponseWriter, r *http.Request) c.RouteError {
|
|||
if c.Site.EnableSsl {
|
||||
sslBit = "s"
|
||||
}
|
||||
var sitemapItem = func(path string) {
|
||||
sitemapItem := func(path string) {
|
||||
w.Write([]byte(`<url>
|
||||
<loc>http` + sslBit + `://` + c.Site.URL + path + `</loc>
|
||||
</url>
|
||||
|
@ -116,9 +116,9 @@ func SitemapForums(w http.ResponseWriter, r *http.Request) c.RouteError {
|
|||
|
||||
for _, fid := range group.CanSee {
|
||||
// Avoid data races by copying the struct into something we can freely mold without worrying about breaking something somewhere else
|
||||
var forum = c.Forums.DirtyGet(fid).Copy()
|
||||
if forum.ParentID == 0 && forum.Name != "" && forum.Active {
|
||||
sitemapItem(c.BuildForumURL(c.NameToSlug(forum.Name), forum.ID))
|
||||
f := c.Forums.DirtyGet(fid).Copy()
|
||||
if f.ParentID == 0 && f.Name != "" && f.Active {
|
||||
sitemapItem(c.BuildForumURL(c.NameToSlug(f.Name), f.ID))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ func SitemapTopics(w http.ResponseWriter, r *http.Request) c.RouteError {
|
|||
if c.Site.EnableSsl {
|
||||
sslBit = "s"
|
||||
}
|
||||
var sitemapItem = func(path string) {
|
||||
sitemapItem := func(path string) {
|
||||
w.Write([]byte(`<sitemap>
|
||||
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
|
||||
</sitemap>
|
||||
|
@ -158,7 +158,7 @@ func SitemapTopics(w http.ResponseWriter, r *http.Request) c.RouteError {
|
|||
return c.InternalErrorXML(err, w, r)
|
||||
}
|
||||
|
||||
var pageCount = topicCount / sitemapPageCap
|
||||
pageCount := topicCount / sitemapPageCap
|
||||
//log.Print("topicCount", topicCount)
|
||||
//log.Print("pageCount", pageCount)
|
||||
writeXMLHeader(w, r)
|
||||
|
@ -201,7 +201,7 @@ func SitemapTopic(w http.ResponseWriter, r *http.Request, page int) c.RouteError
|
|||
return c.InternalErrorXML(err, w, r)
|
||||
}
|
||||
|
||||
var pageCount = topicCount / sitemapPageCap
|
||||
pageCount := topicCount / sitemapPageCap
|
||||
//log.Print("topicCount", topicCount)
|
||||
//log.Print("pageCount", pageCount)
|
||||
//log.Print("page",page)
|
||||
|
@ -243,7 +243,6 @@ func APIMe(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
|||
w.Header().Set("Cache-Control", "private")
|
||||
|
||||
me := JsonMe{(&user).Me(), MeSite{c.Site.MaxRequestSize}}
|
||||
|
||||
jsonBytes, err := json.Marshal(me)
|
||||
if err != nil {
|
||||
return c.InternalErrorJS(err, w, r)
|
||||
|
@ -258,13 +257,13 @@ func OpenSearchXml(w http.ResponseWriter, r *http.Request) c.RouteError {
|
|||
if c.Site.EnableSsl {
|
||||
furl += "s"
|
||||
}
|
||||
furl += "://"+c.Site.URL
|
||||
furl += "://" + c.Site.URL
|
||||
w.Write([]byte(`<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
|
||||
<ShortName>`+c.Site.Name+`</ShortName>
|
||||
<ShortName>` + c.Site.Name + `</ShortName>
|
||||
<InputEncoding>UTF-8</InputEncoding>
|
||||
<Url type="text/html" template="`+furl+`/topics/?q={searchTerms}" />
|
||||
<Url type="application/opensearchdescription+xml" rel="self" template="`+furl+`/opensearch.xml" />
|
||||
<moz:SearchForm>`+furl+`</moz:SearchForm>
|
||||
<Url type="text/html" template="` + furl + `/topics/?q={searchTerms}" />
|
||||
<Url type="application/opensearchdescription+xml" rel="self" template="` + furl + `/opensearch.xml" />
|
||||
<moz:SearchForm>` + furl + `</moz:SearchForm>
|
||||
</OpenSearchDescription>`))
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -35,15 +35,15 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
|
|||
return c.LocalError("Bad extension", w, r, user)
|
||||
}
|
||||
|
||||
sectionID, err := strconv.Atoi(r.FormValue("sid"))
|
||||
sid, err := strconv.Atoi(r.FormValue("sid"))
|
||||
if err != nil {
|
||||
return c.LocalError("The sectionID is not an integer", w, r, user)
|
||||
return c.LocalError("The sid is not an integer", w, r, user)
|
||||
}
|
||||
sectionTable := r.FormValue("stype")
|
||||
|
||||
var originTable string
|
||||
var originID, uploadedBy int
|
||||
err = attachmentStmts.get.QueryRow(filename, sectionID, sectionTable).Scan(§ionID, §ionTable, &originID, &originTable, &uploadedBy, &filename)
|
||||
err = attachmentStmts.get.QueryRow(filename, sid, sectionTable).Scan(&sid, §ionTable, &originID, &originTable, &uploadedBy, &filename)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.NotFound(w, r, nil)
|
||||
} else if err != nil {
|
||||
|
@ -51,7 +51,7 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
|
|||
}
|
||||
|
||||
if sectionTable == "forums" {
|
||||
_, ferr := c.SimpleForumUserCheck(w, r, &user, sectionID)
|
||||
_, ferr := c.SimpleForumUserCheck(w, r, &user, sid)
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
|
|||
w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(c.Year)))
|
||||
} else {
|
||||
guest := c.GuestUser
|
||||
_, ferr := c.SimpleForumUserCheck(w, r, &guest, sectionID)
|
||||
_, ferr := c.SimpleForumUserCheck(w, r, &guest, sid)
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
|
||||
c "github.com/Azareal/Gosora/common"
|
||||
"github.com/Azareal/Gosora/common/counters"
|
||||
"github.com/Azareal/Gosora/common/phrases"
|
||||
"github.com/Azareal/Gosora/query_gen"
|
||||
p "github.com/Azareal/Gosora/common/phrases"
|
||||
qgen "github.com/Azareal/Gosora/query_gen"
|
||||
)
|
||||
|
||||
type ForumStmts struct {
|
||||
|
@ -32,7 +32,7 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
|
|||
page, _ := strconv.Atoi(r.FormValue("page"))
|
||||
_, fid, err := ParseSEOURL(sfid)
|
||||
if err != nil {
|
||||
return c.SimpleError(phrases.GetErrorPhrase("url_id_must_be_integer"),w,r,header)
|
||||
return c.SimpleError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, header)
|
||||
}
|
||||
|
||||
ferr := c.ForumUserCheck(header, w, r, &user, fid)
|
||||
|
@ -66,23 +66,23 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
|
|||
|
||||
// TODO: Use something other than TopicsRow as we don't need to store the forum name and link on each and every topic item?
|
||||
var topicList []*c.TopicsRow
|
||||
var reqUserList = make(map[int]bool)
|
||||
reqUserList := make(map[int]bool)
|
||||
for rows.Next() {
|
||||
var topicItem = c.TopicsRow{ID: 0}
|
||||
err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.IsClosed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.LastReplyAt, &topicItem.LastReplyBy, &topicItem.LastReplyID, &topicItem.ParentID, &topicItem.ViewCount, &topicItem.PostCount, &topicItem.LikeCount)
|
||||
t := c.TopicsRow{ID: 0}
|
||||
err := rows.Scan(&t.ID, &t.Title, &t.Content, &t.CreatedBy, &t.IsClosed, &t.Sticky, &t.CreatedAt, &t.LastReplyAt, &t.LastReplyBy, &t.LastReplyID, &t.ParentID, &t.ViewCount, &t.PostCount, &t.LikeCount)
|
||||
if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
}
|
||||
|
||||
topicItem.Link = c.BuildTopicURL(c.NameToSlug(topicItem.Title), topicItem.ID)
|
||||
t.Link = c.BuildTopicURL(c.NameToSlug(t.Title), t.ID)
|
||||
// TODO: Create a specialised function with a bit less overhead for getting the last page for a post count
|
||||
_, _, lastPage := c.PageOffset(topicItem.PostCount, 1, c.Config.ItemsPerPage)
|
||||
topicItem.LastPage = lastPage
|
||||
_, _, lastPage := c.PageOffset(t.PostCount, 1, c.Config.ItemsPerPage)
|
||||
t.LastPage = lastPage
|
||||
|
||||
header.Hooks.VhookNoRet("forum_trow_assign", &topicItem, &forum)
|
||||
topicList = append(topicList, &topicItem)
|
||||
reqUserList[topicItem.CreatedBy] = true
|
||||
reqUserList[topicItem.LastReplyBy] = true
|
||||
header.Hooks.VhookNoRet("forum_trow_assign", &t, &forum)
|
||||
topicList = append(topicList, &t)
|
||||
reqUserList[t.CreatedBy] = true
|
||||
reqUserList[t.LastReplyBy] = true
|
||||
}
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
|
@ -90,7 +90,7 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
|
|||
}
|
||||
|
||||
// Convert the user ID map to a slice, then bulk load the users
|
||||
var idSlice = make([]int, len(reqUserList))
|
||||
idSlice := make([]int, len(reqUserList))
|
||||
var i int
|
||||
for userID := range reqUserList {
|
||||
idSlice[i] = userID
|
||||
|
@ -105,9 +105,9 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
|
|||
|
||||
// Second pass to the add the user data
|
||||
// TODO: Use a pointer to TopicsRow instead of TopicsRow itself?
|
||||
for _, topicItem := range topicList {
|
||||
topicItem.Creator = userList[topicItem.CreatedBy]
|
||||
topicItem.LastUser = userList[topicItem.LastReplyBy]
|
||||
for _, t := range topicList {
|
||||
t.Creator = userList[t.CreatedBy]
|
||||
t.LastUser = userList[t.LastReplyBy]
|
||||
}
|
||||
header.Zone = "view_forum"
|
||||
header.ZoneID = forum.ID
|
||||
|
@ -128,8 +128,8 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
|
|||
if tmpl == "" {
|
||||
ferr = renderTemplate("forum", w, r, header, pi)
|
||||
} else {
|
||||
tmpl = "forum_"+tmpl
|
||||
err = renderTemplate3(tmpl, tmpl,w, r, header, pi)
|
||||
tmpl = "forum_" + tmpl
|
||||
err = renderTemplate3(tmpl, tmpl, w, r, header, pi)
|
||||
if err != nil {
|
||||
ferr = renderTemplate("forum", w, r, header, pi)
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ func IPSearch(w http.ResponseWriter, r *http.Request, user c.User, header *c.Hea
|
|||
}
|
||||
|
||||
// TODO: Reject IP Addresses with illegal characters
|
||||
var ip = c.SanitiseSingleLine(r.FormValue("ip"))
|
||||
ip := c.SanitiseSingleLine(r.FormValue("ip"))
|
||||
uids, err := c.IPSearch.Lookup(ip)
|
||||
if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
|
|
|
@ -81,7 +81,6 @@ func PagesEdit(w http.ResponseWriter, r *http.Request, user c.User, spid string)
|
|||
if err != nil {
|
||||
return c.LocalError("Page ID needs to be an integer", w, r, user)
|
||||
}
|
||||
|
||||
page, err := c.Pages.Get(pid)
|
||||
if err == sql.ErrNoRows {
|
||||
return c.NotFound(w, r, basePage.Header)
|
||||
|
@ -103,7 +102,6 @@ func PagesEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid s
|
|||
if err != nil {
|
||||
return c.LocalError("Page ID needs to be an integer", w, r, user)
|
||||
}
|
||||
|
||||
pname := r.PostFormValue("name")
|
||||
if pname == "" {
|
||||
return c.LocalError("No name was provided for this page", w, r, user)
|
||||
|
@ -143,7 +141,6 @@ func PagesDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid
|
|||
if err != nil {
|
||||
return c.LocalError("Page ID needs to be an integer", w, r, user)
|
||||
}
|
||||
|
||||
err = c.Pages.Delete(pid)
|
||||
if err != nil {
|
||||
return c.InternalError(err, w, r)
|
||||
|
|
|
@ -10,8 +10,8 @@ import (
|
|||
|
||||
c "github.com/Azareal/Gosora/common"
|
||||
"github.com/Azareal/Gosora/common/counters"
|
||||
"github.com/Azareal/Gosora/common/phrases"
|
||||
"github.com/Azareal/Gosora/query_gen"
|
||||
p "github.com/Azareal/Gosora/common/phrases"
|
||||
qgen "github.com/Azareal/Gosora/query_gen"
|
||||
)
|
||||
|
||||
type ReplyStmts struct {
|
||||
|
@ -353,7 +353,7 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
|
|||
func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
||||
rid, err := strconv.Atoi(srid)
|
||||
if err != nil {
|
||||
return c.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
|
||||
return c.LocalErrorJS(p.GetErrorPhrase("id_must_be_integer"), w, r)
|
||||
}
|
||||
|
||||
reply, err := c.Rstore.Get(rid)
|
||||
|
@ -410,7 +410,7 @@ func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user c.User,
|
|||
func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
||||
rid, err := strconv.Atoi(srid)
|
||||
if err != nil {
|
||||
return c.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
|
||||
return c.LocalErrorJS(p.GetErrorPhrase("id_must_be_integer"), w, r)
|
||||
}
|
||||
|
||||
reply, err := c.Rstore.Get(rid)
|
||||
|
@ -443,7 +443,7 @@ func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, user c.
|
|||
for _, said := range saids {
|
||||
aid, err := strconv.Atoi(said)
|
||||
if err != nil {
|
||||
return c.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
|
||||
return c.LocalErrorJS(p.GetErrorPhrase("id_must_be_integer"), w, r)
|
||||
}
|
||||
rerr := deleteAttachment(w, r, user, aid, true)
|
||||
if rerr != nil {
|
||||
|
@ -574,7 +574,6 @@ func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.Use
|
|||
|
||||
func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
||||
js := (r.PostFormValue("js") == "1")
|
||||
|
||||
rid, err := strconv.Atoi(srid)
|
||||
if err != nil {
|
||||
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)
|
||||
|
|
|
@ -281,8 +281,8 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.
|
|||
|
||||
// Lock this to the forum being linked?
|
||||
// Should we always put it in strictmode when it's linked from another forum? Well, the user might end up changing their mind on what forum they want to post in and it would be a hassle, if they had to switch pages, even if it is a single click for many (exc. mobile)
|
||||
var strictmode bool
|
||||
header.Hooks.VhookNoRet("topic_create_pre_loop", w, r, fid, &header, &user, &strictmode)
|
||||
var strict bool
|
||||
header.Hooks.VhookNoRet("topic_create_pre_loop", w, r, fid, &header, &user, &strict)
|
||||
|
||||
// TODO: Re-add support for plugin_guilds
|
||||
var forumList []c.Forum
|
||||
|
@ -306,7 +306,7 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.
|
|||
// TODO: plugin_superadmin needs to be able to override this loop. Skip flag on topic_create_pre_loop?
|
||||
for _, ffid := range canSee {
|
||||
// TODO: Surely, there's a better way of doing this. I've added it in for now to support plugin_guilds, but we really need to clean this up
|
||||
if strictmode && ffid != fid {
|
||||
if strict && ffid != fid {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -339,10 +339,10 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
|
|||
return c.NoPermissions(w, r, user)
|
||||
}
|
||||
|
||||
topicName := c.SanitiseSingleLine(r.PostFormValue("topic-name"))
|
||||
tname := c.SanitiseSingleLine(r.PostFormValue("topic-name"))
|
||||
content := c.PreparseMessage(r.PostFormValue("topic-content"))
|
||||
// TODO: Fully parse the post and store it in the parsed column
|
||||
tid, err := c.Topics.Create(fid, topicName, content, user.ID, user.LastIP)
|
||||
tid, err := c.Topics.Create(fid, tname, content, user.ID, user.LastIP)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case c.ErrNoRows:
|
||||
|
@ -362,8 +362,8 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
|
|||
return c.LocalError("Unable to load the topic", w, r, user)
|
||||
}
|
||||
if r.PostFormValue("has_poll") == "1" {
|
||||
var maxPollOptions = 10
|
||||
var pollInputItems = make(map[int]string)
|
||||
maxPollOptions := 10
|
||||
pollInputItems := make(map[int]string)
|
||||
for key, values := range r.Form {
|
||||
for _, value := range values {
|
||||
if !strings.HasPrefix(key, "pollinputitem[") {
|
||||
|
@ -394,7 +394,7 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
|
|||
|
||||
if len(pollInputItems) > 0 {
|
||||
// Make sure the indices are sequential to avoid out of bounds issues
|
||||
var seqPollInputItems = make(map[int]string)
|
||||
seqPollInputItems := make(map[int]string)
|
||||
for i := 0; i < len(pollInputItems); i++ {
|
||||
seqPollInputItems[i] = pollInputItems[i]
|
||||
}
|
||||
|
@ -666,7 +666,7 @@ func topicActionPre(stid string, action string, w http.ResponseWriter, r *http.R
|
|||
return nil, nil, c.PreError(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
|
||||
}
|
||||
|
||||
topic, err := c.Topics.Get(tid)
|
||||
t, err := c.Topics.Get(tid)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil, c.PreError("The topic you tried to "+action+" doesn't exist.", w, r)
|
||||
} else if err != nil {
|
||||
|
@ -674,12 +674,11 @@ func topicActionPre(stid string, action string, w http.ResponseWriter, r *http.R
|
|||
}
|
||||
|
||||
// TODO: Add hooks to make use of headerLite
|
||||
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||
lite, ferr := c.SimpleForumUserCheck(w, r, &user, t.ParentID)
|
||||
if ferr != nil {
|
||||
return nil, nil, ferr
|
||||
}
|
||||
|
||||
return topic, lite, nil
|
||||
return t, lite, nil
|
||||
}
|
||||
|
||||
func topicActionPost(err error, action string, w http.ResponseWriter, r *http.Request, lite *c.HeaderLite, topic *c.Topic, user c.User) c.RouteError {
|
||||
|
@ -698,15 +697,15 @@ func topicActionPost(err error, action string, w http.ResponseWriter, r *http.Re
|
|||
return nil
|
||||
}
|
||||
|
||||
func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError {
|
||||
topic, lite, rerr := topicActionPre(stid, "unpin", w, r, user)
|
||||
func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, u c.User, stid string) c.RouteError {
|
||||
t, lite, rerr := topicActionPre(stid, "unpin", w, r, u)
|
||||
if rerr != nil {
|
||||
return rerr
|
||||
}
|
||||
if !user.Perms.ViewTopic || !user.Perms.PinTopic {
|
||||
return c.NoPermissions(w, r, user)
|
||||
if !u.Perms.ViewTopic || !u.Perms.PinTopic {
|
||||
return c.NoPermissions(w, r, u)
|
||||
}
|
||||
return topicActionPost(topic.Unstick(), "unstick", w, r, lite, topic, user)
|
||||
return topicActionPost(t.Unstick(), "unstick", w, r, lite, t, u)
|
||||
}
|
||||
|
||||
func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||
|
@ -773,15 +772,15 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
|
|||
return nil
|
||||
}
|
||||
|
||||
func UnlockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError {
|
||||
topic, lite, rerr := topicActionPre(stid, "unlock", w, r, user)
|
||||
func UnlockTopicSubmit(w http.ResponseWriter, r *http.Request, u c.User, stid string) c.RouteError {
|
||||
t, lite, rerr := topicActionPre(stid, "unlock", w, r, u)
|
||||
if rerr != nil {
|
||||
return rerr
|
||||
}
|
||||
if !user.Perms.ViewTopic || !user.Perms.CloseTopic {
|
||||
return c.NoPermissions(w, r, user)
|
||||
if !u.Perms.ViewTopic || !u.Perms.CloseTopic {
|
||||
return c.NoPermissions(w, r, u)
|
||||
}
|
||||
return topicActionPost(topic.Unlock(), "unlock", w, r, lite, topic, user)
|
||||
return topicActionPost(t.Unlock(), "unlock", w, r, lite, t, u)
|
||||
}
|
||||
|
||||
// ! JS only route
|
||||
|
@ -853,12 +852,12 @@ func MoveTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfid s
|
|||
return nil
|
||||
}
|
||||
|
||||
func addTopicAction(action string, topic *c.Topic, user c.User) error {
|
||||
err := c.ModLogs.Create(action, topic.ID, "topic", user.LastIP, user.ID)
|
||||
func addTopicAction(action string, t *c.Topic, u c.User) error {
|
||||
err := c.ModLogs.Create(action, t.ID, "topic", u.LastIP, u.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return topic.CreateActionReply(action, user.LastIP, user.ID)
|
||||
return t.CreateActionReply(action, u.LastIP, u.ID)
|
||||
}
|
||||
|
||||
// TODO: Refactor this
|
||||
|
|
Loading…
Reference in New Issue