Shortening some things.

Fix the ordering of the lock in WsHubImpl.GuestCount.
This commit is contained in:
Azareal 2019-10-02 07:06:22 +10:00
parent 85b0522955
commit ff48ec9d86
14 changed files with 232 additions and 240 deletions

View File

@ -198,7 +198,7 @@ func ReplaceForumPermsForGroupTx(tx *sql.Tx, gid int, presetSets map[int]string,
return err 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 { if err != nil {
return err 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: Refactor this and write tests for it
// TODO: We really need to improve the thread safety of this // TODO: We really need to improve the thread safety of this
func ForumPermsToGroupForumPreset(fperms *ForumPerms) string { func ForumPermsToGroupForumPreset(fp *ForumPerms) string {
if !fperms.Overrides { if !fp.Overrides {
return "default" return "default"
} }
if !fperms.ViewTopic { if !fp.ViewTopic {
return "no_access" return "no_access"
} }
canPost := (fperms.LikeItem && fperms.CreateTopic && fperms.CreateReply) canPost := (fp.LikeItem && fp.CreateTopic && fp.CreateReply)
canModerate := (canPost && fperms.EditTopic && fperms.DeleteTopic && fperms.EditReply && fperms.DeleteReply && fperms.PinTopic && fperms.CloseTopic && fperms.MoveTopic) canModerate := (canPost && fp.EditTopic && fp.DeleteTopic && fp.EditReply && fp.DeleteReply && fp.PinTopic && fp.CloseTopic && fp.MoveTopic)
if canModerate { if canModerate {
return "can_moderate" 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 { //if !canPost {
return "custom" return "custom"
//} //}
@ -244,7 +244,7 @@ func ForumPermsToGroupForumPreset(fperms *ForumPerms) string {
if canPost { if canPost {
return "can_post" 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 "read_only"
} }
return "custom" return "custom"

View File

@ -35,9 +35,9 @@ func NewSQLSearcher(acc *qgen.Accumulator) (*SQLSearcher, error) {
}, acc.FirstError() }, acc.FirstError()
} }
func (search *SQLSearcher) queryAll(q string) ([]int, error) { func (s *SQLSearcher) queryAll(q string) ([]int, error) {
var ids []int 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...) rows, err := stmt.Query(q...)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return nil return nil
@ -57,11 +57,11 @@ func (search *SQLSearcher) queryAll(q string) ([]int, error) {
return rows.Err() return rows.Err()
} }
err := run(search.queryReplies, q) err := run(s.queryReplies, q)
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = run(search.queryTopics, q, q) err = run(s.queryTopics, q, q)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -71,11 +71,11 @@ func (search *SQLSearcher) queryAll(q string) ([]int, error) {
return ids, err 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 { if len(zones) == 0 {
return nil, nil return nil, nil
} }
var run = func(rows *sql.Rows, err error) error { run := func(rows *sql.Rows, err error) error {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return nil return nil
} else if err != 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 { 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 { } else {
var zList string var zList string
for _, zone := range zones { for _, zone := range zones {
@ -128,6 +128,6 @@ func NewElasticSearchSearcher() (*ElasticSearchSearcher, error) {
return &ElasticSearchSearcher{}, nil 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 return nil, nil
} }

View File

@ -53,7 +53,6 @@ func init() {
func NewThemeList() (themes ThemeList, err error) { func NewThemeList() (themes ThemeList, err error) {
themes = make(map[string]*Theme) themes = make(map[string]*Theme)
themeFiles, err := ioutil.ReadDir("./themes") themeFiles, err := ioutil.ReadDir("./themes")
if err != nil { if err != nil {
return themes, err return themes, err
@ -76,7 +75,7 @@ func NewThemeList() (themes ThemeList, err error) {
return themes, err return themes, err
} }
var theme = &Theme{Name: ""} theme := &Theme{Name: ""}
err = json.Unmarshal(themeFile, theme) err = json.Unmarshal(themeFile, theme)
if err != nil { if err != nil {
return themes, err return themes, err
@ -151,7 +150,7 @@ func NewThemeList() (themes ThemeList, err error) {
if override.IsDir() { if override.IsDir() {
continue 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()) log.Print("attempting to add " + themePath + "/overrides/" + override.Name())
if ext != ".html" { if ext != ".html" {
log.Print("not a html file") 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 // TODO: Make the initThemes and LoadThemes functions less confusing
// ? - Delete themes which no longer exist in the themes folder from the database? // ? - 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() ChangeDefaultThemeMutex.Lock()
defer ChangeDefaultThemeMutex.Unlock() defer ChangeDefaultThemeMutex.Unlock()
@ -211,7 +210,7 @@ func (themes ThemeList) LoadActiveStatus() error {
} }
// Was the theme deleted at some point? // Was the theme deleted at some point?
theme, ok := themes[uname] theme, ok := t[uname]
if !ok { if !ok {
continue continue
} }
@ -226,13 +225,13 @@ func (themes ThemeList) LoadActiveStatus() error {
theme.Active = false theme.Active = false
} }
themes[uname] = theme t[uname] = theme
} }
return rows.Err() return rows.Err()
} }
func (themes ThemeList) LoadStaticFiles() error { func (t ThemeList) LoadStaticFiles() error {
for _, theme := range themes { for _, theme := range t {
err := theme.LoadStaticFiles() err := theme.LoadStaticFiles()
if err != nil { if err != nil {
return err return err

View File

@ -290,10 +290,10 @@ var adminStatsMutex sync.RWMutex
func adminStatsTicker() { func adminStatsTicker() {
time.Sleep(time.Second) time.Sleep(time.Second)
var lastUonline = -1 lastUonline := -1
var lastGonline = -1 lastGonline := -1
var lastTotonline = -1 lastTotonline := -1
var lastCPUPerc = -1 lastCPUPerc := -1
var lastAvailableRAM int64 = -1 var lastAvailableRAM int64 = -1
var noStatUpdates, noRAMUpdates bool var noStatUpdates, noRAMUpdates bool

View File

@ -32,9 +32,9 @@ func widgetSearchAndFilter(widget *Widget, hvars interface{}) (out string, err e
} }
for _, fid := range canSee { for _, fid := range canSee {
forum := Forums.DirtyGet(fid) f := Forums.DirtyGet(fid)
if forum.ParentID == 0 && forum.Name != "" && forum.Active { if f.ParentID == 0 && f.Name != "" && f.Active {
forums = append(forums, filterForum{forum, (header.Zone == "view_forum" || header.Zone == "topics") && header.ZoneID == forum.ID}) forums = append(forums, filterForum{f, (header.Zone == "view_forum" || header.Zone == "topics") && header.ZoneID == f.ID})
} }
} }

View File

@ -2,9 +2,9 @@ package common
import ( import (
"encoding/json" "encoding/json"
"log"
"sync" "sync"
"time" "time"
"log"
"github.com/gorilla/websocket" "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") log.Print("Setting up the WebSocket ticks")
ticker := time.NewTicker(time.Minute * 5) ticker := time.NewTicker(time.Minute * 5)
defer func() { defer func() {
@ -47,9 +47,9 @@ func (hub *WsHubImpl) Start() {
go func() { go func() {
for { for {
item := func(lock *sync.RWMutex, userMap map[int]*WSUser) { item := func(l *sync.RWMutex, userMap map[int]*WSUser) {
lock.RLock() l.RLock()
defer lock.RUnlock() defer l.RUnlock()
// TODO: Copy to temporary slice for less contention? // TODO: Copy to temporary slice for less contention?
for _, user := range userMap { for _, user := range userMap {
user.Ping() user.Ping()
@ -57,40 +57,40 @@ func (hub *WsHubImpl) Start() {
} }
select { select {
case <-ticker.C: case <-ticker.C:
item(&hub.evenUserLock, hub.evenOnlineUsers) item(&h.evenUserLock, h.evenOnlineUsers)
item(&hub.oddUserLock, hub.oddOnlineUsers) item(&h.oddUserLock, h.oddOnlineUsers)
} }
} }
}() }()
if Config.DisableLiveTopicList { if Config.DisableLiveTopicList {
return return
} }
hub.lastTick = time.Now() h.lastTick = time.Now()
AddScheduledSecondTask(hub.Tick) 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 // 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 { func (h *WsHubImpl) Tick() error {
return wsTopicListTick(hub) return wsTopicListTick(h)
} }
func wsTopicListTick(hub *WsHubImpl) error { func wsTopicListTick(h *WsHubImpl) error {
// Avoid hitting GetList when the topic list hasn't changed // Avoid hitting GetList when the topic list hasn't changed
if !TopicListThaw.Thawed() && hub.lastTopicList != nil { if !TopicListThaw.Thawed() && h.lastTopicList != nil {
return nil return nil
} }
tickStart := time.Now() tickStart := time.Now()
// Don't waste CPU time if nothing has happened // Don't waste CPU time if nothing has happened
// TODO: Get a topic list method which strips stickies? // TODO: Get a topic list method which strips stickies?
tList, _, _, err := TopicList.GetList(1, "", nil) tList, _, _, err := TopicList.GetList(1, "", nil)
if err != nil { if err != nil {
hub.lastTick = tickStart h.lastTick = tickStart
return err // TODO: Do we get ErrNoRows here? return err // TODO: Do we get ErrNoRows here?
} }
defer func() { defer func() {
hub.lastTick = tickStart h.lastTick = tickStart
hub.lastTopicList = tList h.lastTopicList = tList
}() }()
if len(tList) == 0 { if len(tList) == 0 {
return nil 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 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: 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 // TODO: Add support for new stickies / replies to them
if len(tList) == len(hub.lastTopicList) { if len(tList) == len(h.lastTopicList) {
var hasItem = false hasItem := false
for j, tItem := range tList { for j, tItem := range tList {
if !tItem.Sticky { 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 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 // 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) groupIDs := make(map[int]bool)
var currentWatchers = make([]*WSUser, len(topicListWatchers)) currentWatchers := make([]*WSUser, len(topicListWatchers))
var i = 0 i := 0
for wsUser, _ := range topicListWatchers { for wsUser, _ := range topicListWatchers {
currentWatchers[i] = wsUser currentWatchers[i] = wsUser
groupIDs[wsUser.User.Group] = true groupIDs[wsUser.User.Group] = true
@ -132,8 +132,8 @@ func wsTopicListTick(hub *WsHubImpl) error {
} }
topicListMutex.RUnlock() topicListMutex.RUnlock()
var groups = make(map[int]*Group) groups := make(map[int]*Group)
var canSeeMap = make(map[string][]int) canSeeMap := make(map[string][]int)
for groupID, _ := range groupIDs { for groupID, _ := range groupIDs {
group, err := Groups.Get(groupID) group, err := Groups.Get(groupID)
if err != nil { if err != nil {
@ -142,14 +142,14 @@ func wsTopicListTick(hub *WsHubImpl) error {
} }
groups[group.ID] = group groups[group.ID] = group
var canSee = make([]byte, len(group.CanSee)) canSee := make([]byte, len(group.CanSee))
for i, item := range group.CanSee { for i, item := range group.CanSee {
canSee[i] = byte(item) canSee[i] = byte(item)
} }
canSeeMap[string(canSee)] = group.CanSee canSeeMap[string(canSee)] = group.CanSee
} }
var canSeeRenders = make(map[string][]byte) canSeeRenders := make(map[string][]byte)
for name, canSee := range canSeeMap { for name, canSee := range canSeeMap {
topicList, forumList, _, err := TopicList.GetListByCanSee(canSee, 1, "", nil) topicList, forumList, _, err := TopicList.GetListByCanSee(canSee, 1, "", nil)
if err != 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 _ = forumList // Might use this later after we get the base feature working
if topicList[0].Sticky { if topicList[0].Sticky {
var lastSticky = 0 lastSticky := 0
for i, row := range topicList { for i, row := range topicList {
if !row.Sticky { if !row.Sticky {
lastSticky = i lastSticky = i
@ -175,7 +175,7 @@ func wsTopicListTick(hub *WsHubImpl) error {
} }
// TODO: Compare to previous tick to eliminate unnecessary work and data // 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 { for i, topicRow := range topicList {
wsTopicList[i] = topicRow.WebSockets() wsTopicList[i] = topicRow.WebSockets()
} }
@ -191,7 +191,7 @@ func wsTopicListTick(hub *WsHubImpl) error {
//fmt.Println("writing to the clients") //fmt.Println("writing to the clients")
for _, wsUser := range currentWatchers { for _, wsUser := range currentWatchers {
group := groups[wsUser.User.Group] group := groups[wsUser.User.Group]
var canSee = make([]byte, len(group.CanSee)) canSee := make([]byte, len(group.CanSee))
for i, item := range group.CanSee { for i, item := range group.CanSee {
canSee[i] = byte(item) canSee[i] = byte(item)
} }
@ -213,38 +213,39 @@ func wsTopicListTick(hub *WsHubImpl) error {
return nil return nil
} }
func (hub *WsHubImpl) GuestCount() int { func (h *WsHubImpl) GuestCount() int {
defer hub.GuestLock.RUnlock() h.GuestLock.RLock()
hub.GuestLock.RLock() defer h.GuestLock.RUnlock()
return len(hub.OnlineGuests) return len(h.OnlineGuests)
} }
func (hub *WsHubImpl) UserCount() (count int) { func (h *WsHubImpl) UserCount() (count int) {
hub.evenUserLock.RLock() h.evenUserLock.RLock()
count += len(hub.evenOnlineUsers) count += len(h.evenOnlineUsers)
hub.evenUserLock.RUnlock() h.evenUserLock.RUnlock()
hub.oddUserLock.RLock() h.oddUserLock.RLock()
count += len(hub.oddOnlineUsers) count += len(h.oddOnlineUsers)
hub.oddUserLock.RUnlock() h.oddUserLock.RUnlock()
return count return count
} }
func (hub *WsHubImpl) HasUser(uid int) (exists bool) { func (h *WsHubImpl) HasUser(uid int) (exists bool) {
hub.evenUserLock.RLock() h.evenUserLock.RLock()
_, exists = hub.evenOnlineUsers[uid] _, exists = h.evenOnlineUsers[uid]
hub.evenUserLock.RUnlock() h.evenUserLock.RUnlock()
if exists { if exists {
return exists return exists
} }
hub.oddUserLock.RLock() h.oddUserLock.RLock()
_, exists = hub.oddOnlineUsers[uid] _, exists = h.oddOnlineUsers[uid]
hub.oddUserLock.RUnlock() h.oddUserLock.RUnlock()
return exists return exists
} }
func (hub *WsHubImpl) broadcastMessage(msg string) error { func (h *WsHubImpl) broadcastMessage(msg string) error {
var userLoop = func(users map[int]*WSUser, mutex *sync.RWMutex) error { userLoop := func(users map[int]*WSUser, m *sync.RWMutex) error {
defer mutex.RUnlock() m.RLock()
defer m.RUnlock()
for _, wsUser := range users { for _, wsUser := range users {
err := wsUser.WriteAll(msg) err := wsUser.WriteAll(msg)
if err != nil { if err != nil {
@ -254,25 +255,23 @@ func (hub *WsHubImpl) broadcastMessage(msg string) error {
return nil return nil
} }
// TODO: Can we move this RLock inside the closure safely? // TODO: Can we move this RLock inside the closure safely?
hub.evenUserLock.RLock() err := userLoop(h.evenOnlineUsers, &h.evenUserLock)
err := userLoop(hub.evenOnlineUsers, &hub.evenUserLock)
if err != nil { if err != nil {
return err return err
} }
hub.oddUserLock.RLock() return userLoop(h.oddOnlineUsers, &h.oddUserLock)
return userLoop(hub.oddOnlineUsers, &hub.oddUserLock)
} }
func (hub *WsHubImpl) getUser(uid int) (wsUser *WSUser, err error) { func (h *WsHubImpl) getUser(uid int) (wsUser *WSUser, err error) {
var ok bool var ok bool
if uid%2 == 0 { if uid%2 == 0 {
hub.evenUserLock.RLock() h.evenUserLock.RLock()
wsUser, ok = hub.evenOnlineUsers[uid] wsUser, ok = h.evenOnlineUsers[uid]
hub.evenUserLock.RUnlock() h.evenUserLock.RUnlock()
} else { } else {
hub.oddUserLock.RLock() h.oddUserLock.RLock()
wsUser, ok = hub.oddOnlineUsers[uid] wsUser, ok = h.oddOnlineUsers[uid]
hub.oddUserLock.RUnlock() h.oddUserLock.RUnlock()
} }
if !ok { if !ok {
return nil, errWsNouser 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 // 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 { if len(uids) == 0 {
return nil, errWsNouser return nil, errWsNouser
} }
var appender = func(lock *sync.RWMutex, users map[int]*WSUser) { appender := func(l *sync.RWMutex, users map[int]*WSUser) {
lock.RLock() l.RLock()
defer lock.RUnlock() defer l.RUnlock()
// We don't want to keep a lock on this for too long, so we'll accept some nil pointers // We don't want to keep a lock on this for too long, so we'll accept some nil pointers
for _, uid := range uids { for _, uid := range uids {
wsUsers = append(wsUsers, users[uid]) wsUsers = append(wsUsers, users[uid])
} }
} }
appender(&hub.evenUserLock, hub.evenOnlineUsers) appender(&h.evenUserLock, h.evenOnlineUsers)
appender(&hub.oddUserLock, hub.oddOnlineUsers) appender(&h.oddUserLock, h.oddOnlineUsers)
if len(wsUsers) == 0 { if len(wsUsers) == 0 {
return nil, errWsNouser 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 // 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) { func (h *WsHubImpl) AllUsers() (users []*User) {
var appender = func(lock *sync.RWMutex, userMap map[int]*WSUser) { appender := func(l *sync.RWMutex, userMap map[int]*WSUser) {
lock.RLock() l.RLock()
defer lock.RUnlock() defer l.RUnlock()
for _, user := range userMap { for _, user := range userMap {
users = append(users, user.User) users = append(users, user.User)
} }
} }
appender(&hub.evenUserLock, hub.evenOnlineUsers) appender(&h.evenUserLock, h.evenOnlineUsers)
appender(&hub.oddUserLock, hub.oddOnlineUsers) appender(&h.oddUserLock, h.oddOnlineUsers)
return users return users
} }
func (hub *WsHubImpl) removeUser(uid int) { func (h *WsHubImpl) removeUser(uid int) {
if uid%2 == 0 { if uid%2 == 0 {
hub.evenUserLock.Lock() h.evenUserLock.Lock()
delete(hub.evenOnlineUsers, uid) delete(h.evenOnlineUsers, uid)
hub.evenUserLock.Unlock() h.evenUserLock.Unlock()
} else { } else {
hub.oddUserLock.Lock() h.oddUserLock.Lock()
delete(hub.oddOnlineUsers, uid) delete(h.oddOnlineUsers, uid)
hub.oddUserLock.Unlock() 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 { if user.ID == 0 {
wsUser := new(WSUser) wsUser := new(WSUser)
wsUser.User = new(User) wsUser.User = new(User)
@ -348,11 +347,11 @@ func (hub *WsHubImpl) AddConn(user User, conn *websocket.Conn) (*WSUser, error)
var mutex *sync.RWMutex var mutex *sync.RWMutex
var theMap map[int]*WSUser var theMap map[int]*WSUser
if user.ID%2 == 0 { if user.ID%2 == 0 {
mutex = &hub.evenUserLock mutex = &h.evenUserLock
theMap = hub.evenOnlineUsers theMap = h.evenOnlineUsers
} else { } else {
mutex = &hub.oddUserLock mutex = &h.oddUserLock
theMap = hub.oddOnlineUsers theMap = h.oddOnlineUsers
} }
mutex.Lock() mutex.Lock()
@ -370,25 +369,25 @@ func (hub *WsHubImpl) AddConn(user User, conn *websocket.Conn) (*WSUser, error)
return wsUser, nil 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.RemoveSocket(conn)
wsUser.Lock() wsUser.Lock()
if len(wsUser.Sockets) == 0 { if len(wsUser.Sockets) == 0 {
hub.removeUser(wsUser.User.ID) h.removeUser(wsUser.User.ID)
} }
wsUser.Unlock() wsUser.Unlock()
} }
func (hub *WsHubImpl) PushMessage(targetUser int, msg string) error { func (h *WsHubImpl) PushMessage(targetUser int, msg string) error {
wsUser, err := hub.getUser(targetUser) wsUser, err := h.getUser(targetUser)
if err != nil { if err != nil {
return err return err
} }
return wsUser.WriteAll(msg) return wsUser.WriteAll(msg)
} }
func (hub *WsHubImpl) pushAlert(targetUser int, alert Alert) error { func (h *WsHubImpl) pushAlert(targetUser int, alert Alert) error {
wsUser, err := hub.getUser(targetUser) wsUser, err := h.getUser(targetUser)
if err != nil { if err != nil {
return err return err
} }
@ -399,8 +398,8 @@ func (hub *WsHubImpl) pushAlert(targetUser int, alert Alert) error {
return wsUser.WriteAll(astr) return wsUser.WriteAll(astr)
} }
func (hub *WsHubImpl) pushAlerts(users []int, alert Alert) error { func (h *WsHubImpl) pushAlerts(users []int, alert Alert) error {
wsUsers, err := hub.getUsers(users) wsUsers, err := h.getUsers(users)
if err != nil { if err != nil {
return err return err
} }

View File

@ -22,8 +22,8 @@ type WSUserSocket struct {
Page string Page string
} }
func (wsUser *WSUser) Ping() error { func (u *WSUser) Ping() error {
for _, socket := range wsUser.Sockets { for _, socket := range u.Sockets {
if socket == nil { if socket == nil {
continue continue
} }
@ -36,9 +36,9 @@ func (wsUser *WSUser) Ping() error {
return nil return nil
} }
func (wsUser *WSUser) WriteAll(msg string) error { func (u *WSUser) WriteAll(msg string) error {
msgbytes := []byte(msg) msgbytes := []byte(msg)
for _, socket := range wsUser.Sockets { for _, socket := range u.Sockets {
if socket == nil { if socket == nil {
continue continue
} }
@ -52,14 +52,14 @@ func (wsUser *WSUser) WriteAll(msg string) error {
return nil return nil
} }
func (wsUser *WSUser) WriteToPage(msg string, page string) error { func (u *WSUser) WriteToPage(msg string, page string) error {
return wsUser.WriteToPageBytes([]byte(msg), page) return u.WriteToPageBytes([]byte(msg), page)
} }
// Inefficient as it looks for sockets for a page even if there are none // 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 var success bool
for _, socket := range wsUser.Sockets { for _, socket := range u.Sockets {
if socket == nil { if socket == nil {
continue continue
} }
@ -80,34 +80,34 @@ func (wsUser *WSUser) WriteToPageBytes(msg []byte, page string) error {
return nil return nil
} }
func (wsUser *WSUser) AddSocket(conn *websocket.Conn, page string) { func (u *WSUser) AddSocket(conn *websocket.Conn, page string) {
wsUser.Lock() 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 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 { if len(u.Sockets) < 6 {
for i, socket := range wsUser.Sockets { for i, socket := range u.Sockets {
if socket == nil { if socket == nil {
wsUser.Sockets[i] = &WSUserSocket{conn, page} u.Sockets[i] = &WSUserSocket{conn, page}
wsUser.Unlock() u.Unlock()
//fmt.Printf("%+v\n", wsUser.Sockets) //fmt.Printf("%+v\n", u.Sockets)
return return
} }
} }
} }
wsUser.Sockets = append(wsUser.Sockets, &WSUserSocket{conn, page}) u.Sockets = append(u.Sockets, &WSUserSocket{conn, page})
//fmt.Printf("%+v\n", wsUser.Sockets) //fmt.Printf("%+v\n", u.Sockets)
wsUser.Unlock() u.Unlock()
} }
func (wsUser *WSUser) RemoveSocket(conn *websocket.Conn) { func (u *WSUser) RemoveSocket(conn *websocket.Conn) {
wsUser.Lock() u.Lock()
if len(wsUser.Sockets) < 6 { if len(u.Sockets) < 6 {
for i, socket := range wsUser.Sockets { for i, socket := range u.Sockets {
if socket == nil { if socket == nil {
continue continue
} }
if socket.conn == conn { if socket.conn == conn {
wsUser.Sockets[i] = nil u.Sockets[i] = nil
wsUser.Unlock() u.Unlock()
//fmt.Printf("%+v\n", wsUser.Sockets) //fmt.Printf("%+v\n", wsUser.Sockets)
return return
} }
@ -115,25 +115,25 @@ func (wsUser *WSUser) RemoveSocket(conn *websocket.Conn) {
} }
var key int var key int
for i, socket := range wsUser.Sockets { for i, socket := range u.Sockets {
if socket.conn == conn { if socket.conn == conn {
key = i key = i
break break
} }
} }
wsUser.Sockets = append(wsUser.Sockets[:key], wsUser.Sockets[key+1:]...) u.Sockets = append(u.Sockets[:key], u.Sockets[key+1:]...)
//fmt.Printf("%+v\n", wsUser.Sockets) //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 { if conn == nil {
return ErrInvalidSocket return ErrInvalidSocket
} }
wsUser.Lock() u.Lock()
for _, socket := range wsUser.Sockets { for _, socket := range u.Sockets {
if socket == nil { if socket == nil {
continue continue
} }
@ -141,15 +141,15 @@ func (wsUser *WSUser) SetPageForSocket(conn *websocket.Conn, page string) error
socket.Page = page socket.Page = page
} }
} }
wsUser.Unlock() u.Unlock()
return nil return nil
} }
func (wsUser *WSUser) InPage(page string) bool { func (u *WSUser) InPage(page string) bool {
wsUser.Lock() u.Lock()
defer wsUser.Unlock() defer u.Unlock()
for _, socket := range wsUser.Sockets { for _, socket := range u.Sockets {
if socket == nil { if socket == nil {
continue continue
} }
@ -160,10 +160,10 @@ func (wsUser *WSUser) InPage(page string) bool {
return false return false
} }
func (wsUser *WSUser) FinalizePage(page string, handle func()) { func (u *WSUser) FinalizePage(page string, handle func()) {
wsUser.Lock() u.Lock()
defer wsUser.Unlock() defer u.Unlock()
for _, socket := range wsUser.Sockets { for _, socket := range u.Sockets {
if socket == nil { if socket == nil {
continue continue
} }

View File

@ -37,7 +37,7 @@ func SitemapXml(w http.ResponseWriter, r *http.Request) c.RouteError {
if c.Site.EnableSsl { if c.Site.EnableSsl {
sslBit = "s" sslBit = "s"
} }
var sitemapItem = func(path string) { sitemapItem := func(path string) {
w.Write([]byte(`<sitemap> w.Write([]byte(`<sitemap>
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc> <loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
</sitemap> </sitemap>
@ -72,10 +72,10 @@ var fuzzySitemapRoutes = map[string]FuzzyRoute{
} }
func sitemapSwitch(w http.ResponseWriter, r *http.Request) c.RouteError { 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 { for name, fuzzy := range fuzzySitemapRoutes {
if strings.HasPrefix(path, name) && strings.HasSuffix(path, ".xml") { 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") spath = strings.TrimSuffix(spath, ".xml")
page, err := strconv.Atoi(spath) page, err := strconv.Atoi(spath)
if err != nil { if err != nil {
@ -99,7 +99,7 @@ func SitemapForums(w http.ResponseWriter, r *http.Request) c.RouteError {
if c.Site.EnableSsl { if c.Site.EnableSsl {
sslBit = "s" sslBit = "s"
} }
var sitemapItem = func(path string) { sitemapItem := func(path string) {
w.Write([]byte(`<url> w.Write([]byte(`<url>
<loc>http` + sslBit + `://` + c.Site.URL + path + `</loc> <loc>http` + sslBit + `://` + c.Site.URL + path + `</loc>
</url> </url>
@ -116,9 +116,9 @@ func SitemapForums(w http.ResponseWriter, r *http.Request) c.RouteError {
for _, fid := range group.CanSee { 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 // 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() f := c.Forums.DirtyGet(fid).Copy()
if forum.ParentID == 0 && forum.Name != "" && forum.Active { if f.ParentID == 0 && f.Name != "" && f.Active {
sitemapItem(c.BuildForumURL(c.NameToSlug(forum.Name), forum.ID)) 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 { if c.Site.EnableSsl {
sslBit = "s" sslBit = "s"
} }
var sitemapItem = func(path string) { sitemapItem := func(path string) {
w.Write([]byte(`<sitemap> w.Write([]byte(`<sitemap>
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc> <loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
</sitemap> </sitemap>
@ -158,7 +158,7 @@ func SitemapTopics(w http.ResponseWriter, r *http.Request) c.RouteError {
return c.InternalErrorXML(err, w, r) return c.InternalErrorXML(err, w, r)
} }
var pageCount = topicCount / sitemapPageCap pageCount := topicCount / sitemapPageCap
//log.Print("topicCount", topicCount) //log.Print("topicCount", topicCount)
//log.Print("pageCount", pageCount) //log.Print("pageCount", pageCount)
writeXMLHeader(w, r) 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) return c.InternalErrorXML(err, w, r)
} }
var pageCount = topicCount / sitemapPageCap pageCount := topicCount / sitemapPageCap
//log.Print("topicCount", topicCount) //log.Print("topicCount", topicCount)
//log.Print("pageCount", pageCount) //log.Print("pageCount", pageCount)
//log.Print("page",page) //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") w.Header().Set("Cache-Control", "private")
me := JsonMe{(&user).Me(), MeSite{c.Site.MaxRequestSize}} me := JsonMe{(&user).Me(), MeSite{c.Site.MaxRequestSize}}
jsonBytes, err := json.Marshal(me) jsonBytes, err := json.Marshal(me)
if err != nil { if err != nil {
return c.InternalErrorJS(err, w, r) return c.InternalErrorJS(err, w, r)
@ -258,13 +257,13 @@ func OpenSearchXml(w http.ResponseWriter, r *http.Request) c.RouteError {
if c.Site.EnableSsl { if c.Site.EnableSsl {
furl += "s" 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/"> 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> <InputEncoding>UTF-8</InputEncoding>
<Url type="text/html" template="`+furl+`/topics/?q={searchTerms}" /> <Url type="text/html" template="` + furl + `/topics/?q={searchTerms}" />
<Url type="application/opensearchdescription+xml" rel="self" template="`+furl+`/opensearch.xml" /> <Url type="application/opensearchdescription+xml" rel="self" template="` + furl + `/opensearch.xml" />
<moz:SearchForm>`+furl+`</moz:SearchForm> <moz:SearchForm>` + furl + `</moz:SearchForm>
</OpenSearchDescription>`)) </OpenSearchDescription>`))
return nil return nil
} }

View File

@ -35,15 +35,15 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
return c.LocalError("Bad extension", w, r, user) 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 { 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") sectionTable := r.FormValue("stype")
var originTable string var originTable string
var originID, uploadedBy int var originID, uploadedBy int
err = attachmentStmts.get.QueryRow(filename, sectionID, sectionTable).Scan(&sectionID, &sectionTable, &originID, &originTable, &uploadedBy, &filename) err = attachmentStmts.get.QueryRow(filename, sid, sectionTable).Scan(&sid, &sectionTable, &originID, &originTable, &uploadedBy, &filename)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.NotFound(w, r, nil) return c.NotFound(w, r, nil)
} else if err != nil { } else if err != nil {
@ -51,7 +51,7 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
} }
if sectionTable == "forums" { if sectionTable == "forums" {
_, ferr := c.SimpleForumUserCheck(w, r, &user, sectionID) _, ferr := c.SimpleForumUserCheck(w, r, &user, sid)
if ferr != nil { if ferr != nil {
return ferr 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))) w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(c.Year)))
} else { } else {
guest := c.GuestUser guest := c.GuestUser
_, ferr := c.SimpleForumUserCheck(w, r, &guest, sectionID) _, ferr := c.SimpleForumUserCheck(w, r, &guest, sid)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }

View File

@ -7,8 +7,8 @@ import (
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters" "github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/common/phrases" p "github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen" qgen "github.com/Azareal/Gosora/query_gen"
) )
type ForumStmts struct { 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")) page, _ := strconv.Atoi(r.FormValue("page"))
_, fid, err := ParseSEOURL(sfid) _, fid, err := ParseSEOURL(sfid)
if err != nil { 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) 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? // 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 topicList []*c.TopicsRow
var reqUserList = make(map[int]bool) reqUserList := make(map[int]bool)
for rows.Next() { for rows.Next() {
var topicItem = c.TopicsRow{ID: 0} t := 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) 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 { if err != nil {
return c.InternalError(err, w, r) 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 // 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) _, _, lastPage := c.PageOffset(t.PostCount, 1, c.Config.ItemsPerPage)
topicItem.LastPage = lastPage t.LastPage = lastPage
header.Hooks.VhookNoRet("forum_trow_assign", &topicItem, &forum) header.Hooks.VhookNoRet("forum_trow_assign", &t, &forum)
topicList = append(topicList, &topicItem) topicList = append(topicList, &t)
reqUserList[topicItem.CreatedBy] = true reqUserList[t.CreatedBy] = true
reqUserList[topicItem.LastReplyBy] = true reqUserList[t.LastReplyBy] = true
} }
err = rows.Err() err = rows.Err()
if err != nil { 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 // 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 var i int
for userID := range reqUserList { for userID := range reqUserList {
idSlice[i] = userID 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 // Second pass to the add the user data
// TODO: Use a pointer to TopicsRow instead of TopicsRow itself? // TODO: Use a pointer to TopicsRow instead of TopicsRow itself?
for _, topicItem := range topicList { for _, t := range topicList {
topicItem.Creator = userList[topicItem.CreatedBy] t.Creator = userList[t.CreatedBy]
topicItem.LastUser = userList[topicItem.LastReplyBy] t.LastUser = userList[t.LastReplyBy]
} }
header.Zone = "view_forum" header.Zone = "view_forum"
header.ZoneID = forum.ID header.ZoneID = forum.ID
@ -128,8 +128,8 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
if tmpl == "" { if tmpl == "" {
ferr = renderTemplate("forum", w, r, header, pi) ferr = renderTemplate("forum", w, r, header, pi)
} else { } else {
tmpl = "forum_"+tmpl tmpl = "forum_" + tmpl
err = renderTemplate3(tmpl, tmpl,w, r, header, pi) err = renderTemplate3(tmpl, tmpl, w, r, header, pi)
if err != nil { if err != nil {
ferr = renderTemplate("forum", w, r, header, pi) ferr = renderTemplate("forum", w, r, header, pi)
} }

View File

@ -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 // 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) uids, err := c.IPSearch.Lookup(ip)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)

View File

@ -81,7 +81,6 @@ func PagesEdit(w http.ResponseWriter, r *http.Request, user c.User, spid string)
if err != nil { if err != nil {
return c.LocalError("Page ID needs to be an integer", w, r, user) return c.LocalError("Page ID needs to be an integer", w, r, user)
} }
page, err := c.Pages.Get(pid) page, err := c.Pages.Get(pid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.NotFound(w, r, basePage.Header) 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 { if err != nil {
return c.LocalError("Page ID needs to be an integer", w, r, user) return c.LocalError("Page ID needs to be an integer", w, r, user)
} }
pname := r.PostFormValue("name") pname := r.PostFormValue("name")
if pname == "" { if pname == "" {
return c.LocalError("No name was provided for this page", w, r, user) 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 { if err != nil {
return c.LocalError("Page ID needs to be an integer", w, r, user) return c.LocalError("Page ID needs to be an integer", w, r, user)
} }
err = c.Pages.Delete(pid) err = c.Pages.Delete(pid)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)

View File

@ -10,8 +10,8 @@ import (
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters" "github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/common/phrases" p "github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen" qgen "github.com/Azareal/Gosora/query_gen"
) )
type ReplyStmts struct { 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 { func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
rid, err := strconv.Atoi(srid) rid, err := strconv.Atoi(srid)
if err != nil { 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) 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 { func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
rid, err := strconv.Atoi(srid) rid, err := strconv.Atoi(srid)
if err != nil { 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) reply, err := c.Rstore.Get(rid)
@ -443,7 +443,7 @@ func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, user c.
for _, said := range saids { for _, said := range saids {
aid, err := strconv.Atoi(said) aid, err := strconv.Atoi(said)
if err != nil { 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) rerr := deleteAttachment(w, r, user, aid, true)
if rerr != nil { 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 { func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
js := (r.PostFormValue("js") == "1") js := (r.PostFormValue("js") == "1")
rid, err := strconv.Atoi(srid) rid, err := strconv.Atoi(srid)
if err != nil { if err != nil {
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js) return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)

View File

@ -281,8 +281,8 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.
// Lock this to the forum being linked? // 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) // 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 var strict bool
header.Hooks.VhookNoRet("topic_create_pre_loop", w, r, fid, &header, &user, &strictmode) header.Hooks.VhookNoRet("topic_create_pre_loop", w, r, fid, &header, &user, &strict)
// TODO: Re-add support for plugin_guilds // TODO: Re-add support for plugin_guilds
var forumList []c.Forum 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? // TODO: plugin_superadmin needs to be able to override this loop. Skip flag on topic_create_pre_loop?
for _, ffid := range canSee { 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 // 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 continue
} }
@ -339,10 +339,10 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
return c.NoPermissions(w, r, user) 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")) content := c.PreparseMessage(r.PostFormValue("topic-content"))
// TODO: Fully parse the post and store it in the parsed column // 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 { if err != nil {
switch err { switch err {
case c.ErrNoRows: 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) return c.LocalError("Unable to load the topic", w, r, user)
} }
if r.PostFormValue("has_poll") == "1" { if r.PostFormValue("has_poll") == "1" {
var maxPollOptions = 10 maxPollOptions := 10
var pollInputItems = make(map[int]string) pollInputItems := make(map[int]string)
for key, values := range r.Form { for key, values := range r.Form {
for _, value := range values { for _, value := range values {
if !strings.HasPrefix(key, "pollinputitem[") { 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 { if len(pollInputItems) > 0 {
// Make sure the indices are sequential to avoid out of bounds issues // 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++ { for i := 0; i < len(pollInputItems); i++ {
seqPollInputItems[i] = 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) 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 { if err == sql.ErrNoRows {
return nil, nil, c.PreError("The topic you tried to "+action+" doesn't exist.", w, r) return nil, nil, c.PreError("The topic you tried to "+action+" doesn't exist.", w, r)
} else if err != nil { } 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 // 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 { if ferr != nil {
return nil, nil, ferr return nil, nil, ferr
} }
return t, lite, nil
return topic, 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 { 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 return nil
} }
func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError { func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, u c.User, stid string) c.RouteError {
topic, lite, rerr := topicActionPre(stid, "unpin", w, r, user) t, lite, rerr := topicActionPre(stid, "unpin", w, r, u)
if rerr != nil { if rerr != nil {
return rerr return rerr
} }
if !user.Perms.ViewTopic || !user.Perms.PinTopic { if !u.Perms.ViewTopic || !u.Perms.PinTopic {
return c.NoPermissions(w, r, user) 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 { 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 return nil
} }
func UnlockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError { func UnlockTopicSubmit(w http.ResponseWriter, r *http.Request, u c.User, stid string) c.RouteError {
topic, lite, rerr := topicActionPre(stid, "unlock", w, r, user) t, lite, rerr := topicActionPre(stid, "unlock", w, r, u)
if rerr != nil { if rerr != nil {
return rerr return rerr
} }
if !user.Perms.ViewTopic || !user.Perms.CloseTopic { if !u.Perms.ViewTopic || !u.Perms.CloseTopic {
return c.NoPermissions(w, r, user) 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 // ! JS only route
@ -853,12 +852,12 @@ func MoveTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfid s
return nil return nil
} }
func addTopicAction(action string, topic *c.Topic, user c.User) error { func addTopicAction(action string, t *c.Topic, u c.User) error {
err := c.ModLogs.Create(action, topic.ID, "topic", user.LastIP, user.ID) err := c.ModLogs.Create(action, t.ID, "topic", u.LastIP, u.ID)
if err != nil { if err != nil {
return err return err
} }
return topic.CreateActionReply(action, user.LastIP, user.ID) return t.CreateActionReply(action, u.LastIP, u.ID)
} }
// TODO: Refactor this // TODO: Refactor this