Shorten the common namespaces in some areas to reduce the amount of boilerplate.
This commit is contained in:
parent
00e30460b5
commit
20a6a22e78
|
@ -10,25 +10,25 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
"gopkg.in/olivere/elastic.v6"
|
"gopkg.in/olivere/elastic.v6"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.Print("Loading the configuration data")
|
log.Print("Loading the configuration data")
|
||||||
err := common.LoadConfig()
|
err := c.LoadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Processing configuration data")
|
log.Print("Processing configuration data")
|
||||||
err = common.ProcessConfig()
|
err = c.ProcessConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if common.DbConfig.Adapter != "mysql" && common.DbConfig.Adapter != "" {
|
if c.DbConfig.Adapter != "mysql" && c.DbConfig.Adapter != "" {
|
||||||
log.Fatal("Only MySQL is supported for upgrades right now, please wait for a newer build of the patcher")
|
log.Fatal("Only MySQL is supported for upgrades right now, please wait for a newer build of the patcher")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,11 +59,11 @@ func main() {
|
||||||
|
|
||||||
func prepMySQL() error {
|
func prepMySQL() error {
|
||||||
return qgen.Builder.Init("mysql", map[string]string{
|
return qgen.Builder.Init("mysql", map[string]string{
|
||||||
"host": common.DbConfig.Host,
|
"host": c.DbConfig.Host,
|
||||||
"port": common.DbConfig.Port,
|
"port": c.DbConfig.Port,
|
||||||
"name": common.DbConfig.Dbname,
|
"name": c.DbConfig.Dbname,
|
||||||
"username": common.DbConfig.Username,
|
"username": c.DbConfig.Username,
|
||||||
"password": common.DbConfig.Password,
|
"password": c.DbConfig.Password,
|
||||||
"collation": "utf8mb4_general_ci",
|
"collation": "utf8mb4_general_ci",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package counters
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,9 +23,9 @@ func NewDefaultAgentViewCounter(acc *qgen.Accumulator) (*DefaultAgentViewCounter
|
||||||
agentBuckets: agentBuckets,
|
agentBuckets: agentBuckets,
|
||||||
insert: acc.Insert("viewchunks_agents").Columns("count, createdAt, browser").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
|
insert: acc.Insert("viewchunks_agents").Columns("count, createdAt, browser").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
|
||||||
}
|
}
|
||||||
common.AddScheduledFifteenMinuteTask(counter.Tick)
|
c.AddScheduledFifteenMinuteTask(counter.Tick)
|
||||||
//common.AddScheduledSecondTask(counter.Tick)
|
//c.AddScheduledSecondTask(counter.Tick)
|
||||||
common.AddShutdownTask(counter.Tick)
|
c.AddShutdownTask(counter.Tick)
|
||||||
return counter, acc.FirstError()
|
return counter, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,14 +50,14 @@ func (counter *DefaultAgentViewCounter) insertChunk(count int, agent int) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var agentName = reverseAgentMapEnum[agent]
|
var agentName = reverseAgentMapEnum[agent]
|
||||||
common.DebugLogf("Inserting a viewchunk with a count of %d for agent %s (%d)", count, agentName, agent)
|
c.DebugLogf("Inserting a viewchunk with a count of %d for agent %s (%d)", count, agentName, agent)
|
||||||
_, err := counter.insert.Exec(count, agentName)
|
_, err := counter.insert.Exec(count, agentName)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (counter *DefaultAgentViewCounter) Bump(agent int) {
|
func (counter *DefaultAgentViewCounter) Bump(agent int) {
|
||||||
// TODO: Test this check
|
// TODO: Test this check
|
||||||
common.DebugDetail("counter.agentBuckets[", agent, "]: ", counter.agentBuckets[agent])
|
c.DebugDetail("counter.agentBuckets[", agent, "]: ", counter.agentBuckets[agent])
|
||||||
if len(counter.agentBuckets) <= agent || agent < 0 {
|
if len(counter.agentBuckets) <= agent || agent < 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,9 +28,9 @@ func NewDefaultForumViewCounter() (*DefaultForumViewCounter, error) {
|
||||||
evenMap: make(map[int]*RWMutexCounterBucket),
|
evenMap: make(map[int]*RWMutexCounterBucket),
|
||||||
insert: acc.Insert("viewchunks_forums").Columns("count, createdAt, forum").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
|
insert: acc.Insert("viewchunks_forums").Columns("count, createdAt, forum").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
|
||||||
}
|
}
|
||||||
common.AddScheduledFifteenMinuteTask(counter.Tick) // There could be a lot of routes, so we don't want to be running this every second
|
c.AddScheduledFifteenMinuteTask(counter.Tick) // There could be a lot of routes, so we don't want to be running this every second
|
||||||
//common.AddScheduledSecondTask(counter.Tick)
|
//c.AddScheduledSecondTask(counter.Tick)
|
||||||
common.AddShutdownTask(counter.Tick)
|
c.AddShutdownTask(counter.Tick)
|
||||||
return counter, acc.FirstError()
|
return counter, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ func (counter *DefaultForumViewCounter) insertChunk(count int, forum int) error
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
common.DebugLogf("Inserting a viewchunk with a count of %d for forum %d", count, forum)
|
c.DebugLogf("Inserting a viewchunk with a count of %d for forum %d", count, forum)
|
||||||
_, err := counter.insert.Exec(count, forum)
|
_, err := counter.insert.Exec(count, forum)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package counters
|
package counters
|
||||||
|
|
||||||
import "database/sql"
|
import "database/sql"
|
||||||
import "github.com/Azareal/Gosora/common"
|
import c "github.com/Azareal/Gosora/common"
|
||||||
import "github.com/Azareal/Gosora/query_gen"
|
import "github.com/Azareal/Gosora/query_gen"
|
||||||
|
|
||||||
var LangViewCounter *DefaultLangViewCounter
|
var LangViewCounter *DefaultLangViewCounter
|
||||||
|
@ -116,9 +116,9 @@ func NewDefaultLangViewCounter(acc *qgen.Accumulator) (*DefaultLangViewCounter,
|
||||||
insert: acc.Insert("viewchunks_langs").Columns("count, createdAt, lang").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
|
insert: acc.Insert("viewchunks_langs").Columns("count, createdAt, lang").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
|
||||||
}
|
}
|
||||||
|
|
||||||
common.AddScheduledFifteenMinuteTask(counter.Tick)
|
c.AddScheduledFifteenMinuteTask(counter.Tick)
|
||||||
//common.AddScheduledSecondTask(counter.Tick)
|
//c.AddScheduledSecondTask(counter.Tick)
|
||||||
common.AddShutdownTask(counter.Tick)
|
c.AddShutdownTask(counter.Tick)
|
||||||
return counter, acc.FirstError()
|
return counter, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ func (counter *DefaultLangViewCounter) insertChunk(count int, id int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var langCode = langCodes[id]
|
var langCode = langCodes[id]
|
||||||
common.DebugLogf("Inserting a viewchunk with a count of %d for lang %s (%d)", count, langCode, id)
|
c.DebugLogf("Inserting a viewchunk with a count of %d for lang %s (%d)", count, langCode, id)
|
||||||
_, err := counter.insert.Exec(count, langCode)
|
_, err := counter.insert.Exec(count, langCode)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ func (counter *DefaultLangViewCounter) Bump(langCode string) (validCode bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Test this check
|
// TODO: Test this check
|
||||||
common.DebugDetail("counter.buckets[", id, "]: ", counter.buckets[id])
|
c.DebugDetail("counter.buckets[", id, "]: ", counter.buckets[id])
|
||||||
if len(counter.buckets) <= id || id < 0 {
|
if len(counter.buckets) <= id || id < 0 {
|
||||||
return validCode
|
return validCode
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,9 +23,9 @@ func NewPostCounter() (*DefaultPostCounter, error) {
|
||||||
currentBucket: 0,
|
currentBucket: 0,
|
||||||
insert: acc.Insert("postchunks").Columns("count, createdAt").Fields("?,UTC_TIMESTAMP()").Prepare(),
|
insert: acc.Insert("postchunks").Columns("count, createdAt").Fields("?,UTC_TIMESTAMP()").Prepare(),
|
||||||
}
|
}
|
||||||
common.AddScheduledFifteenMinuteTask(counter.Tick)
|
c.AddScheduledFifteenMinuteTask(counter.Tick)
|
||||||
//common.AddScheduledSecondTask(counter.Tick)
|
//c.AddScheduledSecondTask(counter.Tick)
|
||||||
common.AddShutdownTask(counter.Tick)
|
c.AddShutdownTask(counter.Tick)
|
||||||
return counter, acc.FirstError()
|
return counter, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ func (counter *DefaultPostCounter) insertChunk(count int64) error {
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
common.DebugLogf("Inserting a postchunk with a count of %d", count)
|
c.DebugLogf("Inserting a postchunk with a count of %d", count)
|
||||||
_, err := counter.insert.Exec(count)
|
_, err := counter.insert.Exec(count)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,9 +28,9 @@ func NewDefaultTopicViewCounter() (*DefaultTopicViewCounter, error) {
|
||||||
evenTopics: make(map[int]*RWMutexCounterBucket),
|
evenTopics: make(map[int]*RWMutexCounterBucket),
|
||||||
update: acc.Update("topics").Set("views = views + ?").Where("tid = ?").Prepare(),
|
update: acc.Update("topics").Set("views = views + ?").Where("tid = ?").Prepare(),
|
||||||
}
|
}
|
||||||
common.AddScheduledFifteenMinuteTask(counter.Tick) // Who knows how many topics we have queued up, we probably don't want this running too frequently
|
c.AddScheduledFifteenMinuteTask(counter.Tick) // Who knows how many topics we have queued up, we probably don't want this running too frequently
|
||||||
//common.AddScheduledSecondTask(counter.Tick)
|
//c.AddScheduledSecondTask(counter.Tick)
|
||||||
common.AddShutdownTask(counter.Tick)
|
c.AddShutdownTask(counter.Tick)
|
||||||
return counter, acc.FirstError()
|
return counter, acc.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,14 +82,14 @@ func (counter *DefaultTopicViewCounter) insertChunk(count int, topicID int) erro
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
common.DebugLogf("Inserting %d views into topic %d", count, topicID)
|
c.DebugLogf("Inserting %d views into topic %d", count, topicID)
|
||||||
_, err := counter.update.Exec(count, topicID)
|
_, err := counter.update.Exec(count, topicID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add a way to disable this for extra speed ;)
|
// TODO: Add a way to disable this for extra speed ;)
|
||||||
tcache := common.Topics.GetCache()
|
tcache := c.Topics.GetCache()
|
||||||
if tcache != nil {
|
if tcache != nil {
|
||||||
topic, err := tcache.Get(topicID)
|
topic, err := tcache.Get(topicID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A blank list to fill out that parameter in Page for routes which don't use it
|
// A blank list to fill out that parameter in Page for routes which don't use it
|
||||||
|
@ -43,16 +43,16 @@ type Guild struct {
|
||||||
LastUpdateTime string
|
LastUpdateTime string
|
||||||
|
|
||||||
MainForumID int
|
MainForumID int
|
||||||
MainForum *common.Forum
|
MainForum *c.Forum
|
||||||
Forums []*common.Forum
|
Forums []*c.Forum
|
||||||
ExtData common.ExtData
|
ExtData c.ExtData
|
||||||
}
|
}
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
Title string
|
Title string
|
||||||
Header *common.Header
|
Header *c.Header
|
||||||
ItemList []*common.TopicsRow
|
ItemList []*c.TopicsRow
|
||||||
Forum *common.Forum
|
Forum *c.Forum
|
||||||
Guild *Guild
|
Guild *Guild
|
||||||
Page int
|
Page int
|
||||||
LastPage int
|
LastPage int
|
||||||
|
@ -61,13 +61,13 @@ type Page struct {
|
||||||
// ListPage is a page struct for constructing a list of every guild
|
// ListPage is a page struct for constructing a list of every guild
|
||||||
type ListPage struct {
|
type ListPage struct {
|
||||||
Title string
|
Title string
|
||||||
Header *common.Header
|
Header *c.Header
|
||||||
GuildList []*Guild
|
GuildList []*Guild
|
||||||
}
|
}
|
||||||
|
|
||||||
type MemberListPage struct {
|
type MemberListPage struct {
|
||||||
Title string
|
Title string
|
||||||
Header *common.Header
|
Header *c.Header
|
||||||
ItemList []Member
|
ItemList []Member
|
||||||
Guild *Guild
|
Guild *Guild
|
||||||
Page int
|
Page int
|
||||||
|
@ -83,15 +83,15 @@ type Member struct {
|
||||||
JoinedAt string
|
JoinedAt string
|
||||||
Offline bool // TODO: Need to track the online states of members when WebSockets are enabled
|
Offline bool // TODO: Need to track the online states of members when WebSockets are enabled
|
||||||
|
|
||||||
User common.User
|
User c.User
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrebuildTmplList(user common.User, header *common.Header) common.CTmpl {
|
func PrebuildTmplList(user c.User, header *c.Header) c.CTmpl {
|
||||||
var guildList = []*Guild{
|
var guildList = []*Guild{
|
||||||
&Guild{
|
&Guild{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
Name: "lol",
|
Name: "lol",
|
||||||
Link: BuildGuildURL(common.NameToSlug("lol"), 1),
|
Link: BuildGuildURL(c.NameToSlug("lol"), 1),
|
||||||
Desc: "A group for people who like to laugh",
|
Desc: "A group for people who like to laugh",
|
||||||
Active: true,
|
Active: true,
|
||||||
MemberCount: 1,
|
MemberCount: 1,
|
||||||
|
@ -99,26 +99,26 @@ func PrebuildTmplList(user common.User, header *common.Header) common.CTmpl {
|
||||||
CreatedAt: "date",
|
CreatedAt: "date",
|
||||||
LastUpdateTime: "date",
|
LastUpdateTime: "date",
|
||||||
MainForumID: 1,
|
MainForumID: 1,
|
||||||
MainForum: common.Forums.DirtyGet(1),
|
MainForum: c.Forums.DirtyGet(1),
|
||||||
Forums: []*common.Forum{common.Forums.DirtyGet(1)},
|
Forums: []*c.Forum{c.Forums.DirtyGet(1)},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
listPage := ListPage{"Guild List", user, header, guildList}
|
listPage := ListPage{"Guild List", user, header, guildList}
|
||||||
return common.CTmpl{"guilds_guild_list", "guilds_guild_list.html", "templates/", "guilds.ListPage", listPage, []string{"./extend/guilds/lib"}}
|
return c.CTmpl{"guilds_guild_list", "guilds_guild_list.html", "templates/", "guilds.ListPage", listPage, []string{"./extend/guilds/lib"}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Do this properly via the widget system
|
// TODO: Do this properly via the widget system
|
||||||
// TODO: REWRITE THIS
|
// TODO: REWRITE THIS
|
||||||
func CommonAreaWidgets(header *common.Header) {
|
func CommonAreaWidgets(header *c.Header) {
|
||||||
// TODO: Hot Groups? Featured Groups? Official Groups?
|
// TODO: Hot Groups? Featured Groups? Official Groups?
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
var menu = common.WidgetMenu{"Guilds", []common.WidgetMenuItem{
|
var menu = c.WidgetMenu{"Guilds", []c.WidgetMenuItem{
|
||||||
common.WidgetMenuItem{"Create Guild", "/guild/create/", false},
|
c.WidgetMenuItem{"Create Guild", "/guild/create/", false},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
err := header.Theme.RunTmpl("widget_menu", pi, w)
|
err := header.Theme.RunTmpl("widget_menu", pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.LogError(err)
|
c.LogError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ func CommonAreaWidgets(header *common.Header) {
|
||||||
|
|
||||||
// TODO: Do this properly via the widget system
|
// TODO: Do this properly via the widget system
|
||||||
// TODO: Make a better more customisable group widget system
|
// TODO: Make a better more customisable group widget system
|
||||||
func GuildWidgets(header *common.Header, guildItem *Guild) (success bool) {
|
func GuildWidgets(header *c.Header, guildItem *Guild) (success bool) {
|
||||||
return false // Disabled until the next commit
|
return false // Disabled until the next commit
|
||||||
|
|
||||||
/*var b bytes.Buffer
|
/*var b bytes.Buffer
|
||||||
|
@ -142,7 +142,7 @@ func GuildWidgets(header *common.Header, guildItem *Guild) (success bool) {
|
||||||
|
|
||||||
err := templates.ExecuteTemplate(&b, "widget_menu.html", menu)
|
err := templates.ExecuteTemplate(&b, "widget_menu.html", menu)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.LogError(err)
|
c.LogError(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,16 +160,16 @@ func GuildWidgets(header *common.Header, guildItem *Guild) (success bool) {
|
||||||
Custom Pages
|
Custom Pages
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func RouteGuildList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func RouteGuildList(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
header, ferr := common.UserCheck(w, r, &user)
|
header, ferr := c.UserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
CommonAreaWidgets(header)
|
CommonAreaWidgets(header)
|
||||||
|
|
||||||
rows, err := ListStmt.Query()
|
rows, err := ListStmt.Query()
|
||||||
if err != nil && err != common.ErrNoRows {
|
if err != nil && err != c.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
|
@ -178,37 +178,37 @@ func RouteGuildList(w http.ResponseWriter, r *http.Request, user common.User) co
|
||||||
guildItem := &Guild{ID: 0}
|
guildItem := &Guild{ID: 0}
|
||||||
err := rows.Scan(&guildItem.ID, &guildItem.Name, &guildItem.Desc, &guildItem.Active, &guildItem.Privacy, &guildItem.Joinable, &guildItem.Owner, &guildItem.MemberCount, &guildItem.CreatedAt, &guildItem.LastUpdateTime)
|
err := rows.Scan(&guildItem.ID, &guildItem.Name, &guildItem.Desc, &guildItem.Active, &guildItem.Privacy, &guildItem.Joinable, &guildItem.Owner, &guildItem.MemberCount, &guildItem.CreatedAt, &guildItem.LastUpdateTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
guildItem.Link = BuildGuildURL(common.NameToSlug(guildItem.Name), guildItem.ID)
|
guildItem.Link = BuildGuildURL(c.NameToSlug(guildItem.Name), guildItem.ID)
|
||||||
guildList = append(guildList, guildItem)
|
guildList = append(guildList, guildItem)
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
err = rows.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := ListPage{"Guild List", user, header, guildList}
|
pi := ListPage{"Guild List", user, header, guildList}
|
||||||
err = header.Theme.RunTmpl("guilds_guild_list", pi, w)
|
err = header.Theme.RunTmpl("guilds_guild_list", pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
_, guildID, err := routes.ParseSEOURL(r.URL.Path[len("/guild/"):])
|
_, guildID, err := routes.ParseSEOURL(r.URL.Path[len("/guild/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.PreError("Not a valid guild ID", w, r)
|
return c.PreError("Not a valid guild ID", w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
guildItem, err := Gstore.Get(guildID)
|
guildItem, err := Gstore.Get(guildID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("Bad guild", w, r, user)
|
return c.LocalError("Bad guild", w, r, user)
|
||||||
}
|
}
|
||||||
// TODO: Build and pass header
|
// TODO: Build and pass header
|
||||||
if !guildItem.Active {
|
if !guildItem.Active {
|
||||||
return common.NotFound(w, r, nil)
|
return c.NotFound(w, r, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -219,36 +219,36 @@ func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
//return routeForum(w, r.WithContext(ctx), user, strconv.Itoa(guildItem.MainForumID))
|
//return routeForum(w, r.WithContext(ctx), user, strconv.Itoa(guildItem.MainForumID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
header, ferr := common.UserCheck(w, r, &user)
|
header, ferr := c.UserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
header.Title = "Create Guild"
|
header.Title = "Create Guild"
|
||||||
// TODO: Add an approval queue mode for group creation
|
// TODO: Add an approval queue mode for group creation
|
||||||
if !user.Loggedin || !user.PluginPerms["CreateGuild"] {
|
if !user.Loggedin || !user.PluginPerms["CreateGuild"] {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
CommonAreaWidgets(header)
|
CommonAreaWidgets(header)
|
||||||
|
|
||||||
pi := common.Page{header, tList, nil}
|
pi := c.Page{header, tList, nil}
|
||||||
err := header.Theme.RunTmpl("guilds_create_guild", pi, w)
|
err := header.Theme.RunTmpl("guilds_create_guild", pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
// TODO: Add an approval queue mode for group creation
|
// TODO: Add an approval queue mode for group creation
|
||||||
if !user.Loggedin || !user.PluginPerms["CreateGuild"] {
|
if !user.Loggedin || !user.PluginPerms["CreateGuild"] {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
var guildActive = true
|
var guildActive = true
|
||||||
var guildName = common.SanitiseSingleLine(r.PostFormValue("group_name"))
|
var guildName = c.SanitiseSingleLine(r.PostFormValue("group_name"))
|
||||||
// TODO: Allow Markdown / BBCode / Limited HTML in the description?
|
// TODO: Allow Markdown / BBCode / Limited HTML in the description?
|
||||||
var guildDesc = common.SanitiseBody(r.PostFormValue("group_desc"))
|
var guildDesc = c.SanitiseBody(r.PostFormValue("group_desc"))
|
||||||
var gprivacy = r.PostFormValue("group_privacy")
|
var gprivacy = r.PostFormValue("group_privacy")
|
||||||
|
|
||||||
var guildPrivacy int
|
var guildPrivacy int
|
||||||
|
@ -264,53 +264,53 @@ func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user common.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the backing forum
|
// Create the backing forum
|
||||||
fid, err := common.Forums.Create(guildName, "", true, "")
|
fid, err := c.Forums.Create(guildName, "", true, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
gid, err := Gstore.Create(guildName, guildDesc, guildActive, guildPrivacy, user.ID, fid)
|
gid, err := Gstore.Create(guildName, guildDesc, guildActive, guildPrivacy, user.ID, fid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the main backing forum to the forum list
|
// Add the main backing forum to the forum list
|
||||||
err = AttachForum(gid, fid)
|
err = AttachForum(gid, fid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = AddMemberStmt.Exec(gid, user.ID, 2)
|
_, err = AddMemberStmt.Exec(gid, user.ID, 2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Redirect(w, r, BuildGuildURL(common.NameToSlug(guildName), gid), http.StatusSeeOther)
|
http.Redirect(w, r, BuildGuildURL(c.NameToSlug(guildName), gid), http.StatusSeeOther)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RouteMemberList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func RouteMemberList(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
header, ferr := common.UserCheck(w, r, &user)
|
header, ferr := c.UserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
|
|
||||||
_, guildID, err := routes.ParseSEOURL(r.URL.Path[len("/guild/members/"):])
|
_, guildID, err := routes.ParseSEOURL(r.URL.Path[len("/guild/members/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.PreError("Not a valid group ID", w, r)
|
return c.PreError("Not a valid group ID", w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
guildItem, err := Gstore.Get(guildID)
|
guildItem, err := Gstore.Get(guildID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("Bad group", w, r, user)
|
return c.LocalError("Bad group", w, r, user)
|
||||||
}
|
}
|
||||||
guildItem.Link = BuildGuildURL(common.NameToSlug(guildItem.Name), guildItem.ID)
|
guildItem.Link = BuildGuildURL(c.NameToSlug(guildItem.Name), guildItem.ID)
|
||||||
|
|
||||||
GuildWidgets(header, guildItem)
|
GuildWidgets(header, guildItem)
|
||||||
|
|
||||||
rows, err := MemberListJoinStmt.Query(guildID)
|
rows, err := MemberListJoinStmt.Query(guildID)
|
||||||
if err != nil && err != common.ErrNoRows {
|
if err != nil && err != c.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var guildMembers []Member
|
var guildMembers []Member
|
||||||
|
@ -318,11 +318,11 @@ func RouteMemberList(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
guildMember := Member{PostCount: 0}
|
guildMember := Member{PostCount: 0}
|
||||||
err := rows.Scan(&guildMember.User.ID, &guildMember.Rank, &guildMember.PostCount, &guildMember.JoinedAt, &guildMember.User.Name, &guildMember.User.RawAvatar)
|
err := rows.Scan(&guildMember.User.ID, &guildMember.Rank, &guildMember.PostCount, &guildMember.JoinedAt, &guildMember.User.Name, &guildMember.User.RawAvatar)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
guildMember.Link = common.BuildProfileURL(common.NameToSlug(guildMember.User.Name), guildMember.User.ID)
|
guildMember.Link = c.BuildProfileURL(c.NameToSlug(guildMember.User.Name), guildMember.User.ID)
|
||||||
guildMember.User.Avatar, guildMember.User.MicroAvatar = common.BuildAvatar(guildMember.User.ID, guildMember.User.RawAvatar)
|
guildMember.User.Avatar, guildMember.User.MicroAvatar = c.BuildAvatar(guildMember.User.ID, guildMember.User.RawAvatar)
|
||||||
guildMember.JoinedAt, _ = common.RelativeTimeFromString(guildMember.JoinedAt)
|
guildMember.JoinedAt, _ = c.RelativeTimeFromString(guildMember.JoinedAt)
|
||||||
if guildItem.Owner == guildMember.User.ID {
|
if guildItem.Owner == guildMember.User.ID {
|
||||||
guildMember.RankString = "Owner"
|
guildMember.RankString = "Owner"
|
||||||
} else {
|
} else {
|
||||||
|
@ -339,18 +339,18 @@ func RouteMemberList(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
err = rows.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
rows.Close()
|
rows.Close()
|
||||||
|
|
||||||
pi := MemberListPage{"Guild Member List", user, header, guildMembers, guildItem, 0, 0}
|
pi := MemberListPage{"Guild Member List", user, header, guildMembers, guildItem, 0, 0}
|
||||||
// A plugin with plugins. Pluginception!
|
// A plugin with plugins. Pluginception!
|
||||||
if common.RunPreRenderHook("pre_render_guilds_member_list", w, r, &user, &pi) {
|
if c.RunPreRenderHook("pre_render_guilds_member_list", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err = common.RunThemeTemplate(header.Theme.Name, "guilds_member_list", pi, w)
|
err = c.RunThemeTemplate(header.Theme.Name, "guilds_member_list", pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -366,7 +366,7 @@ func UnattachForum(fid int) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildGuildURL(slug string, id int) string {
|
func BuildGuildURL(slug string, id int) string {
|
||||||
if slug == "" || !common.Config.BuildSlugs {
|
if slug == "" || !c.Config.BuildSlugs {
|
||||||
return "/guild/" + strconv.Itoa(id)
|
return "/guild/" + strconv.Itoa(id)
|
||||||
}
|
}
|
||||||
return "/guild/" + slug + "." + strconv.Itoa(id)
|
return "/guild/" + slug + "." + strconv.Itoa(id)
|
||||||
|
@ -377,8 +377,8 @@ func BuildGuildURL(slug string, id int) string {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: Prebuild this template
|
// TODO: Prebuild this template
|
||||||
func PreRenderViewForum(w http.ResponseWriter, r *http.Request, user *common.User, data interface{}) (halt bool) {
|
func PreRenderViewForum(w http.ResponseWriter, r *http.Request, user *c.User, data interface{}) (halt bool) {
|
||||||
pi := data.(*common.ForumPage)
|
pi := data.(*c.ForumPage)
|
||||||
if pi.Header.ExtData.Items != nil {
|
if pi.Header.ExtData.Items != nil {
|
||||||
if guildData, ok := pi.Header.ExtData.Items["guilds_current_group"]; ok {
|
if guildData, ok := pi.Header.ExtData.Items["guilds_current_group"]; ok {
|
||||||
guildItem := guildData.(*Guild)
|
guildItem := guildData.(*Guild)
|
||||||
|
@ -386,7 +386,7 @@ func PreRenderViewForum(w http.ResponseWriter, r *http.Request, user *common.Use
|
||||||
guildpi := Page{pi.Title, pi.Header, pi.ItemList, pi.Forum, guildItem, pi.Page, pi.LastPage}
|
guildpi := Page{pi.Title, pi.Header, pi.ItemList, pi.Forum, guildItem, pi.Page, pi.LastPage}
|
||||||
err := header.Theme.RunTmpl("guilds_view_guild", guildpi, w)
|
err := header.Theme.RunTmpl("guilds_view_guild", guildpi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.LogError(err)
|
c.LogError(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -396,10 +396,10 @@ func PreRenderViewForum(w http.ResponseWriter, r *http.Request, user *common.Use
|
||||||
}
|
}
|
||||||
|
|
||||||
func TrowAssign(args ...interface{}) interface{} {
|
func TrowAssign(args ...interface{}) interface{} {
|
||||||
var forum = args[1].(*common.Forum)
|
var forum = args[1].(*c.Forum)
|
||||||
if forum.ParentType == "guild" {
|
if forum.ParentType == "guild" {
|
||||||
var topicItem = args[0].(*common.TopicsRow)
|
var topicItem = args[0].(*c.TopicsRow)
|
||||||
topicItem.ForumLink = "/guild/" + strings.TrimPrefix(topicItem.ForumLink, common.GetForumURLPrefix())
|
topicItem.ForumLink = "/guild/" + strings.TrimPrefix(topicItem.ForumLink, c.GetForumURLPrefix())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -407,7 +407,7 @@ func TrowAssign(args ...interface{}) interface{} {
|
||||||
// TODO: It would be nice, if you could select one of the boards in the group from that drop-down rather than just the one you got linked from
|
// TODO: It would be nice, if you could select one of the boards in the group from that drop-down rather than just the one you got linked from
|
||||||
func TopicCreatePreLoop(args ...interface{}) interface{} {
|
func TopicCreatePreLoop(args ...interface{}) interface{} {
|
||||||
var fid = args[2].(int)
|
var fid = args[2].(int)
|
||||||
if common.Forums.DirtyGet(fid).ParentType == "guild" {
|
if c.Forums.DirtyGet(fid).ParentType == "guild" {
|
||||||
var strictmode = args[5].(*bool)
|
var strictmode = args[5].(*bool)
|
||||||
*strictmode = true
|
*strictmode = true
|
||||||
}
|
}
|
||||||
|
@ -417,10 +417,10 @@ func TopicCreatePreLoop(args ...interface{}) interface{} {
|
||||||
// TODO: Add privacy options
|
// TODO: Add privacy options
|
||||||
// TODO: Add support for multiple boards and add per-board simplified permissions
|
// TODO: Add support for multiple boards and add per-board simplified permissions
|
||||||
// TODO: Take isJs into account for routes which expect JSON responses
|
// TODO: Take isJs into account for routes which expect JSON responses
|
||||||
func ForumCheck(args ...interface{}) (skip bool, rerr common.RouteError) {
|
func ForumCheck(args ...interface{}) (skip bool, rerr c.RouteError) {
|
||||||
var r = args[1].(*http.Request)
|
var r = args[1].(*http.Request)
|
||||||
var fid = args[3].(*int)
|
var fid = args[3].(*int)
|
||||||
var forum = common.Forums.DirtyGet(*fid)
|
var forum = c.Forums.DirtyGet(*fid)
|
||||||
|
|
||||||
if forum.ParentType == "guild" {
|
if forum.ParentType == "guild" {
|
||||||
var err error
|
var err error
|
||||||
|
@ -429,15 +429,15 @@ func ForumCheck(args ...interface{}) (skip bool, rerr common.RouteError) {
|
||||||
if !ok {
|
if !ok {
|
||||||
guildItem, err = Gstore.Get(forum.ParentID)
|
guildItem, err = Gstore.Get(forum.ParentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, common.InternalError(errors.New("Unable to find the parent group for a forum"), w, r)
|
return true, c.InternalError(errors.New("Unable to find the parent group for a forum"), w, r)
|
||||||
}
|
}
|
||||||
if !guildItem.Active {
|
if !guildItem.Active {
|
||||||
return true, common.NotFound(w, r, nil) // TODO: Can we pull header out of args?
|
return true, c.NotFound(w, r, nil) // TODO: Can we pull header out of args?
|
||||||
}
|
}
|
||||||
r = r.WithContext(context.WithValue(r.Context(), "guilds_current_group", guildItem))
|
r = r.WithContext(context.WithValue(r.Context(), "guilds_current_group", guildItem))
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = args[2].(*common.User)
|
var user = args[2].(*c.User)
|
||||||
var rank int
|
var rank int
|
||||||
var posts int
|
var posts int
|
||||||
var joinedAt string
|
var joinedAt string
|
||||||
|
@ -446,32 +446,32 @@ func ForumCheck(args ...interface{}) (skip bool, rerr common.RouteError) {
|
||||||
|
|
||||||
// Clear the default group permissions
|
// Clear the default group permissions
|
||||||
// TODO: Do this more efficiently, doing it quick and dirty for now to get this out quickly
|
// TODO: Do this more efficiently, doing it quick and dirty for now to get this out quickly
|
||||||
common.OverrideForumPerms(&user.Perms, false)
|
c.OverrideForumPerms(&user.Perms, false)
|
||||||
user.Perms.ViewTopic = true
|
user.Perms.ViewTopic = true
|
||||||
|
|
||||||
err = GetMemberStmt.QueryRow(guildItem.ID, user.ID).Scan(&rank, &posts, &joinedAt)
|
err = GetMemberStmt.QueryRow(guildItem.ID, user.ID).Scan(&rank, &posts, &joinedAt)
|
||||||
if err != nil && err != common.ErrNoRows {
|
if err != nil && err != c.ErrNoRows {
|
||||||
return true, common.InternalError(err, w, r)
|
return true, c.InternalError(err, w, r)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
// TODO: Should we let admins / guests into public groups?
|
// TODO: Should we let admins / guests into public groups?
|
||||||
return true, common.LocalError("You're not part of this group!", w, r, *user)
|
return true, c.LocalError("You're not part of this group!", w, r, *user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement bans properly by adding the Local Ban API in the next commit
|
// TODO: Implement bans properly by adding the Local Ban API in the next commit
|
||||||
// TODO: How does this even work? Refactor it along with the rest of this plugin!
|
// TODO: How does this even work? Refactor it along with the rest of this plugin!
|
||||||
if rank < 0 {
|
if rank < 0 {
|
||||||
return true, common.LocalError("You've been banned from this group!", w, r, *user)
|
return true, c.LocalError("You've been banned from this group!", w, r, *user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basic permissions for members, more complicated permissions coming in the next commit!
|
// Basic permissions for members, more complicated permissions coming in the next commit!
|
||||||
if guildItem.Owner == user.ID {
|
if guildItem.Owner == user.ID {
|
||||||
common.OverrideForumPerms(&user.Perms, true)
|
c.OverrideForumPerms(&user.Perms, true)
|
||||||
} else if rank == 0 {
|
} else if rank == 0 {
|
||||||
user.Perms.LikeItem = true
|
user.Perms.LikeItem = true
|
||||||
user.Perms.CreateTopic = true
|
user.Perms.CreateTopic = true
|
||||||
user.Perms.CreateReply = true
|
user.Perms.CreateReply = true
|
||||||
} else {
|
} else {
|
||||||
common.OverrideForumPerms(&user.Perms, true)
|
c.OverrideForumPerms(&user.Perms, true)
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
@ -483,19 +483,19 @@ func ForumCheck(args ...interface{}) (skip bool, rerr common.RouteError) {
|
||||||
|
|
||||||
func Widgets(args ...interface{}) interface{} {
|
func Widgets(args ...interface{}) interface{} {
|
||||||
var zone = args[0].(string)
|
var zone = args[0].(string)
|
||||||
var header = args[2].(*common.Header)
|
var header = args[2].(*c.Header)
|
||||||
var request = args[3].(*http.Request)
|
var request = args[3].(*http.Request)
|
||||||
|
|
||||||
if zone != "view_forum" {
|
if zone != "view_forum" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var forum = args[1].(*common.Forum)
|
var forum = args[1].(*c.Forum)
|
||||||
if forum.ParentType == "guild" {
|
if forum.ParentType == "guild" {
|
||||||
// This is why I hate using contexts, all the daisy chains and interface casts x.x
|
// This is why I hate using contexts, all the daisy chains and interface casts x.x
|
||||||
guildItem, ok := request.Context().Value("guilds_current_group").(*Guild)
|
guildItem, ok := request.Context().Value("guilds_current_group").(*Guild)
|
||||||
if !ok {
|
if !ok {
|
||||||
common.LogError(errors.New("Unable to find a parent group in the context data"))
|
c.LogError(errors.New("Unable to find a parent group in the context data"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
)
|
)
|
||||||
|
@ -38,18 +38,18 @@ func main() {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
log.Print("Loading the configuration data")
|
log.Print("Loading the configuration data")
|
||||||
err := common.LoadConfig()
|
err := c.LoadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print("Processing configuration data")
|
log.Print("Processing configuration data")
|
||||||
err = common.ProcessConfig()
|
err = c.ProcessConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if common.DbConfig.Adapter != "mysql" && common.DbConfig.Adapter != "" {
|
if c.DbConfig.Adapter != "mysql" && c.DbConfig.Adapter != "" {
|
||||||
log.Fatal("Only MySQL is supported for upgrades right now, please wait for a newer build of the patcher")
|
log.Fatal("Only MySQL is supported for upgrades right now, please wait for a newer build of the patcher")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,11 +74,11 @@ func pressAnyKey(scanner *bufio.Scanner) {
|
||||||
|
|
||||||
func prepMySQL() error {
|
func prepMySQL() error {
|
||||||
return qgen.Builder.Init("mysql", map[string]string{
|
return qgen.Builder.Init("mysql", map[string]string{
|
||||||
"host": common.DbConfig.Host,
|
"host": c.DbConfig.Host,
|
||||||
"port": common.DbConfig.Port,
|
"port": c.DbConfig.Port,
|
||||||
"name": common.DbConfig.Dbname,
|
"name": c.DbConfig.Dbname,
|
||||||
"username": common.DbConfig.Username,
|
"username": c.DbConfig.Username,
|
||||||
"password": common.DbConfig.Password,
|
"password": c.DbConfig.Password,
|
||||||
"collation": "utf8mb4_general_ci",
|
"collation": "utf8mb4_general_ci",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,12 +7,12 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Make this a static file somehow? Is it possible for us to put this file somewhere else?
|
// TODO: Make this a static file somehow? Is it possible for us to put this file somewhere else?
|
||||||
// TODO: Add an API so that plugins can register disallowed areas. E.g. /guilds/join for plugin_guilds
|
// TODO: Add an API so that plugins can register disallowed areas. E.g. /guilds/join for plugin_guilds
|
||||||
func RobotsTxt(w http.ResponseWriter, r *http.Request) common.RouteError {
|
func RobotsTxt(w http.ResponseWriter, r *http.Request) c.RouteError {
|
||||||
// TODO: Do we have to put * or something at the end of the paths?
|
// TODO: Do we have to put * or something at the end of the paths?
|
||||||
_, _ = w.Write([]byte(`User-agent: *
|
_, _ = w.Write([]byte(`User-agent: *
|
||||||
Disallow: /panel/*
|
Disallow: /panel/*
|
||||||
|
@ -32,14 +32,14 @@ func writeXMLHeader(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Keep track of when a sitemap was last modifed and add a lastmod element for it
|
// TODO: Keep track of when a sitemap was last modifed and add a lastmod element for it
|
||||||
func SitemapXml(w http.ResponseWriter, r *http.Request) common.RouteError {
|
func SitemapXml(w http.ResponseWriter, r *http.Request) c.RouteError {
|
||||||
var sslBit string
|
var sslBit string
|
||||||
if common.Site.EnableSsl {
|
if c.Site.EnableSsl {
|
||||||
sslBit = "s"
|
sslBit = "s"
|
||||||
}
|
}
|
||||||
var sitemapItem = func(path string) {
|
var sitemapItem = func(path string) {
|
||||||
w.Write([]byte(`<sitemap>
|
w.Write([]byte(`<sitemap>
|
||||||
<loc>http` + sslBit + `://` + common.Site.URL + "/" + path + `</loc>
|
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
|
||||||
</sitemap>
|
</sitemap>
|
||||||
`))
|
`))
|
||||||
}
|
}
|
||||||
|
@ -55,13 +55,13 @@ func SitemapXml(w http.ResponseWriter, r *http.Request) common.RouteError {
|
||||||
|
|
||||||
type FuzzyRoute struct {
|
type FuzzyRoute struct {
|
||||||
Path string
|
Path string
|
||||||
Handle func(http.ResponseWriter, *http.Request, int) common.RouteError
|
Handle func(http.ResponseWriter, *http.Request, int) c.RouteError
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add a sitemap API and clean things up
|
// TODO: Add a sitemap API and clean things up
|
||||||
// TODO: ^-- Make sure that the API is concurrent
|
// TODO: ^-- Make sure that the API is concurrent
|
||||||
// TODO: Add a social group sitemap
|
// TODO: Add a social group sitemap
|
||||||
var sitemapRoutes = map[string]func(http.ResponseWriter, *http.Request) common.RouteError{
|
var sitemapRoutes = map[string]func(http.ResponseWriter, *http.Request) c.RouteError{
|
||||||
"forums.xml": SitemapForums,
|
"forums.xml": SitemapForums,
|
||||||
"topics.xml": SitemapTopics,
|
"topics.xml": SitemapTopics,
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ var fuzzySitemapRoutes = map[string]FuzzyRoute{
|
||||||
"topics_page_": FuzzyRoute{"topics_page_(%d).xml", SitemapTopic},
|
"topics_page_": FuzzyRoute{"topics_page_(%d).xml", SitemapTopic},
|
||||||
}
|
}
|
||||||
|
|
||||||
func sitemapSwitch(w http.ResponseWriter, r *http.Request) common.RouteError {
|
func sitemapSwitch(w http.ResponseWriter, r *http.Request) c.RouteError {
|
||||||
var path = r.URL.Path[len("/sitemaps/"):]
|
var 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") {
|
||||||
|
@ -80,8 +80,8 @@ func sitemapSwitch(w http.ResponseWriter, r *http.Request) common.RouteError {
|
||||||
page, err := strconv.Atoi(spath)
|
page, err := strconv.Atoi(spath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// ? What's this? Do we need it? Was it just a quick trace?
|
// ? What's this? Do we need it? Was it just a quick trace?
|
||||||
common.DebugLogf("Unable to convert string '%s' to integer in fuzzy route", spath)
|
c.DebugLogf("Unable to convert string '%s' to integer in fuzzy route", spath)
|
||||||
return common.NotFound(w, r, nil)
|
return c.NotFound(w, r, nil)
|
||||||
}
|
}
|
||||||
return fuzzy.Handle(w, r, page)
|
return fuzzy.Handle(w, r, page)
|
||||||
}
|
}
|
||||||
|
@ -89,26 +89,26 @@ func sitemapSwitch(w http.ResponseWriter, r *http.Request) common.RouteError {
|
||||||
|
|
||||||
route, ok := sitemapRoutes[path]
|
route, ok := sitemapRoutes[path]
|
||||||
if !ok {
|
if !ok {
|
||||||
return common.NotFound(w, r, nil)
|
return c.NotFound(w, r, nil)
|
||||||
}
|
}
|
||||||
return route(w, r)
|
return route(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SitemapForums(w http.ResponseWriter, r *http.Request) common.RouteError {
|
func SitemapForums(w http.ResponseWriter, r *http.Request) c.RouteError {
|
||||||
var sslBit string
|
var sslBit string
|
||||||
if common.Site.EnableSsl {
|
if c.Site.EnableSsl {
|
||||||
sslBit = "s"
|
sslBit = "s"
|
||||||
}
|
}
|
||||||
var sitemapItem = func(path string) {
|
var sitemapItem = func(path string) {
|
||||||
w.Write([]byte(`<url>
|
w.Write([]byte(`<url>
|
||||||
<loc>http` + sslBit + `://` + common.Site.URL + path + `</loc>
|
<loc>http` + sslBit + `://` + c.Site.URL + path + `</loc>
|
||||||
</url>
|
</url>
|
||||||
`))
|
`))
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := common.Groups.Get(common.GuestUser.Group)
|
group, err := c.Groups.Get(c.GuestUser.Group)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.SilentInternalErrorXML(errors.New("The guest group doesn't exist for some reason"), w, r)
|
return c.SilentInternalErrorXML(errors.New("The guest group doesn't exist for some reason"), w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
writeXMLHeader(w, r)
|
writeXMLHeader(w, r)
|
||||||
|
@ -116,9 +116,9 @@ func SitemapForums(w http.ResponseWriter, r *http.Request) common.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 = common.Forums.DirtyGet(fid).Copy()
|
var forum = c.Forums.DirtyGet(fid).Copy()
|
||||||
if forum.ParentID == 0 && forum.Name != "" && forum.Active {
|
if forum.ParentID == 0 && forum.Name != "" && forum.Active {
|
||||||
sitemapItem(common.BuildForumURL(common.NameToSlug(forum.Name), forum.ID))
|
sitemapItem(c.BuildForumURL(c.NameToSlug(forum.Name), forum.ID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,34 +128,34 @@ func SitemapForums(w http.ResponseWriter, r *http.Request) common.RouteError {
|
||||||
|
|
||||||
// TODO: Add a global ratelimit. 10 50MB files (smaller if compressed better) per minute?
|
// TODO: Add a global ratelimit. 10 50MB files (smaller if compressed better) per minute?
|
||||||
// ? We might have problems with banned users, if they have fewer ViewTopic permissions than guests as they'll be able to see this list. Then again, a banned user could just logout to see it
|
// ? We might have problems with banned users, if they have fewer ViewTopic permissions than guests as they'll be able to see this list. Then again, a banned user could just logout to see it
|
||||||
func SitemapTopics(w http.ResponseWriter, r *http.Request) common.RouteError {
|
func SitemapTopics(w http.ResponseWriter, r *http.Request) c.RouteError {
|
||||||
var sslBit string
|
var sslBit string
|
||||||
if common.Site.EnableSsl {
|
if c.Site.EnableSsl {
|
||||||
sslBit = "s"
|
sslBit = "s"
|
||||||
}
|
}
|
||||||
var sitemapItem = func(path string) {
|
var sitemapItem = func(path string) {
|
||||||
w.Write([]byte(`<sitemap>
|
w.Write([]byte(`<sitemap>
|
||||||
<loc>http` + sslBit + `://` + common.Site.URL + "/" + path + `</loc>
|
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
|
||||||
</sitemap>
|
</sitemap>
|
||||||
`))
|
`))
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := common.Groups.Get(common.GuestUser.Group)
|
group, err := c.Groups.Get(c.GuestUser.Group)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.SilentInternalErrorXML(errors.New("The guest group doesn't exist for some reason"), w, r)
|
return c.SilentInternalErrorXML(errors.New("The guest group doesn't exist for some reason"), w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var visibleForums []common.Forum
|
var visibleForums []c.Forum
|
||||||
for _, fid := range group.CanSee {
|
for _, fid := range group.CanSee {
|
||||||
forum := common.Forums.DirtyGet(fid)
|
forum := c.Forums.DirtyGet(fid)
|
||||||
if forum.Name != "" && forum.Active {
|
if forum.Name != "" && forum.Active {
|
||||||
visibleForums = append(visibleForums, forum.Copy())
|
visibleForums = append(visibleForums, forum.Copy())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
topicCount, err := common.TopicCountInForums(visibleForums)
|
topicCount, err := c.TopicCountInForums(visibleForums)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorXML(err, w, r)
|
return c.InternalErrorXML(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var pageCount = topicCount / sitemapPageCap
|
var pageCount = topicCount / sitemapPageCap
|
||||||
|
@ -170,35 +170,35 @@ func SitemapTopics(w http.ResponseWriter, r *http.Request) common.RouteError {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SitemapTopic(w http.ResponseWriter, r *http.Request, page int) common.RouteError {
|
func SitemapTopic(w http.ResponseWriter, r *http.Request, page int) c.RouteError {
|
||||||
/*var sslBit string
|
/*var sslBit string
|
||||||
if common.Site.EnableSsl {
|
if c.Site.EnableSsl {
|
||||||
sslBit = "s"
|
sslBit = "s"
|
||||||
}
|
}
|
||||||
var sitemapItem = func(path string) {
|
var sitemapItem = func(path string) {
|
||||||
w.Write([]byte(`<url>
|
w.Write([]byte(`<url>
|
||||||
<loc>http` + sslBit + `://` + common.Site.URL + "/" + path + `</loc>
|
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
|
||||||
</url>
|
</url>
|
||||||
`))
|
`))
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
group, err := common.Groups.Get(common.GuestUser.Group)
|
group, err := c.Groups.Get(c.GuestUser.Group)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.SilentInternalErrorXML(errors.New("The guest group doesn't exist for some reason"), w, r)
|
return c.SilentInternalErrorXML(errors.New("The guest group doesn't exist for some reason"), w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var visibleForums []common.Forum
|
var visibleForums []c.Forum
|
||||||
for _, fid := range group.CanSee {
|
for _, fid := range group.CanSee {
|
||||||
forum := common.Forums.DirtyGet(fid)
|
forum := c.Forums.DirtyGet(fid)
|
||||||
if forum.Name != "" && forum.Active {
|
if forum.Name != "" && forum.Active {
|
||||||
visibleForums = append(visibleForums, forum.Copy())
|
visibleForums = append(visibleForums, forum.Copy())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argList, qlist := common.ForumListToArgQ(visibleForums)
|
argList, qlist := c.ForumListToArgQ(visibleForums)
|
||||||
topicCount, err := common.ArgQToTopicCount(argList, qlist)
|
topicCount, err := c.ArgQToTopicCount(argList, qlist)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorXML(err, w, r)
|
return c.InternalErrorXML(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var pageCount = topicCount / sitemapPageCap
|
var pageCount = topicCount / sitemapPageCap
|
||||||
|
@ -216,18 +216,18 @@ func SitemapTopic(w http.ResponseWriter, r *http.Request, page int) common.Route
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SitemapUsers(w http.ResponseWriter, r *http.Request) common.RouteError {
|
func SitemapUsers(w http.ResponseWriter, r *http.Request) c.RouteError {
|
||||||
writeXMLHeader(w, r)
|
writeXMLHeader(w, r)
|
||||||
w.Write([]byte("<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n"))
|
w.Write([]byte("<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n"))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type JsonMe struct {
|
type JsonMe struct {
|
||||||
User *common.MeUser
|
User *c.MeUser
|
||||||
Site MeSite
|
Site MeSite
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't want to expose too much information about the site, so we'll make this a small subset of common.site
|
// We don't want to expose too much information about the site, so we'll make this a small subset of c.site
|
||||||
type MeSite struct {
|
type MeSite struct {
|
||||||
MaxRequestSize int
|
MaxRequestSize int
|
||||||
}
|
}
|
||||||
|
@ -235,18 +235,18 @@ type MeSite struct {
|
||||||
// APIMe returns information about the current logged-in user
|
// APIMe returns information about the current logged-in user
|
||||||
// TODO: Find some way to stop intermediaries from doing compression to avoid the BREACH attack
|
// TODO: Find some way to stop intermediaries from doing compression to avoid the BREACH attack
|
||||||
// TODO: Decouple site settings into a different API? I'd like to avoid having too many requests, if possible, maybe we can use a different name for this?
|
// TODO: Decouple site settings into a different API? I'd like to avoid having too many requests, if possible, maybe we can use a different name for this?
|
||||||
func APIMe(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func APIMe(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
// TODO: Don't make this too JSON dependent so that we can swap in newer more efficient formats
|
// TODO: Don't make this too JSON dependent so that we can swap in newer more efficient formats
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
// We don't want an intermediary accidentally caching this
|
// We don't want an intermediary accidentally caching this
|
||||||
// TODO: Use this header anywhere with a user check?
|
// TODO: Use this header anywhere with a user check?
|
||||||
w.Header().Set("Cache-Control", "private")
|
w.Header().Set("Cache-Control", "private")
|
||||||
|
|
||||||
me := JsonMe{(&user).Me(), MeSite{common.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 common.InternalErrorJS(err, w, r)
|
return c.InternalErrorJS(err, w, r)
|
||||||
}
|
}
|
||||||
w.Write(jsonBytes)
|
w.Write(jsonBytes)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ var attachmentStmts AttachmentStmts
|
||||||
|
|
||||||
// TODO: Abstract this with an attachment store
|
// TODO: Abstract this with an attachment store
|
||||||
func init() {
|
func init() {
|
||||||
common.DbInits.Add(func(acc *qgen.Accumulator) error {
|
c.DbInits.Add(func(acc *qgen.Accumulator) error {
|
||||||
attachmentStmts = AttachmentStmts{
|
attachmentStmts = AttachmentStmts{
|
||||||
get: acc.Select("attachments").Columns("sectionID, sectionTable, originID, originTable, uploadedBy, path").Where("path = ? AND sectionID = ? AND sectionTable = ?").Prepare(),
|
get: acc.Select("attachments").Columns("sectionID, sectionTable, originID, originTable, uploadedBy, path").Where("path = ? AND sectionID = ? AND sectionTable = ?").Prepare(),
|
||||||
}
|
}
|
||||||
|
@ -28,16 +28,16 @@ func init() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func ShowAttachment(w http.ResponseWriter, r *http.Request, user common.User, filename string) common.RouteError {
|
func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filename string) c.RouteError {
|
||||||
filename = common.Stripslashes(filename)
|
filename = c.Stripslashes(filename)
|
||||||
var ext = filepath.Ext("./attachs/" + filename)
|
var ext = filepath.Ext("./attachs/" + filename)
|
||||||
if !common.AllowedFileExts.Contains(strings.TrimPrefix(ext, ".")) {
|
if !c.AllowedFileExts.Contains(strings.TrimPrefix(ext, ".")) {
|
||||||
return common.LocalError("Bad extension", w, r, user)
|
return c.LocalError("Bad extension", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
sectionID, err := strconv.Atoi(r.FormValue("sectionID"))
|
sectionID, err := strconv.Atoi(r.FormValue("sectionID"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("The sectionID is not an integer", w, r, user)
|
return c.LocalError("The sectionID is not an integer", w, r, user)
|
||||||
}
|
}
|
||||||
var sectionTable = r.FormValue("sectionType")
|
var sectionTable = r.FormValue("sectionType")
|
||||||
|
|
||||||
|
@ -45,37 +45,37 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user common.User, fi
|
||||||
var originID, uploadedBy int
|
var originID, uploadedBy int
|
||||||
err = attachmentStmts.get.QueryRow(filename, sectionID, sectionTable).Scan(§ionID, §ionTable, &originID, &originTable, &uploadedBy, &filename)
|
err = attachmentStmts.get.QueryRow(filename, sectionID, sectionTable).Scan(§ionID, §ionTable, &originID, &originTable, &uploadedBy, &filename)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.NotFound(w, r, nil)
|
return c.NotFound(w, r, nil)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if sectionTable == "forums" {
|
if sectionTable == "forums" {
|
||||||
_, ferr := common.SimpleForumUserCheck(w, r, &user, sectionID)
|
_, ferr := c.SimpleForumUserCheck(w, r, &user, sectionID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic {
|
if !user.Perms.ViewTopic {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return common.LocalError("Unknown section", w, r, user)
|
return c.LocalError("Unknown section", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
if originTable != "topics" && originTable != "replies" {
|
if originTable != "topics" && originTable != "replies" {
|
||||||
return common.LocalError("Unknown origin", w, r, user)
|
return c.LocalError("Unknown origin", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !user.Loggedin {
|
if !user.Loggedin {
|
||||||
w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(common.Year)))
|
w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(c.Year)))
|
||||||
} else {
|
} else {
|
||||||
guest := common.GuestUser
|
guest := c.GuestUser
|
||||||
_, ferr := common.SimpleForumUserCheck(w, r, &guest, sectionID)
|
_, ferr := c.SimpleForumUserCheck(w, r, &guest, sectionID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if guest.Perms.ViewTopic {
|
if guest.Perms.ViewTopic {
|
||||||
w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(common.Year)))
|
w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(c.Year)))
|
||||||
} else {
|
} else {
|
||||||
w.Header().Set("Cache-Control", "private")
|
w.Header().Set("Cache-Control", "private")
|
||||||
}
|
}
|
||||||
|
@ -87,27 +87,27 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user common.User, fi
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add a table for the files and lock the file row when performing tasks related to the file
|
// TODO: Add a table for the files and lock the file row when performing tasks related to the file
|
||||||
func deleteAttachment(w http.ResponseWriter, r *http.Request, user common.User, aid int, js bool) common.RouteError {
|
func deleteAttachment(w http.ResponseWriter, r *http.Request, user c.User, aid int, js bool) c.RouteError {
|
||||||
attach, err := common.Attachments.Get(aid)
|
attach, err := c.Attachments.Get(aid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.NotFoundJSQ(w, r, nil, js)
|
return c.NotFoundJSQ(w, r, nil, js)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = common.Attachments.Delete(aid)
|
err = c.Attachments.Delete(aid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
count := common.Attachments.CountInPath(attach.Path)
|
count := c.Attachments.CountInPath(attach.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
err := os.Remove("./attachs/" + attach.Path)
|
err := os.Remove("./attachs/" + attach.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ func deleteAttachment(w http.ResponseWriter, r *http.Request, user common.User,
|
||||||
// TODO: Stop duplicating this code
|
// TODO: Stop duplicating this code
|
||||||
// TODO: Use a transaction here
|
// TODO: Use a transaction here
|
||||||
// TODO: Move this function to neutral ground
|
// TODO: Move this function to neutral ground
|
||||||
func uploadAttachment(w http.ResponseWriter, r *http.Request, user common.User, sid int, sectionTable string, oid int, originTable string, extra string) (pathMap map[string]string, rerr common.RouteError) {
|
func uploadAttachment(w http.ResponseWriter, r *http.Request, user c.User, sid int, sectionTable string, oid int, originTable string, extra string) (pathMap map[string]string, rerr c.RouteError) {
|
||||||
pathMap = make(map[string]string)
|
pathMap = make(map[string]string)
|
||||||
files, rerr := uploadFilesWithHash(w, r, user, "./attachs/")
|
files, rerr := uploadFilesWithHash(w, r, user, "./attachs/")
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
|
@ -125,9 +125,9 @@ func uploadAttachment(w http.ResponseWriter, r *http.Request, user common.User,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, filename := range files {
|
for _, filename := range files {
|
||||||
aid, err := common.Attachments.Add(sid, sectionTable, oid, originTable, user.ID, filename, extra)
|
aid, err := c.Attachments.Add(sid, sectionTable, oid, originTable, user.ID, filename, extra)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, common.InternalError(err, w, r)
|
return nil, c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, ok := pathMap[filename]
|
_, ok := pathMap[filename]
|
||||||
|
@ -139,18 +139,18 @@ func uploadAttachment(w http.ResponseWriter, r *http.Request, user common.User,
|
||||||
|
|
||||||
switch originTable {
|
switch originTable {
|
||||||
case "topics":
|
case "topics":
|
||||||
_, err = topicStmts.updateAttachs.Exec(common.Attachments.CountIn(originTable, oid), oid)
|
_, err = topicStmts.updateAttachs.Exec(c.Attachments.CountIn(originTable, oid), oid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, common.InternalError(err, w, r)
|
return nil, c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
err = common.Topics.Reload(oid)
|
err = c.Topics.Reload(oid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, common.InternalError(err, w, r)
|
return nil, c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
case "replies":
|
case "replies":
|
||||||
_, err = replyStmts.updateAttachs.Exec(common.Attachments.CountIn(originTable, oid), oid)
|
_, err = replyStmts.updateAttachs.Exec(c.Attachments.CountIn(originTable, oid), oid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, common.InternalError(err, w, r)
|
return nil, c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var successJSONBytes = []byte(`{"success":"1"}`)
|
var successJSONBytes = []byte(`{"success":"1"}`)
|
||||||
|
@ -21,9 +21,9 @@ func ParseSEOURL(urlBit string) (slug string, id int, err error) {
|
||||||
return halves[0], tid, err
|
return halves[0], tid, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func doPush(w http.ResponseWriter, header *common.Header) {
|
func doPush(w http.ResponseWriter, header *c.Header) {
|
||||||
//fmt.Println("in doPush")
|
//fmt.Println("in doPush")
|
||||||
if common.Config.EnableCDNPush {
|
if c.Config.EnableCDNPush {
|
||||||
// TODO: Faster string building...
|
// TODO: Faster string building...
|
||||||
var sbuf string
|
var sbuf string
|
||||||
var push = func(in []string) {
|
var push = func(in []string) {
|
||||||
|
@ -46,9 +46,9 @@ func doPush(w http.ResponseWriter, header *common.Header) {
|
||||||
sbuf = sbuf[:len(sbuf)-1]
|
sbuf = sbuf[:len(sbuf)-1]
|
||||||
w.Header().Set("Link", sbuf)
|
w.Header().Set("Link", sbuf)
|
||||||
}
|
}
|
||||||
} else if !common.Config.DisableServerPush {
|
} else if !c.Config.DisableServerPush {
|
||||||
//fmt.Println("push enabled")
|
//fmt.Println("push enabled")
|
||||||
gzw, ok := w.(common.GzipResponseWriter)
|
gzw, ok := w.(c.GzipResponseWriter)
|
||||||
if ok {
|
if ok {
|
||||||
w = gzw.ResponseWriter
|
w = gzw.ResponseWriter
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ func doPush(w http.ResponseWriter, header *common.Header) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *common.Header, pi interface{}) common.RouteError {
|
func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) c.RouteError {
|
||||||
if header.CurrentUser.Loggedin {
|
if header.CurrentUser.Loggedin {
|
||||||
header.MetaDesc = ""
|
header.MetaDesc = ""
|
||||||
header.OGDesc = ""
|
header.OGDesc = ""
|
||||||
|
@ -83,7 +83,7 @@ func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, hea
|
||||||
header.OGDesc = header.MetaDesc
|
header.OGDesc = header.MetaDesc
|
||||||
}
|
}
|
||||||
// TODO: Expand this to non-HTTPS requests too
|
// TODO: Expand this to non-HTTPS requests too
|
||||||
if !header.LooseCSP && common.Site.EnableSsl {
|
if !header.LooseCSP && c.Site.EnableSsl {
|
||||||
w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self' www.youtube-nocookie.com;upgrade-insecure-requests")
|
w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self' www.youtube-nocookie.com;upgrade-insecure-requests")
|
||||||
}
|
}
|
||||||
header.AddScript("global.js")
|
header.AddScript("global.js")
|
||||||
|
@ -98,12 +98,12 @@ func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, hea
|
||||||
if header.CurrentUser.IsAdmin {
|
if header.CurrentUser.IsAdmin {
|
||||||
header.Elapsed1 = time.Since(header.StartedAt).String()
|
header.Elapsed1 = time.Since(header.StartedAt).String()
|
||||||
}
|
}
|
||||||
if common.RunPreRenderHook("pre_render_"+tmplName, w, r, &header.CurrentUser, pi) {
|
if c.RunPreRenderHook("pre_render_"+tmplName, w, r, &header.CurrentUser, pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := header.Theme.RunTmpl(tmplName, pi, w)
|
err := header.Theme.RunTmpl(tmplName, pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"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"
|
"github.com/Azareal/Gosora/common/phrases"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
|
@ -19,7 +19,7 @@ var forumStmts ForumStmts
|
||||||
|
|
||||||
// TODO: Move these DbInits into *Forum as Topics()
|
// TODO: Move these DbInits into *Forum as Topics()
|
||||||
func init() {
|
func init() {
|
||||||
common.DbInits.Add(func(acc *qgen.Accumulator) error {
|
c.DbInits.Add(func(acc *qgen.Accumulator) error {
|
||||||
forumStmts = ForumStmts{
|
forumStmts = ForumStmts{
|
||||||
getTopics: acc.Select("topics").Columns("tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, lastReplyID, parentID, views, postCount, likeCount").Where("parentID = ?").Orderby("sticky DESC, lastReplyAt DESC, createdBy DESC").Limit("?,?").Prepare(),
|
getTopics: acc.Select("topics").Columns("tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, lastReplyID, parentID, views, postCount, likeCount").Where("parentID = ?").Orderby("sticky DESC, lastReplyAt DESC, createdBy DESC").Limit("?,?").Prepare(),
|
||||||
}
|
}
|
||||||
|
@ -28,55 +28,55 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Retire this in favour of an alias for /topics/?
|
// TODO: Retire this in favour of an alias for /topics/?
|
||||||
func ViewForum(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header, sfid string) common.RouteError {
|
func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header, sfid string) c.RouteError {
|
||||||
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 common.PreError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r)
|
return c.PreError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
ferr := common.ForumUserCheck(header, w, r, &user, fid)
|
ferr := c.ForumUserCheck(header, w, r, &user, fid)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic {
|
if !user.Perms.ViewTopic {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
header.Path = "/forums/"
|
header.Path = "/forums/"
|
||||||
|
|
||||||
// TODO: Fix this double-check
|
// TODO: Fix this double-check
|
||||||
forum, err := common.Forums.Get(fid)
|
forum, err := c.Forums.Get(fid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.NotFound(w, r, header)
|
return c.NotFound(w, r, header)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
header.Title = forum.Name
|
header.Title = forum.Name
|
||||||
header.OGDesc = forum.Desc
|
header.OGDesc = forum.Desc
|
||||||
|
|
||||||
// TODO: Does forum.TopicCount take the deleted items into consideration for guests? We don't have soft-delete yet, only hard-delete
|
// TODO: Does forum.TopicCount take the deleted items into consideration for guests? We don't have soft-delete yet, only hard-delete
|
||||||
offset, page, lastPage := common.PageOffset(forum.TopicCount, page, common.Config.ItemsPerPage)
|
offset, page, lastPage := c.PageOffset(forum.TopicCount, page, c.Config.ItemsPerPage)
|
||||||
|
|
||||||
// TODO: Move this to *Forum
|
// TODO: Move this to *Forum
|
||||||
rows, err := forumStmts.getTopics.Query(fid, offset, common.Config.ItemsPerPage)
|
rows, err := forumStmts.getTopics.Query(fid, offset, c.Config.ItemsPerPage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
// 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 []*common.TopicsRow
|
var topicList []*c.TopicsRow
|
||||||
var reqUserList = make(map[int]bool)
|
var reqUserList = make(map[int]bool)
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var topicItem = common.TopicsRow{ID: 0}
|
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)
|
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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
topicItem.Link = common.BuildTopicURL(common.NameToSlug(topicItem.Title), topicItem.ID)
|
topicItem.Link = c.BuildTopicURL(c.NameToSlug(topicItem.Title), topicItem.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 := common.PageOffset(topicItem.PostCount, 1, common.Config.ItemsPerPage)
|
_, _, lastPage := c.PageOffset(topicItem.PostCount, 1, c.Config.ItemsPerPage)
|
||||||
topicItem.LastPage = lastPage
|
topicItem.LastPage = lastPage
|
||||||
|
|
||||||
header.Hooks.VhookNoRet("forum_trow_assign", &topicItem, &forum)
|
header.Hooks.VhookNoRet("forum_trow_assign", &topicItem, &forum)
|
||||||
|
@ -86,7 +86,7 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user common.User, header
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
err = rows.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -98,9 +98,9 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user common.User, header
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: What if a user is deleted via the Control Panel?
|
// TODO: What if a user is deleted via the Control Panel?
|
||||||
userList, err := common.Users.BulkGetMap(idSlice)
|
userList, err := c.Users.BulkGetMap(idSlice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second pass to the add the user data
|
// Second pass to the add the user data
|
||||||
|
@ -116,14 +116,14 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user common.User, header
|
||||||
if r.FormValue("js") == "1" {
|
if r.FormValue("js") == "1" {
|
||||||
outBytes, err := wsTopicList(topicList, lastPage).MarshalJSON()
|
outBytes, err := wsTopicList(topicList, lastPage).MarshalJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
w.Write(outBytes)
|
w.Write(outBytes)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
pageList := common.Paginate(forum.TopicCount, common.Config.ItemsPerPage, 5)
|
pageList := c.Paginate(forum.TopicCount, c.Config.ItemsPerPage, 5)
|
||||||
pi := common.ForumPage{header, topicList, forum, common.Paginator{pageList, page, lastPage}}
|
pi := c.ForumPage{header, topicList, forum, c.Paginator{pageList, page, lastPage}}
|
||||||
ferr = renderTemplate("forum", w, r, header, pi)
|
ferr = renderTemplate("forum", w, r, header, pi)
|
||||||
counters.ForumViewCounter.Bump(forum.ID)
|
counters.ForumViewCounter.Bump(forum.ID)
|
||||||
return ferr
|
return ferr
|
||||||
|
|
|
@ -4,40 +4,40 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/common/phrases"
|
"github.com/Azareal/Gosora/common/phrases"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ForumList(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
|
func ForumList(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
|
||||||
header.Title = phrases.GetTitlePhrase("forums")
|
header.Title = phrases.GetTitlePhrase("forums")
|
||||||
header.Zone = "forums"
|
header.Zone = "forums"
|
||||||
header.Path = "/forums/"
|
header.Path = "/forums/"
|
||||||
header.MetaDesc = header.Settings["meta_desc"].(string)
|
header.MetaDesc = header.Settings["meta_desc"].(string)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var forumList []common.Forum
|
var forumList []c.Forum
|
||||||
var canSee []int
|
var canSee []int
|
||||||
if user.IsSuperAdmin {
|
if user.IsSuperAdmin {
|
||||||
canSee, err = common.Forums.GetAllVisibleIDs()
|
canSee, err = c.Forums.GetAllVisibleIDs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
group, err := common.Groups.Get(user.Group)
|
group, err := c.Groups.Get(user.Group)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Group #%d doesn't exist despite being used by common.User #%d", user.Group, user.ID)
|
log.Printf("Group #%d doesn't exist despite being used by c.User #%d", user.Group, user.ID)
|
||||||
return common.LocalError("Something weird happened", w, r, user)
|
return c.LocalError("Something weird happened", w, r, user)
|
||||||
}
|
}
|
||||||
canSee = group.CanSee
|
canSee = group.CanSee
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fid := range canSee {
|
for _, fid := range 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 = common.Forums.DirtyGet(fid).Copy()
|
var forum = c.Forums.DirtyGet(fid).Copy()
|
||||||
if forum.ParentID == 0 && forum.Name != "" && forum.Active {
|
if forum.ParentID == 0 && forum.Name != "" && forum.Active {
|
||||||
if forum.LastTopicID != 0 {
|
if forum.LastTopicID != 0 {
|
||||||
if forum.LastTopic.ID != 0 && forum.LastReplyer.ID != 0 {
|
if forum.LastTopic.ID != 0 && forum.LastReplyer.ID != 0 {
|
||||||
forum.LastTopicTime = common.RelativeTime(forum.LastTopic.LastReplyAt)
|
forum.LastTopicTime = c.RelativeTime(forum.LastTopic.LastReplyAt)
|
||||||
} else {
|
} else {
|
||||||
forum.LastTopicTime = ""
|
forum.LastTopicTime = ""
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,6 @@ func ForumList(w http.ResponseWriter, r *http.Request, user common.User, header
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.ForumsPage{header, forumList}
|
pi := c.ForumsPage{header, forumList}
|
||||||
return renderTemplate("forums", w, r, header, pi)
|
return renderTemplate("forums", w, r, header, pi)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,17 +9,17 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/common/phrases"
|
"github.com/Azareal/Gosora/common/phrases"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cacheControlMaxAge = "max-age=" + strconv.Itoa(int(common.Day)) // TODO: Make this a common.Config value
|
var cacheControlMaxAge = "max-age=" + strconv.Itoa(int(c.Day)) // TODO: Make this a c.Config value
|
||||||
|
|
||||||
// GET functions
|
// GET functions
|
||||||
func StaticFile(w http.ResponseWriter, r *http.Request) {
|
func StaticFile(w http.ResponseWriter, r *http.Request) {
|
||||||
file, ok := common.StaticFiles.Get(r.URL.Path)
|
file, ok := c.StaticFiles.Get(r.URL.Path)
|
||||||
if !ok {
|
if !ok {
|
||||||
common.DebugLogf("Failed to find '%s'", r.URL.Path) // TODO: Use MicroNotFound? Might be better than the unneccessary overhead of sprintf
|
c.DebugLogf("Failed to find '%s'", r.URL.Path) // TODO: Use MicroNotFound? Might be better than the unneccessary overhead of sprintf
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -47,56 +47,56 @@ func StaticFile(w http.ResponseWriter, r *http.Request) {
|
||||||
// Other options instead of io.Copy: io.CopyN(), w.Write(), http.ServeContent()
|
// Other options instead of io.Copy: io.CopyN(), w.Write(), http.ServeContent()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Overview(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
|
func Overview(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
|
||||||
header.Title = phrases.GetTitlePhrase("overview")
|
header.Title = phrases.GetTitlePhrase("overview")
|
||||||
header.Zone = "overview"
|
header.Zone = "overview"
|
||||||
pi := common.Page{header, tList, nil}
|
pi := c.Page{header, tList, nil}
|
||||||
return renderTemplate("overview", w, r, header, pi)
|
return renderTemplate("overview", w, r, header, pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CustomPage(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header, name string) common.RouteError {
|
func CustomPage(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header, name string) c.RouteError {
|
||||||
header.Zone = "custom_page"
|
header.Zone = "custom_page"
|
||||||
name = common.SanitiseSingleLine(name)
|
name = c.SanitiseSingleLine(name)
|
||||||
page, err := common.Pages.GetByName(name)
|
page, err := c.Pages.GetByName(name)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
header.Title = page.Title
|
header.Title = page.Title
|
||||||
pi := common.CustomPagePage{header, page}
|
pi := c.CustomPagePage{header, page}
|
||||||
return renderTemplate("custom_page", w, r, header, pi)
|
return renderTemplate("custom_page", w, r, header, pi)
|
||||||
} else if err != sql.ErrNoRows {
|
} else if err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ! Is this safe?
|
// ! Is this safe?
|
||||||
if common.DefaultTemplates.Lookup("page_"+name+".html") == nil {
|
if c.DefaultTemplates.Lookup("page_"+name+".html") == nil {
|
||||||
return common.NotFound(w, r, header)
|
return c.NotFound(w, r, header)
|
||||||
}
|
}
|
||||||
|
|
||||||
header.Title = phrases.GetTitlePhrase("page")
|
header.Title = phrases.GetTitlePhrase("page")
|
||||||
pi := common.Page{header, tList, nil}
|
pi := c.Page{header, tList, nil}
|
||||||
// TODO: Pass the page name to the pre-render hook?
|
// TODO: Pass the page name to the pre-render hook?
|
||||||
if common.RunPreRenderHook("pre_render_tmpl_page", w, r, &user, &pi) {
|
if c.RunPreRenderHook("pre_render_tmpl_page", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err = header.Theme.RunTmpl("page_"+name, pi, w)
|
err = header.Theme.RunTmpl("page_"+name, pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Set the cookie domain
|
// TODO: Set the cookie domain
|
||||||
func ChangeTheme(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func ChangeTheme(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
//headerLite, _ := SimpleUserCheck(w, r, &user)
|
//headerLite, _ := SimpleUserCheck(w, r, &user)
|
||||||
// TODO: Rename isJs to something else, just in case we rewrite the JS side in WebAssembly?
|
// TODO: Rename isJs to something else, just in case we rewrite the JS side in WebAssembly?
|
||||||
isJs := (r.PostFormValue("isJs") == "1")
|
isJs := (r.PostFormValue("isJs") == "1")
|
||||||
newTheme := common.SanitiseSingleLine(r.PostFormValue("newTheme"))
|
newTheme := c.SanitiseSingleLine(r.PostFormValue("newTheme"))
|
||||||
|
|
||||||
theme, ok := common.Themes[newTheme]
|
theme, ok := c.Themes[newTheme]
|
||||||
if !ok || theme.HideFromThemes {
|
if !ok || theme.HideFromThemes {
|
||||||
return common.LocalErrorJSQ("That theme doesn't exist", w, r, user, isJs)
|
return c.LocalErrorJSQ("That theme doesn't exist", w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: int(common.Year)}
|
cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: int(c.Year)}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
|
|
||||||
if !isJs {
|
if !isJs {
|
||||||
|
|
|
@ -3,37 +3,37 @@ package routes
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/common/phrases"
|
"github.com/Azareal/Gosora/common/phrases"
|
||||||
)
|
)
|
||||||
|
|
||||||
func IPSearch(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
|
func IPSearch(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
|
||||||
header.Title = phrases.GetTitlePhrase("ip_search")
|
header.Title = phrases.GetTitlePhrase("ip_search")
|
||||||
// TODO: How should we handle the permissions if we extend this into an alt detector of sorts?
|
// TODO: How should we handle the permissions if we extend this into an alt detector of sorts?
|
||||||
if !user.Perms.ViewIPs {
|
if !user.Perms.ViewIPs {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Reject IP Addresses with illegal characters
|
// TODO: Reject IP Addresses with illegal characters
|
||||||
var ip = common.SanitiseSingleLine(r.FormValue("ip"))
|
var ip = c.SanitiseSingleLine(r.FormValue("ip"))
|
||||||
uids, err := common.IPSearch.Lookup(ip)
|
uids, err := c.IPSearch.Lookup(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: What if a user is deleted via the Control Panel? We'll cross that bridge when we come to it, although we might lean towards blanking the account and removing the related data rather than purging it
|
// TODO: What if a user is deleted via the Control Panel? We'll cross that bridge when we come to it, although we might lean towards blanking the account and removing the related data rather than purging it
|
||||||
userList, err := common.Users.BulkGetMap(uids)
|
userList, err := c.Users.BulkGetMap(uids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.IPSearchPage{header, userList, ip}
|
pi := c.IPSearchPage{header, userList, ip}
|
||||||
if common.RunPreRenderHook("pre_render_ip_search", w, r, &user, &pi) {
|
if c.RunPreRenderHook("pre_render_ip_search", w, r, &user, &pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err = header.Theme.RunTmpl("ip_search", pi, w)
|
err = header.Theme.RunTmpl("ip_search", pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/common/phrases"
|
"github.com/Azareal/Gosora/common/phrases"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
@ -103,7 +103,7 @@ func analyticsRowsToViewMap(rows *sql.Rows, labelList []int64, viewMap map[int64
|
||||||
}
|
}
|
||||||
var unixCreatedAt = createdAt.Unix()
|
var unixCreatedAt = createdAt.Unix()
|
||||||
// TODO: Bulk log this
|
// TODO: Bulk log this
|
||||||
if common.Dev.SuperDebug {
|
if c.Dev.SuperDebug {
|
||||||
log.Print("count: ", count)
|
log.Print("count: ", count)
|
||||||
log.Print("createdAt: ", createdAt)
|
log.Print("createdAt: ", createdAt)
|
||||||
log.Print("unixCreatedAt: ", unixCreatedAt)
|
log.Print("unixCreatedAt: ", unixCreatedAt)
|
||||||
|
@ -118,7 +118,7 @@ func analyticsRowsToViewMap(rows *sql.Rows, labelList []int64, viewMap map[int64
|
||||||
return viewMap, rows.Err()
|
return viewMap, rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func PreAnalyticsDetail(w http.ResponseWriter, r *http.Request, user *common.User) (*common.BasePanelPage, common.RouteError) {
|
func PreAnalyticsDetail(w http.ResponseWriter, r *http.Request, user *c.User) (*c.BasePanelPage, c.RouteError) {
|
||||||
basePage, ferr := buildBasePage(w, r, user, "analytics", "analytics")
|
basePage, ferr := buildBasePage(w, r, user, "analytics", "analytics")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return nil, ferr
|
return nil, ferr
|
||||||
|
@ -129,336 +129,336 @@ func PreAnalyticsDetail(w http.ResponseWriter, r *http.Request, user *common.Use
|
||||||
return basePage, nil
|
return basePage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsViews(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func AnalyticsViews(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
common.DebugLog("in panel.AnalyticsViews")
|
c.DebugLog("in panel.AnalyticsViews")
|
||||||
// TODO: Add some sort of analytics store / iterator?
|
// TODO: Add some sort of analytics store / iterator?
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks").Columns("count, createdAt").Where("route = ''").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
rows, err := qgen.NewAcc().Select("viewchunks").Columns("count, createdAt").Where("route = ''").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewList []int64
|
var viewList []int64
|
||||||
var viewItems []common.PanelAnalyticsItem
|
var viewItems []c.PanelAnalyticsItem
|
||||||
for _, value := range revLabelList {
|
for _, value := range revLabelList {
|
||||||
viewList = append(viewList, viewMap[value])
|
viewList = append(viewList, viewMap[value])
|
||||||
viewItems = append(viewItems, common.PanelAnalyticsItem{Time: value, Count: viewMap[value]})
|
viewItems = append(viewItems, c.PanelAnalyticsItem{Time: value, Count: viewMap[value]})
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
var ttime string
|
var ttime string
|
||||||
if timeRange.Range == "six-hours" || timeRange.Range == "twelve-hours" || timeRange.Range == "one-day" {
|
if timeRange.Range == "six-hours" || timeRange.Range == "twelve-hours" || timeRange.Range == "one-day" {
|
||||||
ttime = "time"
|
ttime = "time"
|
||||||
}
|
}
|
||||||
pi := common.PanelAnalyticsPage{basePage, graph, viewItems, timeRange.Range, timeRange.Unit, ttime}
|
pi := c.PanelAnalyticsPage{basePage, graph, viewItems, timeRange.Range, timeRange.Unit, ttime}
|
||||||
return renderTemplate("panel_analytics_views", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_views", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsRouteViews(w http.ResponseWriter, r *http.Request, user common.User, route string) common.RouteError {
|
func AnalyticsRouteViews(w http.ResponseWriter, r *http.Request, user c.User, route string) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
common.DebugLog("in panel.AnalyticsRouteViews")
|
c.DebugLog("in panel.AnalyticsRouteViews")
|
||||||
// TODO: Validate the route is valid
|
// TODO: Validate the route is valid
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks").Columns("count, createdAt").Where("route = ?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(route)
|
rows, err := qgen.NewAcc().Select("viewchunks").Columns("count, createdAt").Where("route = ?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(route)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewList []int64
|
var viewList []int64
|
||||||
var viewItems []common.PanelAnalyticsItem
|
var viewItems []c.PanelAnalyticsItem
|
||||||
for _, value := range revLabelList {
|
for _, value := range revLabelList {
|
||||||
viewList = append(viewList, viewMap[value])
|
viewList = append(viewList, viewMap[value])
|
||||||
viewItems = append(viewItems, common.PanelAnalyticsItem{Time: value, Count: viewMap[value]})
|
viewItems = append(viewItems, c.PanelAnalyticsItem{Time: value, Count: viewMap[value]})
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
|
|
||||||
pi := common.PanelAnalyticsRoutePage{basePage, common.SanitiseSingleLine(route), graph, viewItems, timeRange.Range}
|
pi := c.PanelAnalyticsRoutePage{basePage, c.SanitiseSingleLine(route), graph, viewItems, timeRange.Range}
|
||||||
return renderTemplate("panel_analytics_route_views", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_route_views", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user common.User, agent string) common.RouteError {
|
func AnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user c.User, agent string) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
// ? Only allow valid agents? The problem with this is that agents wind up getting renamed and it would take a migration to get them all up to snuff
|
// ? Only allow valid agents? The problem with this is that agents wind up getting renamed and it would take a migration to get them all up to snuff
|
||||||
agent = common.SanitiseSingleLine(agent)
|
agent = c.SanitiseSingleLine(agent)
|
||||||
|
|
||||||
common.DebugLog("in panel.AnalyticsAgentViews")
|
c.DebugLog("in panel.AnalyticsAgentViews")
|
||||||
// TODO: Verify the agent is valid
|
// TODO: Verify the agent is valid
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks_agents").Columns("count, createdAt").Where("browser = ?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(agent)
|
rows, err := qgen.NewAcc().Select("viewchunks_agents").Columns("count, createdAt").Where("browser = ?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(agent)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewList []int64
|
var viewList []int64
|
||||||
for _, value := range revLabelList {
|
for _, value := range revLabelList {
|
||||||
viewList = append(viewList, viewMap[value])
|
viewList = append(viewList, viewMap[value])
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
|
|
||||||
friendlyAgent, ok := phrases.GetUserAgentPhrase(agent)
|
friendlyAgent, ok := phrases.GetUserAgentPhrase(agent)
|
||||||
if !ok {
|
if !ok {
|
||||||
friendlyAgent = agent
|
friendlyAgent = agent
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelAnalyticsAgentPage{basePage, agent, friendlyAgent, graph, timeRange.Range}
|
pi := c.PanelAnalyticsAgentPage{basePage, agent, friendlyAgent, graph, timeRange.Range}
|
||||||
return renderTemplate("panel_analytics_agent_views", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_agent_views", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsForumViews(w http.ResponseWriter, r *http.Request, user common.User, sfid string) common.RouteError {
|
func AnalyticsForumViews(w http.ResponseWriter, r *http.Request, user c.User, sfid string) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
fid, err := strconv.Atoi(sfid)
|
fid, err := strconv.Atoi(sfid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("Invalid integer", w, r, user)
|
return c.LocalError("Invalid integer", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
common.DebugLog("in panel.AnalyticsForumViews")
|
c.DebugLog("in panel.AnalyticsForumViews")
|
||||||
// TODO: Verify the agent is valid
|
// TODO: Verify the agent is valid
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks_forums").Columns("count, createdAt").Where("forum = ?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(fid)
|
rows, err := qgen.NewAcc().Select("viewchunks_forums").Columns("count, createdAt").Where("forum = ?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(fid)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewList []int64
|
var viewList []int64
|
||||||
for _, value := range revLabelList {
|
for _, value := range revLabelList {
|
||||||
viewList = append(viewList, viewMap[value])
|
viewList = append(viewList, viewMap[value])
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
|
|
||||||
forum, err := common.Forums.Get(fid)
|
forum, err := c.Forums.Get(fid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelAnalyticsAgentPage{basePage, sfid, forum.Name, graph, timeRange.Range}
|
pi := c.PanelAnalyticsAgentPage{basePage, sfid, forum.Name, graph, timeRange.Range}
|
||||||
return renderTemplate("panel_analytics_forum_views", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_forum_views", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsSystemViews(w http.ResponseWriter, r *http.Request, user common.User, system string) common.RouteError {
|
func AnalyticsSystemViews(w http.ResponseWriter, r *http.Request, user c.User, system string) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
system = common.SanitiseSingleLine(system)
|
system = c.SanitiseSingleLine(system)
|
||||||
|
|
||||||
common.DebugLog("in panel.AnalyticsSystemViews")
|
c.DebugLog("in panel.AnalyticsSystemViews")
|
||||||
// TODO: Verify the OS name is valid
|
// TODO: Verify the OS name is valid
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks_systems").Columns("count, createdAt").Where("system = ?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(system)
|
rows, err := qgen.NewAcc().Select("viewchunks_systems").Columns("count, createdAt").Where("system = ?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(system)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewList []int64
|
var viewList []int64
|
||||||
for _, value := range revLabelList {
|
for _, value := range revLabelList {
|
||||||
viewList = append(viewList, viewMap[value])
|
viewList = append(viewList, viewMap[value])
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
|
|
||||||
friendlySystem, ok := phrases.GetOSPhrase(system)
|
friendlySystem, ok := phrases.GetOSPhrase(system)
|
||||||
if !ok {
|
if !ok {
|
||||||
friendlySystem = system
|
friendlySystem = system
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelAnalyticsAgentPage{basePage, system, friendlySystem, graph, timeRange.Range}
|
pi := c.PanelAnalyticsAgentPage{basePage, system, friendlySystem, graph, timeRange.Range}
|
||||||
return renderTemplate("panel_analytics_system_views", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_system_views", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsLanguageViews(w http.ResponseWriter, r *http.Request, user common.User, lang string) common.RouteError {
|
func AnalyticsLanguageViews(w http.ResponseWriter, r *http.Request, user c.User, lang string) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
lang = common.SanitiseSingleLine(lang)
|
lang = c.SanitiseSingleLine(lang)
|
||||||
|
|
||||||
common.DebugLog("in panel.AnalyticsLanguageViews")
|
c.DebugLog("in panel.AnalyticsLanguageViews")
|
||||||
// TODO: Verify the language code is valid
|
// TODO: Verify the language code is valid
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks_langs").Columns("count, createdAt").Where("lang = ?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(lang)
|
rows, err := qgen.NewAcc().Select("viewchunks_langs").Columns("count, createdAt").Where("lang = ?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(lang)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewList []int64
|
var viewList []int64
|
||||||
for _, value := range revLabelList {
|
for _, value := range revLabelList {
|
||||||
viewList = append(viewList, viewMap[value])
|
viewList = append(viewList, viewMap[value])
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
|
|
||||||
friendlyLang, ok := phrases.GetHumanLangPhrase(lang)
|
friendlyLang, ok := phrases.GetHumanLangPhrase(lang)
|
||||||
if !ok {
|
if !ok {
|
||||||
friendlyLang = lang
|
friendlyLang = lang
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelAnalyticsAgentPage{basePage, lang, friendlyLang, graph, timeRange.Range}
|
pi := c.PanelAnalyticsAgentPage{basePage, lang, friendlyLang, graph, timeRange.Range}
|
||||||
return renderTemplate("panel_analytics_lang_views", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_lang_views", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsReferrerViews(w http.ResponseWriter, r *http.Request, user common.User, domain string) common.RouteError {
|
func AnalyticsReferrerViews(w http.ResponseWriter, r *http.Request, user c.User, domain string) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
common.DebugLog("in panel.AnalyticsReferrerViews")
|
c.DebugLog("in panel.AnalyticsReferrerViews")
|
||||||
// TODO: Verify the agent is valid
|
// TODO: Verify the agent is valid
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks_referrers").Columns("count, createdAt").Where("domain = ?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(domain)
|
rows, err := qgen.NewAcc().Select("viewchunks_referrers").Columns("count, createdAt").Where("domain = ?").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query(domain)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewList []int64
|
var viewList []int64
|
||||||
for _, value := range revLabelList {
|
for _, value := range revLabelList {
|
||||||
viewList = append(viewList, viewMap[value])
|
viewList = append(viewList, viewMap[value])
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
pi := common.PanelAnalyticsAgentPage{basePage, common.SanitiseSingleLine(domain), "", graph, timeRange.Range}
|
pi := c.PanelAnalyticsAgentPage{basePage, c.SanitiseSingleLine(domain), "", graph, timeRange.Range}
|
||||||
return renderTemplate("panel_analytics_referrer_views", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_referrer_views", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsTopics(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func AnalyticsTopics(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
common.DebugLog("in panel.AnalyticsTopics")
|
c.DebugLog("in panel.AnalyticsTopics")
|
||||||
rows, err := qgen.NewAcc().Select("topicchunks").Columns("count, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
rows, err := qgen.NewAcc().Select("topicchunks").Columns("count, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewList []int64
|
var viewList []int64
|
||||||
var viewItems []common.PanelAnalyticsItem
|
var viewItems []c.PanelAnalyticsItem
|
||||||
for _, value := range revLabelList {
|
for _, value := range revLabelList {
|
||||||
viewList = append(viewList, viewMap[value])
|
viewList = append(viewList, viewMap[value])
|
||||||
viewItems = append(viewItems, common.PanelAnalyticsItem{Time: value, Count: viewMap[value]})
|
viewItems = append(viewItems, c.PanelAnalyticsItem{Time: value, Count: viewMap[value]})
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
pi := common.PanelAnalyticsPage{basePage, graph, viewItems, timeRange.Range, timeRange.Unit, "time"}
|
pi := c.PanelAnalyticsPage{basePage, graph, viewItems, timeRange.Range, timeRange.Unit, "time"}
|
||||||
return renderTemplate("panel_analytics_topics", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_topics", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsPosts(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func AnalyticsPosts(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
common.DebugLog("in panel.AnalyticsPosts")
|
c.DebugLog("in panel.AnalyticsPosts")
|
||||||
rows, err := qgen.NewAcc().Select("postchunks").Columns("count, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
rows, err := qgen.NewAcc().Select("postchunks").Columns("count, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewList []int64
|
var viewList []int64
|
||||||
var viewItems []common.PanelAnalyticsItem
|
var viewItems []c.PanelAnalyticsItem
|
||||||
for _, value := range revLabelList {
|
for _, value := range revLabelList {
|
||||||
viewList = append(viewList, viewMap[value])
|
viewList = append(viewList, viewMap[value])
|
||||||
viewItems = append(viewItems, common.PanelAnalyticsItem{Time: value, Count: viewMap[value]})
|
viewItems = append(viewItems, c.PanelAnalyticsItem{Time: value, Count: viewMap[value]})
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
pi := common.PanelAnalyticsPage{basePage, graph, viewItems, timeRange.Range, timeRange.Unit, "time"}
|
pi := c.PanelAnalyticsPage{basePage, graph, viewItems, timeRange.Range, timeRange.Unit, "time"}
|
||||||
return renderTemplate("panel_analytics_posts", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_posts", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ func analyticsRowsToNameMap(rows *sql.Rows) (map[string]int, error) {
|
||||||
return nameMap, err
|
return nameMap, err
|
||||||
}
|
}
|
||||||
// TODO: Bulk log this
|
// TODO: Bulk log this
|
||||||
if common.Dev.SuperDebug {
|
if c.Dev.SuperDebug {
|
||||||
log.Print("count: ", count)
|
log.Print("count: ", count)
|
||||||
log.Print("name: ", name)
|
log.Print("name: ", name)
|
||||||
}
|
}
|
||||||
|
@ -497,7 +497,7 @@ func analyticsRowsToDuoMap(rows *sql.Rows, labelList []int64, viewMap map[int64]
|
||||||
|
|
||||||
// TODO: Bulk log this
|
// TODO: Bulk log this
|
||||||
var unixCreatedAt = createdAt.Unix()
|
var unixCreatedAt = createdAt.Unix()
|
||||||
if common.Dev.SuperDebug {
|
if c.Dev.SuperDebug {
|
||||||
log.Print("count: ", count)
|
log.Print("count: ", count)
|
||||||
log.Print("name: ", name)
|
log.Print("name: ", name)
|
||||||
log.Print("createdAt: ", createdAt)
|
log.Print("createdAt: ", createdAt)
|
||||||
|
@ -557,7 +557,7 @@ func analyticsVMapToOVList(vMap map[string]map[int64]int64) (ovList []OVItem) {
|
||||||
return tOVList
|
return tOVList
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsForums(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func AnalyticsForums(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
|
@ -567,17 +567,17 @@ func AnalyticsForums(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
|
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks_forums").Columns("count, forum, createdAt").Where("forum != ''").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
rows, err := qgen.NewAcc().Select("viewchunks_forums").Columns("count, forum, createdAt").Where("forum != ''").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
vMap, forumMap, err := analyticsRowsToDuoMap(rows, labelList, viewMap)
|
vMap, forumMap, err := analyticsRowsToDuoMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
ovList := analyticsVMapToOVList(vMap)
|
ovList := analyticsVMapToOVList(vMap)
|
||||||
|
|
||||||
|
@ -592,15 +592,15 @@ func AnalyticsForums(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
vList = append(vList, viewList)
|
vList = append(vList, viewList)
|
||||||
fid, err := strconv.Atoi(ovitem.name)
|
fid, err := strconv.Atoi(ovitem.name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
var lName string
|
var lName string
|
||||||
forum, err := common.Forums.Get(fid)
|
forum, err := c.Forums.Get(fid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
// TODO: Localise this
|
// TODO: Localise this
|
||||||
lName = "Deleted Forum"
|
lName = "Deleted Forum"
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
} else {
|
} else {
|
||||||
lName = forum.Name
|
lName = forum.Name
|
||||||
}
|
}
|
||||||
|
@ -610,38 +610,38 @@ func AnalyticsForums(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
|
graph := c.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
|
|
||||||
// TODO: Sort this slice
|
// TODO: Sort this slice
|
||||||
var forumItems []common.PanelAnalyticsAgentsItem
|
var forumItems []c.PanelAnalyticsAgentsItem
|
||||||
for sfid, count := range forumMap {
|
for sfid, count := range forumMap {
|
||||||
fid, err := strconv.Atoi(sfid)
|
fid, err := strconv.Atoi(sfid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
var lName string
|
var lName string
|
||||||
forum, err := common.Forums.Get(fid)
|
forum, err := c.Forums.Get(fid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
// TODO: Localise this
|
// TODO: Localise this
|
||||||
lName = "Deleted Forum"
|
lName = "Deleted Forum"
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
} else {
|
} else {
|
||||||
lName = forum.Name
|
lName = forum.Name
|
||||||
}
|
}
|
||||||
forumItems = append(forumItems, common.PanelAnalyticsAgentsItem{
|
forumItems = append(forumItems, c.PanelAnalyticsAgentsItem{
|
||||||
Agent: sfid,
|
Agent: sfid,
|
||||||
FriendlyAgent: lName,
|
FriendlyAgent: lName,
|
||||||
Count: count,
|
Count: count,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelAnalyticsDuoPage{basePage, forumItems, graph, timeRange.Range}
|
pi := c.PanelAnalyticsDuoPage{basePage, forumItems, graph, timeRange.Range}
|
||||||
return renderTemplate("panel_analytics_forums", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_forums", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsRoutes(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func AnalyticsRoutes(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
|
@ -651,17 +651,17 @@ func AnalyticsRoutes(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
|
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks").Columns("count, route, createdAt").Where("route != ''").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
rows, err := qgen.NewAcc().Select("viewchunks").Columns("count, route, createdAt").Where("route != ''").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
vMap, routeMap, err := analyticsRowsToDuoMap(rows, labelList, viewMap)
|
vMap, routeMap, err := analyticsRowsToDuoMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
ovList := analyticsVMapToOVList(vMap)
|
ovList := analyticsVMapToOVList(vMap)
|
||||||
|
|
||||||
|
@ -680,24 +680,24 @@ func AnalyticsRoutes(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
|
graph := c.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
|
|
||||||
// TODO: Sort this slice
|
// TODO: Sort this slice
|
||||||
var routeItems []common.PanelAnalyticsRoutesItem
|
var routeItems []c.PanelAnalyticsRoutesItem
|
||||||
for route, count := range routeMap {
|
for route, count := range routeMap {
|
||||||
routeItems = append(routeItems, common.PanelAnalyticsRoutesItem{
|
routeItems = append(routeItems, c.PanelAnalyticsRoutesItem{
|
||||||
Route: route,
|
Route: route,
|
||||||
Count: count,
|
Count: count,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelAnalyticsRoutesPage{basePage, routeItems, graph, timeRange.Range}
|
pi := c.PanelAnalyticsRoutesPage{basePage, routeItems, graph, timeRange.Range}
|
||||||
return renderTemplate("panel_analytics_routes", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_routes", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trialling multi-series charts
|
// Trialling multi-series charts
|
||||||
func AnalyticsAgents(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func AnalyticsAgents(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
|
@ -707,17 +707,17 @@ func AnalyticsAgents(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
|
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks_agents").Columns("count, browser, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
rows, err := qgen.NewAcc().Select("viewchunks_agents").Columns("count, browser, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
vMap, agentMap, err := analyticsRowsToDuoMap(rows, labelList, viewMap)
|
vMap, agentMap, err := analyticsRowsToDuoMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
ovList := analyticsVMapToOVList(vMap)
|
ovList := analyticsVMapToOVList(vMap)
|
||||||
|
|
||||||
|
@ -740,28 +740,28 @@ func AnalyticsAgents(w http.ResponseWriter, r *http.Request, user common.User) c
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
|
graph := c.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
|
|
||||||
// TODO: Sort this slice
|
// TODO: Sort this slice
|
||||||
var agentItems []common.PanelAnalyticsAgentsItem
|
var agentItems []c.PanelAnalyticsAgentsItem
|
||||||
for agent, count := range agentMap {
|
for agent, count := range agentMap {
|
||||||
aAgent, ok := phrases.GetUserAgentPhrase(agent)
|
aAgent, ok := phrases.GetUserAgentPhrase(agent)
|
||||||
if !ok {
|
if !ok {
|
||||||
aAgent = agent
|
aAgent = agent
|
||||||
}
|
}
|
||||||
agentItems = append(agentItems, common.PanelAnalyticsAgentsItem{
|
agentItems = append(agentItems, c.PanelAnalyticsAgentsItem{
|
||||||
Agent: agent,
|
Agent: agent,
|
||||||
FriendlyAgent: aAgent,
|
FriendlyAgent: aAgent,
|
||||||
Count: count,
|
Count: count,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelAnalyticsDuoPage{basePage, agentItems, graph, timeRange.Range}
|
pi := c.PanelAnalyticsDuoPage{basePage, agentItems, graph, timeRange.Range}
|
||||||
return renderTemplate("panel_analytics_agents", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_agents", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsSystems(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func AnalyticsSystems(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
|
@ -771,17 +771,17 @@ func AnalyticsSystems(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
|
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks_systems").Columns("count, system, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
rows, err := qgen.NewAcc().Select("viewchunks_systems").Columns("count, system, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
vMap, osMap, err := analyticsRowsToDuoMap(rows, labelList, viewMap)
|
vMap, osMap, err := analyticsRowsToDuoMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
ovList := analyticsVMapToOVList(vMap)
|
ovList := analyticsVMapToOVList(vMap)
|
||||||
|
|
||||||
|
@ -804,28 +804,28 @@ func AnalyticsSystems(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
|
graph := c.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
|
|
||||||
// TODO: Sort this slice
|
// TODO: Sort this slice
|
||||||
var systemItems []common.PanelAnalyticsAgentsItem
|
var systemItems []c.PanelAnalyticsAgentsItem
|
||||||
for system, count := range osMap {
|
for system, count := range osMap {
|
||||||
sSystem, ok := phrases.GetOSPhrase(system)
|
sSystem, ok := phrases.GetOSPhrase(system)
|
||||||
if !ok {
|
if !ok {
|
||||||
sSystem = system
|
sSystem = system
|
||||||
}
|
}
|
||||||
systemItems = append(systemItems, common.PanelAnalyticsAgentsItem{
|
systemItems = append(systemItems, c.PanelAnalyticsAgentsItem{
|
||||||
Agent: system,
|
Agent: system,
|
||||||
FriendlyAgent: sSystem,
|
FriendlyAgent: sSystem,
|
||||||
Count: count,
|
Count: count,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelAnalyticsDuoPage{basePage, systemItems, graph, timeRange.Range}
|
pi := c.PanelAnalyticsDuoPage{basePage, systemItems, graph, timeRange.Range}
|
||||||
return renderTemplate("panel_analytics_systems", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_systems", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
basePage, ferr := PreAnalyticsDetail(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
|
@ -835,17 +835,17 @@ func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user common.User
|
||||||
|
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
|
||||||
|
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks_langs").Columns("count, lang, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
rows, err := qgen.NewAcc().Select("viewchunks_langs").Columns("count, lang, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
vMap, langMap, err := analyticsRowsToDuoMap(rows, labelList, viewMap)
|
vMap, langMap, err := analyticsRowsToDuoMap(rows, labelList, viewMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
ovList := analyticsVMapToOVList(vMap)
|
ovList := analyticsVMapToOVList(vMap)
|
||||||
|
|
||||||
|
@ -868,56 +868,56 @@ func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user common.User
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
graph := common.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
|
graph := c.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
|
||||||
common.DebugLogf("graph: %+v\n", graph)
|
c.DebugLogf("graph: %+v\n", graph)
|
||||||
|
|
||||||
// TODO: Can we de-duplicate these analytics functions further?
|
// TODO: Can we de-duplicate these analytics functions further?
|
||||||
// TODO: Sort this slice
|
// TODO: Sort this slice
|
||||||
var langItems []common.PanelAnalyticsAgentsItem
|
var langItems []c.PanelAnalyticsAgentsItem
|
||||||
for lang, count := range langMap {
|
for lang, count := range langMap {
|
||||||
lLang, ok := phrases.GetHumanLangPhrase(lang)
|
lLang, ok := phrases.GetHumanLangPhrase(lang)
|
||||||
if !ok {
|
if !ok {
|
||||||
lLang = lang
|
lLang = lang
|
||||||
}
|
}
|
||||||
langItems = append(langItems, common.PanelAnalyticsAgentsItem{
|
langItems = append(langItems, c.PanelAnalyticsAgentsItem{
|
||||||
Agent: lang,
|
Agent: lang,
|
||||||
FriendlyAgent: lLang,
|
FriendlyAgent: lLang,
|
||||||
Count: count,
|
Count: count,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelAnalyticsDuoPage{basePage, langItems, graph, timeRange.Range}
|
pi := c.PanelAnalyticsDuoPage{basePage, langItems, graph, timeRange.Range}
|
||||||
return renderTemplate("panel_analytics_langs", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_langs", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnalyticsReferrers(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func AnalyticsReferrers(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := buildBasePage(w, r, &user, "analytics", "analytics")
|
basePage, ferr := buildBasePage(w, r, &user, "analytics", "analytics")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := qgen.NewAcc().Select("viewchunks_referrers").Columns("count, domain").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
rows, err := qgen.NewAcc().Select("viewchunks_referrers").Columns("count, domain").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
refMap, err := analyticsRowsToNameMap(rows)
|
refMap, err := analyticsRowsToNameMap(rows)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Sort this slice
|
// TODO: Sort this slice
|
||||||
var refItems []common.PanelAnalyticsAgentsItem
|
var refItems []c.PanelAnalyticsAgentsItem
|
||||||
for domain, count := range refMap {
|
for domain, count := range refMap {
|
||||||
refItems = append(refItems, common.PanelAnalyticsAgentsItem{
|
refItems = append(refItems, c.PanelAnalyticsAgentsItem{
|
||||||
Agent: common.SanitiseSingleLine(domain),
|
Agent: c.SanitiseSingleLine(domain),
|
||||||
Count: count,
|
Count: count,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelAnalyticsAgentsPage{basePage, refItems, timeRange.Range}
|
pi := c.PanelAnalyticsAgentsPage{basePage, refItems, timeRange.Range}
|
||||||
return renderTemplate("panel_analytics_referrers", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_analytics_referrers", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,10 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Backups(w http.ResponseWriter, r *http.Request, user common.User, backupURL string) common.RouteError {
|
func Backups(w http.ResponseWriter, r *http.Request, user c.User, backupURL string) c.RouteError {
|
||||||
basePage, ferr := buildBasePage(w, r, &user, "backups", "backups")
|
basePage, ferr := buildBasePage(w, r, &user, "backups", "backups")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
|
@ -18,15 +18,15 @@ func Backups(w http.ResponseWriter, r *http.Request, user common.User, backupURL
|
||||||
|
|
||||||
if backupURL != "" {
|
if backupURL != "" {
|
||||||
// We don't want them trying to break out of this directory, it shouldn't hurt since it's a super admin, but it's always good to practice good security hygiene, especially if this is one of many instances on a managed server not controlled by the superadmin/s
|
// We don't want them trying to break out of this directory, it shouldn't hurt since it's a super admin, but it's always good to practice good security hygiene, especially if this is one of many instances on a managed server not controlled by the superadmin/s
|
||||||
backupURL = common.Stripslashes(backupURL)
|
backupURL = c.Stripslashes(backupURL)
|
||||||
|
|
||||||
var ext = filepath.Ext("./backups/" + backupURL)
|
var ext = filepath.Ext("./backups/" + backupURL)
|
||||||
if ext != ".sql" && ext != ".zip" {
|
if ext != ".sql" && ext != ".zip" {
|
||||||
return common.NotFound(w, r, basePage.Header)
|
return c.NotFound(w, r, basePage.Header)
|
||||||
}
|
}
|
||||||
info, err := os.Stat("./backups/" + backupURL)
|
info, err := os.Stat("./backups/" + backupURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.NotFound(w, r, basePage.Header)
|
return c.NotFound(w, r, basePage.Header)
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Length", strconv.FormatInt(info.Size(), 10))
|
w.Header().Set("Content-Length", strconv.FormatInt(info.Size(), 10))
|
||||||
|
|
||||||
|
@ -44,19 +44,19 @@ func Backups(w http.ResponseWriter, r *http.Request, user common.User, backupURL
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var backupList []common.BackupItem
|
var backupList []c.BackupItem
|
||||||
backupFiles, err := ioutil.ReadDir("./backups")
|
backupFiles, err := ioutil.ReadDir("./backups")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
for _, backupFile := range backupFiles {
|
for _, backupFile := range backupFiles {
|
||||||
var ext = filepath.Ext(backupFile.Name())
|
var ext = filepath.Ext(backupFile.Name())
|
||||||
if ext != ".sql" {
|
if ext != ".sql" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
backupList = append(backupList, common.BackupItem{backupFile.Name(), backupFile.ModTime()})
|
backupList = append(backupList, c.BackupItem{backupFile.Name(), backupFile.ModTime()})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelBackupPage{basePage, backupList}
|
pi := c.PanelBackupPage{basePage, backupList}
|
||||||
return renderTemplate("panel_backups", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_backups", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package panel
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/common/phrases"
|
"github.com/Azareal/Gosora/common/phrases"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ var tList []interface{}
|
||||||
var successJSONBytes = []byte(`{"success":"1"}`)
|
var successJSONBytes = []byte(`{"success":"1"}`)
|
||||||
|
|
||||||
// We're trying to reduce the amount of boilerplate in here, so I added these two functions, they might wind up circulating outside this file in the future
|
// We're trying to reduce the amount of boilerplate in here, so I added these two functions, they might wind up circulating outside this file in the future
|
||||||
func successRedirect(dest string, w http.ResponseWriter, r *http.Request, isJs bool) common.RouteError {
|
func successRedirect(dest string, w http.ResponseWriter, r *http.Request, isJs bool) c.RouteError {
|
||||||
if !isJs {
|
if !isJs {
|
||||||
http.Redirect(w, r, dest, http.StatusSeeOther)
|
http.Redirect(w, r, dest, http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
|
@ -21,25 +21,25 @@ func successRedirect(dest string, w http.ResponseWriter, r *http.Request, isJs b
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *common.Header, pi interface{}) common.RouteError {
|
func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) c.RouteError {
|
||||||
header.AddScript("global.js")
|
header.AddScript("global.js")
|
||||||
if common.RunPreRenderHook("pre_render_"+tmplName, w, r, &header.CurrentUser, pi) {
|
if c.RunPreRenderHook("pre_render_"+tmplName, w, r, &header.CurrentUser, pi) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// TODO: Prepend this with panel_?
|
// TODO: Prepend this with panel_?
|
||||||
err := header.Theme.RunTmpl(tmplName, pi, w)
|
err := header.Theme.RunTmpl(tmplName, pi, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildBasePage(w http.ResponseWriter, r *http.Request, user *common.User, titlePhrase string, zone string) (*common.BasePanelPage, common.RouteError) {
|
func buildBasePage(w http.ResponseWriter, r *http.Request, user *c.User, titlePhrase string, zone string) (*c.BasePanelPage, c.RouteError) {
|
||||||
header, stats, ferr := common.PanelUserCheck(w, r, user)
|
header, stats, ferr := c.PanelUserCheck(w, r, user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return nil, ferr
|
return nil, ferr
|
||||||
}
|
}
|
||||||
header.Title = phrases.GetTitlePhrase("panel_" + titlePhrase)
|
header.Title = phrases.GetTitlePhrase("panel_" + titlePhrase)
|
||||||
|
|
||||||
return &common.BasePanelPage{header, stats, zone, common.ReportForumID}, nil
|
return &c.BasePanelPage{header, stats, zone, c.ReportForumID}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Debug(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func Debug(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := buildBasePage(w, r, &user, "debug", "debug")
|
basePage, ferr := buildBasePage(w, r, &user, "debug", "debug")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
|
@ -19,7 +19,7 @@ func Debug(w http.ResponseWriter, r *http.Request, user common.User) common.Rout
|
||||||
goVersion := runtime.Version()
|
goVersion := runtime.Version()
|
||||||
dbVersion := qgen.Builder.DbVersion()
|
dbVersion := qgen.Builder.DbVersion()
|
||||||
var uptime string
|
var uptime string
|
||||||
upDuration := time.Since(common.StartTime)
|
upDuration := time.Since(c.StartTime)
|
||||||
hours := int(upDuration.Hours())
|
hours := int(upDuration.Hours())
|
||||||
minutes := int(upDuration.Minutes())
|
minutes := int(upDuration.Minutes())
|
||||||
if hours > 24 {
|
if hours > 24 {
|
||||||
|
@ -41,6 +41,6 @@ func Debug(w http.ResponseWriter, r *http.Request, user common.User) common.Rout
|
||||||
var memStats runtime.MemStats
|
var memStats runtime.MemStats
|
||||||
runtime.ReadMemStats(&memStats)
|
runtime.ReadMemStats(&memStats)
|
||||||
|
|
||||||
pi := common.PanelDebugPage{basePage, goVersion, dbVersion, uptime, openConnCount, qgen.Builder.GetAdapter().GetName(), goroutines, cpus, memStats}
|
pi := c.PanelDebugPage{basePage, goVersion, dbVersion, uptime, openConnCount, qgen.Builder.GetAdapter().GetName(), goroutines, cpus, memStats}
|
||||||
return renderTemplate("panel_debug", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_debug", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,21 +8,21 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/common/phrases"
|
"github.com/Azareal/Gosora/common/phrases"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Themes(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func Themes(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := buildBasePage(w, r, &user, "themes", "themes")
|
basePage, ferr := buildBasePage(w, r, &user, "themes", "themes")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
var pThemeList, vThemeList []*common.Theme
|
var pThemeList, vThemeList []*c.Theme
|
||||||
for _, theme := range common.Themes {
|
for _, theme := range c.Themes {
|
||||||
if theme.HideFromThemes {
|
if theme.HideFromThemes {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -33,88 +33,88 @@ func Themes(w http.ResponseWriter, r *http.Request, user common.User) common.Rou
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelThemesPage{basePage, pThemeList, vThemeList}
|
pi := c.PanelThemesPage{basePage, pThemeList, vThemeList}
|
||||||
return renderTemplate("panel_themes", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_themes", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesSetDefault(w http.ResponseWriter, r *http.Request, user common.User, uname string) common.RouteError {
|
func ThemesSetDefault(w http.ResponseWriter, r *http.Request, user c.User, uname string) c.RouteError {
|
||||||
_, ferr := common.SimplePanelUserCheck(w, r, &user)
|
_, ferr := c.SimplePanelUserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
theme, ok := common.Themes[uname]
|
theme, ok := c.Themes[uname]
|
||||||
if !ok {
|
if !ok {
|
||||||
return common.LocalError("The theme isn't registered in the system", w, r, user)
|
return c.LocalError("The theme isn't registered in the system", w, r, user)
|
||||||
}
|
}
|
||||||
if theme.Disabled {
|
if theme.Disabled {
|
||||||
return common.LocalError("You must not enable this theme", w, r, user)
|
return c.LocalError("You must not enable this theme", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := common.UpdateDefaultTheme(theme)
|
err := c.UpdateDefaultTheme(theme)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Redirect(w, r, "/panel/themes/", http.StatusSeeOther)
|
http.Redirect(w, r, "/panel/themes/", http.StatusSeeOther)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenus(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func ThemesMenus(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := buildBasePage(w, r, &user, "themes_menus", "themes")
|
basePage, ferr := buildBasePage(w, r, &user, "themes_menus", "themes")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
var menuList []common.PanelMenuListItem
|
var menuList []c.PanelMenuListItem
|
||||||
for mid, list := range common.Menus.GetAllMap() {
|
for mid, list := range c.Menus.GetAllMap() {
|
||||||
var name = ""
|
var name = ""
|
||||||
if mid == 1 {
|
if mid == 1 {
|
||||||
name = phrases.GetTmplPhrase("panel_themes_menus_main")
|
name = phrases.GetTmplPhrase("panel_themes_menus_main")
|
||||||
}
|
}
|
||||||
menuList = append(menuList, common.PanelMenuListItem{
|
menuList = append(menuList, c.PanelMenuListItem{
|
||||||
Name: name,
|
Name: name,
|
||||||
ID: mid,
|
ID: mid,
|
||||||
ItemCount: len(list.List),
|
ItemCount: len(list.List),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelMenuListPage{basePage, menuList}
|
pi := c.PanelMenuListPage{basePage, menuList}
|
||||||
return renderTemplate("panel_themes_menus", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_themes_menus", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user common.User, smid string) common.RouteError {
|
func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user c.User, smid string) c.RouteError {
|
||||||
// TODO: Something like Menu #1 for the title?
|
// TODO: Something like Menu #1 for the title?
|
||||||
basePage, ferr := buildBasePage(w, r, &user, "themes_menus_edit", "themes")
|
basePage, ferr := buildBasePage(w, r, &user, "themes_menus_edit", "themes")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
basePage.Header.AddScript("Sortable-1.4.0/Sortable.min.js")
|
basePage.Header.AddScript("Sortable-1.4.0/Sortable.min.js")
|
||||||
|
|
||||||
mid, err := strconv.Atoi(smid)
|
mid, err := strconv.Atoi(smid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
return c.LocalError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
menuHold, err := common.Menus.Get(mid)
|
menuHold, err := c.Menus.Get(mid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.NotFound(w, r, basePage.Header)
|
return c.NotFound(w, r, basePage.Header)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var menuList []common.MenuItem
|
var menuList []c.MenuItem
|
||||||
for _, item := range menuHold.List {
|
for _, item := range menuHold.List {
|
||||||
var menuTmpls = map[string]common.MenuTmpl{
|
var menuTmpls = map[string]c.MenuTmpl{
|
||||||
item.TmplName: menuHold.Parse(item.Name, []byte("{{.Name}}")),
|
item.TmplName: menuHold.Parse(item.Name, []byte("{{.Name}}")),
|
||||||
}
|
}
|
||||||
var renderBuffer [][]byte
|
var renderBuffer [][]byte
|
||||||
|
@ -132,39 +132,39 @@ func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user common.User, s
|
||||||
menuList = append(menuList, item)
|
menuList = append(menuList, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelMenuPage{basePage, mid, menuList}
|
pi := c.PanelMenuPage{basePage, mid, menuList}
|
||||||
return renderTemplate("panel_themes_menus_items", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_themes_menus_items", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenuItemEdit(w http.ResponseWriter, r *http.Request, user common.User, sitemID string) common.RouteError {
|
func ThemesMenuItemEdit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError {
|
||||||
// TODO: Something like Menu #1 for the title?
|
// TODO: Something like Menu #1 for the title?
|
||||||
basePage, ferr := buildBasePage(w, r, &user, "themes_menus_edit", "themes")
|
basePage, ferr := buildBasePage(w, r, &user, "themes_menus_edit", "themes")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
itemID, err := strconv.Atoi(sitemID)
|
itemID, err := strconv.Atoi(sitemID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
return c.LocalError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
menuItem, err := common.Menus.ItemStore().Get(itemID)
|
menuItem, err := c.Menus.ItemStore().Get(itemID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.NotFound(w, r, basePage.Header)
|
return c.NotFound(w, r, basePage.Header)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelMenuItemPage{basePage, menuItem}
|
pi := c.PanelMenuItemPage{basePage, menuItem}
|
||||||
return renderTemplate("panel_themes_menus_item_edit", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_themes_menus_item_edit", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func themesMenuItemSetters(r *http.Request, menuItem common.MenuItem) common.MenuItem {
|
func themesMenuItemSetters(r *http.Request, menuItem c.MenuItem) c.MenuItem {
|
||||||
var getItem = func(name string) string {
|
var getItem = func(name string) string {
|
||||||
return common.SanitiseSingleLine(r.PostFormValue("item-" + name))
|
return c.SanitiseSingleLine(r.PostFormValue("item-" + name))
|
||||||
}
|
}
|
||||||
menuItem.Name = getItem("name")
|
menuItem.Name = getItem("name")
|
||||||
menuItem.HTMLID = getItem("htmlid")
|
menuItem.HTMLID = getItem("htmlid")
|
||||||
|
@ -208,113 +208,113 @@ func themesMenuItemSetters(r *http.Request, menuItem common.MenuItem) common.Men
|
||||||
return menuItem
|
return menuItem
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, sitemID string) common.RouteError {
|
func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError {
|
||||||
_, ferr := common.SimplePanelUserCheck(w, r, &user)
|
_, ferr := c.SimplePanelUserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
isJs := (r.PostFormValue("js") == "1")
|
isJs := (r.PostFormValue("js") == "1")
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
itemID, err := strconv.Atoi(sitemID)
|
itemID, err := strconv.Atoi(sitemID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs)
|
return c.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
menuItem, err := common.Menus.ItemStore().Get(itemID)
|
menuItem, err := c.Menus.ItemStore().Get(itemID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.LocalErrorJSQ("This item doesn't exist.", w, r, user, isJs)
|
return c.LocalErrorJSQ("This item doesn't exist.", w, r, user, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
//menuItem = menuItem.Copy() // If we switch this for a pointer, we might need this as a scratchpad
|
//menuItem = menuItem.Copy() // If we switch this for a pointer, we might need this as a scratchpad
|
||||||
menuItem = themesMenuItemSetters(r, menuItem)
|
menuItem = themesMenuItemSetters(r, menuItem)
|
||||||
|
|
||||||
err = menuItem.Commit()
|
err = menuItem.Commit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
return successRedirect("/panel/themes/menus/item/edit/"+strconv.Itoa(itemID), w, r, isJs)
|
return successRedirect("/panel/themes/menus/item/edit/"+strconv.Itoa(itemID), w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
_, ferr := common.SimplePanelUserCheck(w, r, &user)
|
_, ferr := c.SimplePanelUserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
|
|
||||||
isJs := (r.PostFormValue("js") == "1")
|
isJs := (r.PostFormValue("js") == "1")
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
smenuID := r.PostFormValue("mid")
|
smenuID := r.PostFormValue("mid")
|
||||||
if smenuID == "" {
|
if smenuID == "" {
|
||||||
return common.LocalErrorJSQ("No menuID provided", w, r, user, isJs)
|
return c.LocalErrorJSQ("No menuID provided", w, r, user, isJs)
|
||||||
}
|
}
|
||||||
menuID, err := strconv.Atoi(smenuID)
|
menuID, err := strconv.Atoi(smenuID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs)
|
return c.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
menuItem := common.MenuItem{MenuID: menuID}
|
menuItem := c.MenuItem{MenuID: menuID}
|
||||||
menuItem = themesMenuItemSetters(r, menuItem)
|
menuItem = themesMenuItemSetters(r, menuItem)
|
||||||
itemID, err := menuItem.Create()
|
itemID, err := menuItem.Create()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
return successRedirect("/panel/themes/menus/item/edit/"+strconv.Itoa(itemID), w, r, isJs)
|
return successRedirect("/panel/themes/menus/item/edit/"+strconv.Itoa(itemID), w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, user common.User, sitemID string) common.RouteError {
|
func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError {
|
||||||
_, ferr := common.SimplePanelUserCheck(w, r, &user)
|
_, ferr := c.SimplePanelUserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
isJs := (r.PostFormValue("js") == "1")
|
isJs := (r.PostFormValue("js") == "1")
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
itemID, err := strconv.Atoi(sitemID)
|
itemID, err := strconv.Atoi(sitemID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs)
|
return c.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs)
|
||||||
}
|
}
|
||||||
menuItem, err := common.Menus.ItemStore().Get(itemID)
|
menuItem, err := c.Menus.ItemStore().Get(itemID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.LocalErrorJSQ("This item doesn't exist.", w, r, user, isJs)
|
return c.LocalErrorJSQ("This item doesn't exist.", w, r, user, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
//menuItem = menuItem.Copy() // If we switch this for a pointer, we might need this as a scratchpad
|
//menuItem = menuItem.Copy() // If we switch this for a pointer, we might need this as a scratchpad
|
||||||
|
|
||||||
err = menuItem.Delete()
|
err = menuItem.Delete()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
return successRedirect("/panel/themes/menus/", w, r, isJs)
|
return successRedirect("/panel/themes/menus/", w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user common.User, smid string) common.RouteError {
|
func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user c.User, smid string) c.RouteError {
|
||||||
_, ferr := common.SimplePanelUserCheck(w, r, &user)
|
_, ferr := c.SimplePanelUserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
isJs := (r.PostFormValue("js") == "1")
|
isJs := (r.PostFormValue("js") == "1")
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
mid, err := strconv.Atoi(smid)
|
mid, err := strconv.Atoi(smid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs)
|
return c.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs)
|
||||||
}
|
}
|
||||||
menuHold, err := common.Menus.Get(mid)
|
menuHold, err := c.Menus.Get(mid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.LocalErrorJSQ("Can't find menu", w, r, user, isJs)
|
return c.LocalErrorJSQ("Can't find menu", w, r, user, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
sitems := strings.TrimSuffix(strings.TrimPrefix(r.PostFormValue("items"), "{"), "}")
|
sitems := strings.TrimSuffix(strings.TrimPrefix(r.PostFormValue("items"), "{"), "}")
|
||||||
|
@ -324,7 +324,7 @@ func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user comm
|
||||||
for index, smiid := range strings.Split(sitems, ",") {
|
for index, smiid := range strings.Split(sitems, ",") {
|
||||||
miid, err := strconv.Atoi(smiid)
|
miid, err := strconv.Atoi(smiid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ("Invalid integer in menu item list", w, r, user, isJs)
|
return c.LocalErrorJSQ("Invalid integer in menu item list", w, r, user, isJs)
|
||||||
}
|
}
|
||||||
updateMap[miid] = index
|
updateMap[miid] = index
|
||||||
}
|
}
|
||||||
|
@ -333,38 +333,38 @@ func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user comm
|
||||||
return successRedirect("/panel/themes/menus/edit/"+strconv.Itoa(mid), w, r, isJs)
|
return successRedirect("/panel/themes/menus/edit/"+strconv.Itoa(mid), w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesWidgets(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func ThemesWidgets(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
basePage, ferr := buildBasePage(w, r, &user, "themes_widgets", "themes")
|
basePage, ferr := buildBasePage(w, r, &user, "themes_widgets", "themes")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
basePage.Header.AddScript("widgets.js")
|
basePage.Header.AddScript("widgets.js")
|
||||||
|
|
||||||
var docks = make(map[string][]common.WidgetEdit)
|
var docks = make(map[string][]c.WidgetEdit)
|
||||||
for _, name := range common.GetDockList() {
|
for _, name := range c.GetDockList() {
|
||||||
if name == "leftOfNav" || name == "rightOfNav" {
|
if name == "leftOfNav" || name == "rightOfNav" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var widgets []common.WidgetEdit
|
var widgets []c.WidgetEdit
|
||||||
for _, widget := range common.GetDock(name) {
|
for _, widget := range c.GetDock(name) {
|
||||||
var data = make(map[string]string)
|
var data = make(map[string]string)
|
||||||
err := json.Unmarshal([]byte(widget.RawBody), &data)
|
err := json.Unmarshal([]byte(widget.RawBody), &data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
widgets = append(widgets, common.WidgetEdit{widget, data})
|
widgets = append(widgets, c.WidgetEdit{widget, data})
|
||||||
}
|
}
|
||||||
docks[name] = widgets
|
docks[name] = widgets
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.PanelWidgetListPage{basePage, docks, common.WidgetEdit{&common.Widget{ID: 0, Type: "simple"}, make(map[string]string)}}
|
pi := c.PanelWidgetListPage{basePage, docks, c.WidgetEdit{&c.Widget{ID: 0, Type: "simple"}, make(map[string]string)}}
|
||||||
return renderTemplate("panel_themes_widgets", w, r, basePage.Header, &pi)
|
return renderTemplate("panel_themes_widgets", w, r, basePage.Header, &pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func widgetsParseInputs(r *http.Request, widget *common.Widget) (*common.WidgetEdit, error) {
|
func widgetsParseInputs(r *http.Request, widget *c.Widget) (*c.WidgetEdit, error) {
|
||||||
var data = make(map[string]string)
|
var data = make(map[string]string)
|
||||||
widget.Enabled = (r.FormValue("wenabled") == "1")
|
widget.Enabled = (r.FormValue("wenabled") == "1")
|
||||||
widget.Location = r.FormValue("wlocation")
|
widget.Location = r.FormValue("wlocation")
|
||||||
|
@ -372,7 +372,7 @@ func widgetsParseInputs(r *http.Request, widget *common.Widget) (*common.WidgetE
|
||||||
return nil, errors.New("You need to specify a location for this widget.")
|
return nil, errors.New("You need to specify a location for this widget.")
|
||||||
}
|
}
|
||||||
widget.Side = r.FormValue("wside")
|
widget.Side = r.FormValue("wside")
|
||||||
if !common.HasDock(widget.Side) {
|
if !c.HasDock(widget.Side) {
|
||||||
return nil, errors.New("The widget dock you specified doesn't exist.")
|
return nil, errors.New("The widget dock you specified doesn't exist.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,95 +394,95 @@ func widgetsParseInputs(r *http.Request, widget *common.Widget) (*common.WidgetE
|
||||||
return nil, errors.New("Unknown widget type")
|
return nil, errors.New("Unknown widget type")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &common.WidgetEdit{widget, data}, nil
|
return &c.WidgetEdit{widget, data}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ThemesWidgetsEditSubmit is an action which is triggered when someone sends an update request for a widget
|
// ThemesWidgetsEditSubmit is an action which is triggered when someone sends an update request for a widget
|
||||||
func ThemesWidgetsEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, swid string) common.RouteError {
|
func ThemesWidgetsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, swid string) c.RouteError {
|
||||||
//fmt.Println("in ThemesWidgetsEditSubmit")
|
//fmt.Println("in ThemesWidgetsEditSubmit")
|
||||||
_, ferr := common.SimplePanelUserCheck(w, r, &user)
|
_, ferr := c.SimplePanelUserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
isJs := (r.PostFormValue("js") == "1")
|
isJs := (r.PostFormValue("js") == "1")
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
wid, err := strconv.Atoi(swid)
|
wid, err := strconv.Atoi(swid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs)
|
return c.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
widget, err := common.Widgets.Get(wid)
|
widget, err := c.Widgets.Get(wid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.NotFoundJSQ(w, r, nil, isJs)
|
return c.NotFoundJSQ(w, r, nil, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
ewidget, err := widgetsParseInputs(r, widget.Copy())
|
ewidget, err := widgetsParseInputs(r, widget.Copy())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ(err.Error(), w, r, user, isJs)
|
return c.LocalErrorJSQ(err.Error(), w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ewidget.Commit()
|
err = ewidget.Commit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
return successRedirect("/panel/themes/widgets/", w, r, isJs)
|
return successRedirect("/panel/themes/widgets/", w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ThemesWidgetsCreateSubmit is an action which is triggered when someone sends a create request for a widget
|
// ThemesWidgetsCreateSubmit is an action which is triggered when someone sends a create request for a widget
|
||||||
func ThemesWidgetsCreateSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func ThemesWidgetsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
//fmt.Println("in ThemesWidgetsCreateSubmit")
|
//fmt.Println("in ThemesWidgetsCreateSubmit")
|
||||||
isJs := (r.PostFormValue("js") == "1")
|
isJs := (r.PostFormValue("js") == "1")
|
||||||
_, ferr := common.SimplePanelUserCheck(w, r, &user)
|
_, ferr := c.SimplePanelUserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
ewidget, err := widgetsParseInputs(r, &common.Widget{})
|
ewidget, err := widgetsParseInputs(r, &c.Widget{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ(err.Error(), w, r, user, isJs)
|
return c.LocalErrorJSQ(err.Error(), w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ewidget.Create()
|
err = ewidget.Create()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
return successRedirect("/panel/themes/widgets/", w, r, isJs)
|
return successRedirect("/panel/themes/widgets/", w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesWidgetsDeleteSubmit(w http.ResponseWriter, r *http.Request, user common.User, swid string) common.RouteError {
|
func ThemesWidgetsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, swid string) c.RouteError {
|
||||||
_, ferr := common.SimplePanelUserCheck(w, r, &user)
|
_, ferr := c.SimplePanelUserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
isJs := (r.PostFormValue("js") == "1")
|
isJs := (r.PostFormValue("js") == "1")
|
||||||
if !user.Perms.ManageThemes {
|
if !user.Perms.ManageThemes {
|
||||||
return common.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
wid, err := strconv.Atoi(swid)
|
wid, err := strconv.Atoi(swid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs)
|
return c.LocalErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user, isJs)
|
||||||
}
|
}
|
||||||
widget, err := common.Widgets.Get(wid)
|
widget, err := c.Widgets.Get(wid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.NotFound(w, r, nil)
|
return c.NotFound(w, r, nil)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = widget.Delete()
|
err = widget.Delete()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
return successRedirect("/panel/themes/widgets/", w, r, isJs)
|
return successRedirect("/panel/themes/widgets/", w, r, isJs)
|
||||||
|
|
|
@ -6,85 +6,85 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PollVote(w http.ResponseWriter, r *http.Request, user common.User, sPollID string) common.RouteError {
|
func PollVote(w http.ResponseWriter, r *http.Request, user c.User, sPollID string) c.RouteError {
|
||||||
pollID, err := strconv.Atoi(sPollID)
|
pollID, err := strconv.Atoi(sPollID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.PreError("The provided PollID is not a valid number.", w, r)
|
return c.PreError("The provided PollID is not a valid number.", w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
poll, err := common.Polls.Get(pollID)
|
poll, err := c.Polls.Get(pollID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreError("The poll you tried to vote for doesn't exist.", w, r)
|
return c.PreError("The poll you tried to vote for doesn't exist.", w, r)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
var topic *common.Topic
|
var topic *c.Topic
|
||||||
if poll.ParentTable == "replies" {
|
if poll.ParentTable == "replies" {
|
||||||
reply, err := common.Rstore.Get(poll.ParentID)
|
reply, err := c.Rstore.Get(poll.ParentID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreError("The parent post doesn't exist.", w, r)
|
return c.PreError("The parent post doesn't exist.", w, r)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
topic, err = common.Topics.Get(reply.ParentID)
|
topic, err = c.Topics.Get(reply.ParentID)
|
||||||
} else if poll.ParentTable == "topics" {
|
} else if poll.ParentTable == "topics" {
|
||||||
topic, err = common.Topics.Get(poll.ParentID)
|
topic, err = c.Topics.Get(poll.ParentID)
|
||||||
} else {
|
} else {
|
||||||
return common.InternalError(errors.New("Unknown parentTable for poll"), w, r)
|
return c.InternalError(errors.New("Unknown parentTable for poll"), w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreError("The parent topic doesn't exist.", w, r)
|
return c.PreError("The parent topic doesn't exist.", w, r)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
_, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
_, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic {
|
if !user.Perms.ViewTopic {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
optionIndex, err := strconv.Atoi(r.PostFormValue("poll_option_input"))
|
optionIndex, err := strconv.Atoi(r.PostFormValue("poll_option_input"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("Malformed input", w, r, user)
|
return c.LocalError("Malformed input", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = poll.CastVote(optionIndex, user.ID, user.LastIP)
|
err = poll.CastVote(optionIndex, user.ID, user.LastIP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(topic.ID), http.StatusSeeOther)
|
http.Redirect(w, r, "/topic/"+strconv.Itoa(topic.ID), http.StatusSeeOther)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func PollResults(w http.ResponseWriter, r *http.Request, user common.User, sPollID string) common.RouteError {
|
func PollResults(w http.ResponseWriter, r *http.Request, user c.User, sPollID string) c.RouteError {
|
||||||
//log.Print("in PollResults")
|
//log.Print("in PollResults")
|
||||||
pollID, err := strconv.Atoi(sPollID)
|
pollID, err := strconv.Atoi(sPollID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.PreError("The provided PollID is not a valid number.", w, r)
|
return c.PreError("The provided PollID is not a valid number.", w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
poll, err := common.Polls.Get(pollID)
|
poll, err := c.Polls.Get(pollID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreError("The poll you tried to vote for doesn't exist.", w, r)
|
return c.PreError("The poll you tried to vote for doesn't exist.", w, r)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Abstract this
|
// TODO: Abstract this
|
||||||
rows, err := qgen.NewAcc().Select("polls_options").Columns("votes").Where("pollID = ?").Orderby("option ASC").Query(poll.ID)
|
rows, err := qgen.NewAcc().Select("polls_options").Columns("votes").Where("pollID = ?").Orderby("option ASC").Query(poll.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
|
@ -93,13 +93,13 @@ func PollResults(w http.ResponseWriter, r *http.Request, user common.User, sPoll
|
||||||
var votes int
|
var votes int
|
||||||
err := rows.Scan(&votes)
|
err := rows.Scan(&votes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
optionList += strconv.Itoa(votes) + ","
|
optionList += strconv.Itoa(votes) + ","
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
err = rows.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement a version of this which doesn't rely so much on sequential order
|
// TODO: Implement a version of this which doesn't rely so much on sequential order
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/common/phrases"
|
"github.com/Azareal/Gosora/common/phrases"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
)
|
)
|
||||||
|
@ -19,7 +19,7 @@ var profileStmts ProfileStmts
|
||||||
|
|
||||||
// TODO: Move these DbInits into some sort of abstraction
|
// TODO: Move these DbInits into some sort of abstraction
|
||||||
func init() {
|
func init() {
|
||||||
common.DbInits.Add(func(acc *qgen.Accumulator) error {
|
c.DbInits.Add(func(acc *qgen.Accumulator) error {
|
||||||
profileStmts = ProfileStmts{
|
profileStmts = ProfileStmts{
|
||||||
getReplies: acc.SimpleLeftJoin("users_replies", "users", "users_replies.rid, users_replies.content, users_replies.createdBy, users_replies.createdAt, users_replies.lastEdit, users_replies.lastEditBy, users.avatar, users.name, users.group", "users_replies.createdBy = users.uid", "users_replies.uid = ?", "", ""),
|
getReplies: acc.SimpleLeftJoin("users_replies", "users", "users_replies.rid, users_replies.content, users_replies.createdBy, users_replies.createdAt, users_replies.lastEdit, users_replies.lastEditBy, users.avatar, users.name, users.group", "users_replies.createdBy = users.uid", "users_replies.uid = ?", "", ""),
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove the View part of the name?
|
// TODO: Remove the View part of the name?
|
||||||
func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
|
func ViewProfile(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
|
||||||
// TODO: Preload this?
|
// TODO: Preload this?
|
||||||
header.AddSheet(header.Theme.Name + "/profile.css")
|
header.AddSheet(header.Theme.Name + "/profile.css")
|
||||||
if user.Loggedin {
|
if user.Loggedin {
|
||||||
|
@ -39,57 +39,57 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User, heade
|
||||||
var replyCreatedAt time.Time
|
var replyCreatedAt time.Time
|
||||||
var replyContent, replyCreatedByName, replyAvatar, replyMicroAvatar, replyTag, replyClassName string
|
var replyContent, replyCreatedByName, replyAvatar, replyMicroAvatar, replyTag, replyClassName string
|
||||||
var rid, replyCreatedBy, replyLastEdit, replyLastEditBy, replyLines, replyGroup int
|
var rid, replyCreatedBy, replyLastEdit, replyLastEditBy, replyLines, replyGroup int
|
||||||
var replyList []common.ReplyUser
|
var replyList []c.ReplyUser
|
||||||
|
|
||||||
// TODO: Do a 301 if it's the wrong username? Do a canonical too?
|
// TODO: Do a 301 if it's the wrong username? Do a canonical too?
|
||||||
_, pid, err := ParseSEOURL(r.URL.Path[len("/user/"):])
|
_, pid, err := ParseSEOURL(r.URL.Path[len("/user/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("The provided UserID is not a valid number.", w, r, user)
|
return c.LocalError("The provided UserID is not a valid number.", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
var puser *common.User
|
var puser *c.User
|
||||||
if pid == user.ID {
|
if pid == user.ID {
|
||||||
user.IsMod = true
|
user.IsMod = true
|
||||||
puser = &user
|
puser = &user
|
||||||
} else {
|
} else {
|
||||||
// Fetch the user data
|
// Fetch the user data
|
||||||
// TODO: Add a shared function for checking for ErrNoRows and internal erroring if it's not that case?
|
// TODO: Add a shared function for checking for ErrNoRows and internal erroring if it's not that case?
|
||||||
puser, err = common.Users.Get(pid)
|
puser, err = c.Users.Get(pid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.NotFound(w, r, header)
|
return c.NotFound(w, r, header)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
puser.Init()
|
puser.Init()
|
||||||
}
|
}
|
||||||
header.Title = phrases.GetTitlePhrasef("profile", puser.Name)
|
header.Title = phrases.GetTitlePhrasef("profile", puser.Name)
|
||||||
header.Path = common.BuildProfileURL(common.NameToSlug(puser.Name), puser.ID)
|
header.Path = c.BuildProfileURL(c.NameToSlug(puser.Name), puser.ID)
|
||||||
|
|
||||||
// Get the replies..
|
// Get the replies..
|
||||||
rows, err := profileStmts.getReplies.Query(puser.ID)
|
rows, err := profileStmts.getReplies.Query(puser.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
err := rows.Scan(&rid, &replyContent, &replyCreatedBy, &replyCreatedAt, &replyLastEdit, &replyLastEditBy, &replyAvatar, &replyCreatedByName, &replyGroup)
|
err := rows.Scan(&rid, &replyContent, &replyCreatedBy, &replyCreatedAt, &replyLastEdit, &replyLastEditBy, &replyAvatar, &replyCreatedByName, &replyGroup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := common.Groups.Get(replyGroup)
|
group, err := c.Groups.Get(replyGroup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
replyLines = strings.Count(replyContent, "\n")
|
replyLines = strings.Count(replyContent, "\n")
|
||||||
if group.IsMod {
|
if group.IsMod {
|
||||||
replyClassName = common.Config.StaffCSS
|
replyClassName = c.Config.StaffCSS
|
||||||
} else {
|
} else {
|
||||||
replyClassName = ""
|
replyClassName = ""
|
||||||
}
|
}
|
||||||
replyAvatar, replyMicroAvatar = common.BuildAvatar(replyCreatedBy, replyAvatar)
|
replyAvatar, replyMicroAvatar = c.BuildAvatar(replyCreatedBy, replyAvatar)
|
||||||
|
|
||||||
if group.Tag != "" {
|
if group.Tag != "" {
|
||||||
replyTag = group.Tag
|
replyTag = group.Tag
|
||||||
|
@ -103,18 +103,18 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User, heade
|
||||||
replyLikeCount := 0
|
replyLikeCount := 0
|
||||||
// TODO: Add a hook here
|
// TODO: Add a hook here
|
||||||
|
|
||||||
replyList = append(replyList, common.ReplyUser{rid, puser.ID, replyContent, common.ParseMessage(replyContent, 0, ""), replyCreatedBy, common.BuildProfileURL(common.NameToSlug(replyCreatedByName), replyCreatedBy), replyCreatedByName, replyGroup, replyCreatedAt, replyLastEdit, replyLastEditBy, replyAvatar, replyMicroAvatar, replyClassName, replyLines, replyTag, "", "", "", 0, "", replyLiked, replyLikeCount, 0, "", "", nil})
|
replyList = append(replyList, c.ReplyUser{rid, puser.ID, replyContent, c.ParseMessage(replyContent, 0, ""), replyCreatedBy, c.BuildProfileURL(c.NameToSlug(replyCreatedByName), replyCreatedBy), replyCreatedByName, replyGroup, replyCreatedAt, replyLastEdit, replyLastEditBy, replyAvatar, replyMicroAvatar, replyClassName, replyLines, replyTag, "", "", "", 0, "", replyLiked, replyLikeCount, 0, "", "", nil})
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
err = rows.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalise the score so that the user sees their relative progress to the next level rather than showing them their total score
|
// Normalise the score so that the user sees their relative progress to the next level rather than showing them their total score
|
||||||
prevScore := common.GetLevelScore(puser.Level)
|
prevScore := c.GetLevelScore(puser.Level)
|
||||||
currentScore := puser.Score - prevScore
|
currentScore := puser.Score - prevScore
|
||||||
nextScore := common.GetLevelScore(puser.Level+1) - prevScore
|
nextScore := c.GetLevelScore(puser.Level+1) - prevScore
|
||||||
|
|
||||||
ppage := common.ProfilePage{header, replyList, *puser, currentScore, nextScore}
|
ppage := c.ProfilePage{header, replyList, *puser, currentScore, nextScore}
|
||||||
return renderTemplate("profile", w, r, header, ppage)
|
return renderTemplate("profile", w, r, header, ppage)
|
||||||
}
|
}
|
||||||
|
|
298
routes/reply.go
298
routes/reply.go
|
@ -8,7 +8,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"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"
|
"github.com/Azareal/Gosora/common/phrases"
|
||||||
"github.com/Azareal/Gosora/query_gen"
|
"github.com/Azareal/Gosora/query_gen"
|
||||||
|
@ -23,7 +23,7 @@ var replyStmts ReplyStmts
|
||||||
|
|
||||||
// TODO: Move this statement somewhere else
|
// TODO: Move this statement somewhere else
|
||||||
func init() {
|
func init() {
|
||||||
common.DbInits.Add(func(acc *qgen.Accumulator) error {
|
c.DbInits.Add(func(acc *qgen.Accumulator) error {
|
||||||
replyStmts = ReplyStmts{
|
replyStmts = ReplyStmts{
|
||||||
// TODO: Less race-y attachment count updates
|
// TODO: Less race-y attachment count updates
|
||||||
updateAttachs: acc.Update("replies").Set("attachCount = ?").Where("rid = ?").Prepare(),
|
updateAttachs: acc.Update("replies").Set("attachCount = ?").Where("rid = ?").Prepare(),
|
||||||
|
@ -37,43 +37,43 @@ type JsonReply struct {
|
||||||
Content string
|
Content string
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
// TODO: Use this
|
// TODO: Use this
|
||||||
js := r.FormValue("js") == "1"
|
js := r.FormValue("js") == "1"
|
||||||
tid, err := strconv.Atoi(r.PostFormValue("tid"))
|
tid, err := strconv.Atoi(r.PostFormValue("tid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.PreErrorJSQ("Failed to convert the Topic ID", w, r, js)
|
return c.PreErrorJSQ("Failed to convert the Topic ID", w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := common.Topics.Get(tid)
|
topic, err := c.Topics.Get(tid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJSQ("Couldn't find the parent topic", w, r, js)
|
return c.PreErrorJSQ("Couldn't find the parent topic", w, r, js)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
lite, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.CreateReply {
|
if !user.Perms.ViewTopic || !user.Perms.CreateReply {
|
||||||
return common.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, user, js)
|
||||||
}
|
}
|
||||||
if topic.IsClosed && !user.Perms.CloseTopic {
|
if topic.IsClosed && !user.Perms.CloseTopic {
|
||||||
return common.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, user, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
content := common.PreparseMessage(r.PostFormValue("reply-content"))
|
content := c.PreparseMessage(r.PostFormValue("reply-content"))
|
||||||
// TODO: Fully parse the post and put that in the parsed column
|
// TODO: Fully parse the post and put that in the parsed column
|
||||||
rid, err := common.Rstore.Create(topic, content, user.LastIP, user.ID)
|
rid, err := c.Rstore.Create(topic, content, user.LastIP, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := common.Rstore.Get(rid)
|
reply, err := c.Rstore.Get(rid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ("Unable to load the reply", w, r, user, js)
|
return c.LocalErrorJSQ("Unable to load the reply", w, r, user, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the file attachments
|
// Handle the file attachments
|
||||||
|
@ -89,26 +89,26 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
var maxPollOptions = 10
|
var maxPollOptions = 10
|
||||||
var pollInputItems = make(map[int]string)
|
var pollInputItems = make(map[int]string)
|
||||||
for key, values := range r.Form {
|
for key, values := range r.Form {
|
||||||
//common.DebugDetail("key: ", key)
|
//c.DebugDetail("key: ", key)
|
||||||
//common.DebugDetailf("values: %+v\n", values)
|
//c.DebugDetailf("values: %+v\n", values)
|
||||||
for _, value := range values {
|
for _, value := range values {
|
||||||
if strings.HasPrefix(key, "pollinputitem[") {
|
if strings.HasPrefix(key, "pollinputitem[") {
|
||||||
halves := strings.Split(key, "[")
|
halves := strings.Split(key, "[")
|
||||||
if len(halves) != 2 {
|
if len(halves) != 2 {
|
||||||
return common.LocalErrorJSQ("Malformed pollinputitem", w, r, user, js)
|
return c.LocalErrorJSQ("Malformed pollinputitem", w, r, user, js)
|
||||||
}
|
}
|
||||||
halves[1] = strings.TrimSuffix(halves[1], "]")
|
halves[1] = strings.TrimSuffix(halves[1], "]")
|
||||||
|
|
||||||
index, err := strconv.Atoi(halves[1])
|
index, err := strconv.Atoi(halves[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ("Malformed pollinputitem", w, r, user, js)
|
return c.LocalErrorJSQ("Malformed pollinputitem", w, r, user, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are duplicates, then something has gone horribly wrong, so let's ignore them, this'll likely happen during an attack
|
// If there are duplicates, then something has gone horribly wrong, so let's ignore them, this'll likely happen during an attack
|
||||||
_, exists := pollInputItems[index]
|
_, exists := pollInputItems[index]
|
||||||
// TODO: Should we use SanitiseBody instead to keep the newlines?
|
// TODO: Should we use SanitiseBody instead to keep the newlines?
|
||||||
if !exists && len(common.SanitiseSingleLine(value)) != 0 {
|
if !exists && len(c.SanitiseSingleLine(value)) != 0 {
|
||||||
pollInputItems[index] = common.SanitiseSingleLine(value)
|
pollInputItems[index] = c.SanitiseSingleLine(value)
|
||||||
if len(pollInputItems) >= maxPollOptions {
|
if len(pollInputItems) >= maxPollOptions {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -124,40 +124,40 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
}
|
}
|
||||||
|
|
||||||
pollType := 0 // Basic single choice
|
pollType := 0 // Basic single choice
|
||||||
_, err := common.Polls.Create(reply, pollType, seqPollInputItems)
|
_, err := c.Polls.Create(reply, pollType, seqPollInputItems)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ("Failed to add poll to reply", w, r, user, js) // TODO: Might need to be an internal error as it could leave phantom polls?
|
return c.LocalErrorJSQ("Failed to add poll to reply", w, r, user, js) // TODO: Might need to be an internal error as it could leave phantom polls?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = common.Forums.UpdateLastTopic(tid, user.ID, topic.ParentID)
|
err = c.Forums.UpdateLastTopic(tid, user.ID, topic.ParentID)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
common.AddActivityAndNotifyAll(user.ID, topic.CreatedBy, "reply", "topic", tid)
|
c.AddActivityAndNotifyAll(user.ID, topic.CreatedBy, "reply", "topic", tid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
wcount := common.WordCount(content)
|
wcount := c.WordCount(content)
|
||||||
err = user.IncreasePostStats(wcount, false)
|
err = user.IncreasePostStats(wcount, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
nTopic, err := common.Topics.Get(tid)
|
nTopic, err := c.Topics.Get(tid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJSQ("Couldn't find the parent topic", w, r, js)
|
return c.PreErrorJSQ("Couldn't find the parent topic", w, r, js)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
page := common.LastPage(nTopic.PostCount, common.Config.ItemsPerPage)
|
page := c.LastPage(nTopic.PostCount, c.Config.ItemsPerPage)
|
||||||
|
|
||||||
rows, err := replyStmts.createReplyPaging.Query(reply.ID, topic.ID)
|
rows, err := replyStmts.createReplyPaging.Query(reply.ID, topic.ID)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
|
@ -166,16 +166,16 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
var rid int
|
var rid int
|
||||||
err := rows.Scan(&rid)
|
err := rows.Scan(&rid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
rids = append(rids, rid)
|
rids = append(rids, rid)
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
err = rows.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
if len(rids) == 0 {
|
if len(rids) == 0 {
|
||||||
return common.NotFoundJSQ(w, r, nil, js)
|
return c.NotFoundJSQ(w, r, nil, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
if page > 1 {
|
if page > 1 {
|
||||||
|
@ -185,7 +185,7 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
} else if len(rids) == 2 && rids[1] == reply.ID {
|
} else if len(rids) == 2 && rids[1] == reply.ID {
|
||||||
offset = 2
|
offset = 2
|
||||||
}
|
}
|
||||||
page = common.LastPage(nTopic.PostCount-(len(rids)+offset), common.Config.ItemsPerPage)
|
page = c.LastPage(nTopic.PostCount-(len(rids)+offset), c.Config.ItemsPerPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.PostCounter.Bump()
|
counters.PostCounter.Bump()
|
||||||
|
@ -196,9 +196,9 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
|
|
||||||
prid, _ := strconv.Atoi(r.FormValue("prid"))
|
prid, _ := strconv.Atoi(r.FormValue("prid"))
|
||||||
if js && (prid == 0 || rids[0] == prid) {
|
if js && (prid == 0 || rids[0] == prid) {
|
||||||
outBytes, err := json.Marshal(JsonReply{common.ParseMessage(reply.Content, topic.ParentID, "forums")})
|
outBytes, err := json.Marshal(JsonReply{c.ParseMessage(reply.Content, topic.ParentID, "forums")})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
w.Write(outBytes)
|
w.Write(outBytes)
|
||||||
} else {
|
} else {
|
||||||
|
@ -213,52 +213,52 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
|
|
||||||
// TODO: Disable stat updates in posts handled by plugin_guilds
|
// TODO: Disable stat updates in posts handled by plugin_guilds
|
||||||
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
|
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
|
||||||
func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, srid string) common.RouteError {
|
func ReplyEditSubmit(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 common.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)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := common.Rstore.Get(rid)
|
reply, err := c.Rstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJSQ("The target reply doesn't exist.", w, r, js)
|
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, js)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := reply.Topic()
|
topic, err := reply.Topic()
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJSQ("The parent topic doesn't exist.", w, r, js)
|
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, js)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
lite, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.EditReply {
|
if !user.Perms.ViewTopic || !user.Perms.EditReply {
|
||||||
return common.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, user, js)
|
||||||
}
|
}
|
||||||
if topic.IsClosed && !user.Perms.CloseTopic {
|
if topic.IsClosed && !user.Perms.CloseTopic {
|
||||||
return common.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, user, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = reply.SetPost(r.PostFormValue("edit_item"))
|
err = reply.SetPost(r.PostFormValue("edit_item"))
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJSQ("The parent topic doesn't exist.", w, r, js)
|
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, js)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Avoid the load to get this faster?
|
// TODO: Avoid the load to get this faster?
|
||||||
reply, err = common.Rstore.Get(rid)
|
reply, err = c.Rstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJSQ("The updated reply doesn't exist.", w, r, js)
|
return c.PreErrorJSQ("The updated reply doesn't exist.", w, r, js)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
skip, rerr := lite.Hooks.VhookSkippable("action_end_edit_reply", reply.ID, &user)
|
skip, rerr := lite.Hooks.VhookSkippable("action_end_edit_reply", reply.ID, &user)
|
||||||
|
@ -269,9 +269,9 @@ func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, s
|
||||||
if !js {
|
if !js {
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(topic.ID)+"#reply-"+strconv.Itoa(rid), http.StatusSeeOther)
|
http.Redirect(w, r, "/topic/"+strconv.Itoa(topic.ID)+"#reply-"+strconv.Itoa(rid), http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
outBytes, err := json.Marshal(JsonReply{common.ParseMessage(reply.Content, topic.ParentID, "forums")})
|
outBytes, err := json.Marshal(JsonReply{c.ParseMessage(reply.Content, topic.ParentID, "forums")})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
w.Write(outBytes)
|
w.Write(outBytes)
|
||||||
}
|
}
|
||||||
|
@ -281,39 +281,39 @@ func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, s
|
||||||
|
|
||||||
// TODO: Refactor this
|
// TODO: Refactor this
|
||||||
// TODO: Disable stat updates in posts handled by plugin_guilds
|
// TODO: Disable stat updates in posts handled by plugin_guilds
|
||||||
func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user common.User, srid string) common.RouteError {
|
func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
||||||
isJs := (r.PostFormValue("isJs") == "1")
|
isJs := (r.PostFormValue("isJs") == "1")
|
||||||
rid, err := strconv.Atoi(srid)
|
rid, err := strconv.Atoi(srid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, isJs)
|
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := common.Rstore.Get(rid)
|
reply, err := c.Rstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJSQ("The reply you tried to delete doesn't exist.", w, r, isJs)
|
return c.PreErrorJSQ("The reply you tried to delete doesn't exist.", w, r, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := common.Topics.Get(reply.ParentID)
|
topic, err := c.Topics.Get(reply.ParentID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJSQ("The parent topic doesn't exist.", w, r, isJs)
|
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
lite, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.DeleteReply {
|
if !user.Perms.ViewTopic || !user.Perms.DeleteReply {
|
||||||
return common.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = reply.Delete()
|
err = reply.Delete()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
skip, rerr := lite.Hooks.VhookSkippable("action_end_delete_reply", reply.ID, &user)
|
skip, rerr := lite.Hooks.VhookSkippable("action_end_delete_reply", reply.ID, &user)
|
||||||
|
@ -321,7 +321,7 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user common.User,
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
|
|
||||||
//log.Printf("Reply #%d was deleted by common.User #%d", rid, user.ID)
|
//log.Printf("Reply #%d was deleted by c.User #%d", rid, user.ID)
|
||||||
if !isJs {
|
if !isJs {
|
||||||
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
|
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
|
@ -329,20 +329,20 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user common.User,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ? - What happens if an error fires after a redirect...?
|
// ? - What happens if an error fires after a redirect...?
|
||||||
replyCreator, err := common.Users.Get(reply.CreatedBy)
|
replyCreator, err := c.Users.Get(reply.CreatedBy)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
wcount := common.WordCount(reply.Content)
|
wcount := c.WordCount(reply.Content)
|
||||||
err = replyCreator.DecreasePostStats(wcount, false)
|
err = replyCreator.DecreasePostStats(wcount, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
} else if err != sql.ErrNoRows {
|
} else if err != sql.ErrNoRows {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = common.ModLogs.Create("delete", reply.ParentID, "reply", user.LastIP, user.ID)
|
err = c.ModLogs.Create("delete", reply.ParentID, "reply", user.LastIP, user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -350,33 +350,33 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user common.User,
|
||||||
// TODO: Avoid uploading this again if the attachment already exists? They'll resolve to the same hash either way, but we could save on some IO / bandwidth here
|
// TODO: Avoid uploading this again if the attachment already exists? They'll resolve to the same hash either way, but we could save on some IO / bandwidth here
|
||||||
// TODO: Enforce the max request limit on all of this topic's attachments
|
// TODO: Enforce the max request limit on all of this topic's attachments
|
||||||
// TODO: Test this route
|
// TODO: Test this route
|
||||||
func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user common.User, srid string) common.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 common.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
|
return c.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := common.Rstore.Get(rid)
|
reply, err := c.Rstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJS("You can't attach to something which doesn't exist!", w, r)
|
return c.PreErrorJS("You can't attach to something which doesn't exist!", w, r)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJS(err, w, r)
|
return c.InternalErrorJS(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := common.Topics.Get(reply.ParentID)
|
topic, err := c.Topics.Get(reply.ParentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.NotFoundJS(w, r)
|
return c.NotFoundJS(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
lite, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.EditReply || !user.Perms.UploadFiles {
|
if !user.Perms.ViewTopic || !user.Perms.EditReply || !user.Perms.UploadFiles {
|
||||||
return common.NoPermissionsJS(w, r, user)
|
return c.NoPermissionsJS(w, r, user)
|
||||||
}
|
}
|
||||||
if topic.IsClosed && !user.Perms.CloseTopic {
|
if topic.IsClosed && !user.Perms.CloseTopic {
|
||||||
return common.NoPermissionsJS(w, r, user)
|
return c.NoPermissionsJS(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the file attachments
|
// Handle the file attachments
|
||||||
|
@ -386,7 +386,7 @@ func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user common.
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
if len(pathMap) == 0 {
|
if len(pathMap) == 0 {
|
||||||
return common.InternalErrorJS(errors.New("no paths for attachment add"), w, r)
|
return c.InternalErrorJS(errors.New("no paths for attachment add"), w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
skip, rerr := lite.Hooks.VhookSkippable("action_end_add_attach_to_reply", reply.ID, &user)
|
skip, rerr := lite.Hooks.VhookSkippable("action_end_add_attach_to_reply", reply.ID, &user)
|
||||||
|
@ -407,43 +407,43 @@ func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user common.
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Reduce the amount of duplication between this and RemoveAttachFromTopicSubmit
|
// TODO: Reduce the amount of duplication between this and RemoveAttachFromTopicSubmit
|
||||||
func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, user common.User, srid string) common.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 common.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
|
return c.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := common.Rstore.Get(rid)
|
reply, err := c.Rstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJS("You can't attach from something which doesn't exist!", w, r)
|
return c.PreErrorJS("You can't attach from something which doesn't exist!", w, r)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJS(err, w, r)
|
return c.InternalErrorJS(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := common.Topics.Get(reply.ParentID)
|
topic, err := c.Topics.Get(reply.ParentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.NotFoundJS(w, r)
|
return c.NotFoundJS(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
lite, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.EditReply {
|
if !user.Perms.ViewTopic || !user.Perms.EditReply {
|
||||||
return common.NoPermissionsJS(w, r, user)
|
return c.NoPermissionsJS(w, r, user)
|
||||||
}
|
}
|
||||||
if topic.IsClosed && !user.Perms.CloseTopic {
|
if topic.IsClosed && !user.Perms.CloseTopic {
|
||||||
return common.NoPermissionsJS(w, r, user)
|
return c.NoPermissionsJS(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
saids := strings.Split(r.PostFormValue("aids"), ",")
|
saids := strings.Split(r.PostFormValue("aids"), ",")
|
||||||
if len(saids) == 0 {
|
if len(saids) == 0 {
|
||||||
return common.LocalErrorJS("No aids provided", w, r)
|
return c.LocalErrorJS("No aids provided", w, r)
|
||||||
}
|
}
|
||||||
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 common.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
|
return c.LocalErrorJS(phrases.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 {
|
||||||
|
@ -462,35 +462,35 @@ func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, user co
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move the profile reply routes to their own file?
|
// TODO: Move the profile reply routes to their own file?
|
||||||
func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
|
||||||
if !user.Perms.ViewTopic || !user.Perms.CreateReply {
|
if !user.Perms.ViewTopic || !user.Perms.CreateReply {
|
||||||
return common.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
uid, err := strconv.Atoi(r.PostFormValue("uid"))
|
uid, err := strconv.Atoi(r.PostFormValue("uid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("Invalid UID", w, r, user)
|
return c.LocalError("Invalid UID", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
profileOwner, err := common.Users.Get(uid)
|
profileOwner, err := c.Users.Get(uid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.LocalError("The profile you're trying to post on doesn't exist.", w, r, user)
|
return c.LocalError("The profile you're trying to post on doesn't exist.", w, r, user)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
content := common.PreparseMessage(r.PostFormValue("reply-content"))
|
content := c.PreparseMessage(r.PostFormValue("reply-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
|
||||||
_, err = common.Prstore.Create(profileOwner.ID, content, user.ID, user.LastIP)
|
_, err = c.Prstore.Create(profileOwner.ID, content, user.ID, user.LastIP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ! Be careful about leaking per-route permission state with &user
|
// ! Be careful about leaking per-route permission state with &user
|
||||||
alert := common.Alert{0, user.ID, profileOwner.ID, "reply", "user", profileOwner.ID, &user}
|
alert := c.Alert{0, user.ID, profileOwner.ID, "reply", "user", profileOwner.ID, &user}
|
||||||
err = common.AddActivityAndNotifyTarget(alert)
|
err = c.AddActivityAndNotifyTarget(alert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.PostCounter.Bump()
|
counters.PostCounter.Bump()
|
||||||
|
@ -498,34 +498,34 @@ func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user commo
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, srid string) common.RouteError {
|
func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
||||||
isJs := (r.PostFormValue("js") == "1")
|
isJs := (r.PostFormValue("js") == "1")
|
||||||
|
|
||||||
rid, err := strconv.Atoi(srid)
|
rid, err := strconv.Atoi(srid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, isJs)
|
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := common.Prstore.Get(rid)
|
reply, err := c.Prstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJSQ("The target reply doesn't exist.", w, r, isJs)
|
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
creator, err := common.Users.Get(reply.CreatedBy)
|
creator, err := c.Users.Get(reply.CreatedBy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ? Does the admin understand that this group perm affects this?
|
// ? Does the admin understand that this group perm affects this?
|
||||||
if user.ID != creator.ID && !user.Perms.EditReply {
|
if user.ID != creator.ID && !user.Perms.EditReply {
|
||||||
return common.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = reply.SetBody(r.PostFormValue("edit_item"))
|
err = reply.SetBody(r.PostFormValue("edit_item"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isJs {
|
if !isJs {
|
||||||
|
@ -536,35 +536,35 @@ func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user common.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user common.User, srid string) common.RouteError {
|
func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
||||||
isJs := (r.PostFormValue("isJs") == "1")
|
isJs := (r.PostFormValue("isJs") == "1")
|
||||||
|
|
||||||
rid, err := strconv.Atoi(srid)
|
rid, err := strconv.Atoi(srid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, isJs)
|
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := common.Prstore.Get(rid)
|
reply, err := c.Prstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJSQ("The target reply doesn't exist.", w, r, isJs)
|
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
creator, err := common.Users.Get(reply.CreatedBy)
|
creator, err := c.Users.Get(reply.CreatedBy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.ID != creator.ID && !user.Perms.DeleteReply {
|
if user.ID != creator.ID && !user.Perms.DeleteReply {
|
||||||
return common.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = reply.Delete()
|
err = reply.Delete()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
//log.Printf("The profile post '%d' was deleted by common.User #%d", reply.ID, user.ID)
|
//log.Printf("The profile post '%d' was deleted by c.User #%d", reply.ID, user.ID)
|
||||||
|
|
||||||
if !isJs {
|
if !isJs {
|
||||||
//http.Redirect(w,r, "/user/" + strconv.Itoa(creator.ID), http.StatusSeeOther)
|
//http.Redirect(w,r, "/user/" + strconv.Itoa(creator.ID), http.StatusSeeOther)
|
||||||
|
@ -574,59 +574,59 @@ func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user commo
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user common.User, srid string) common.RouteError {
|
func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
|
||||||
isJs := (r.PostFormValue("isJs") == "1")
|
isJs := (r.PostFormValue("isJs") == "1")
|
||||||
|
|
||||||
rid, err := strconv.Atoi(srid)
|
rid, err := strconv.Atoi(srid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, isJs)
|
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := common.Rstore.Get(rid)
|
reply, err := c.Rstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJSQ("You can't like something which doesn't exist!", w, r, isJs)
|
return c.PreErrorJSQ("You can't like something which doesn't exist!", w, r, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := common.Topics.Get(reply.ParentID)
|
topic, err := c.Topics.Get(reply.ParentID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.PreErrorJSQ("The parent topic doesn't exist.", w, r, isJs)
|
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add hooks to make use of headerLite
|
// TODO: Add hooks to make use of headerLite
|
||||||
lite, ferr := common.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ViewTopic || !user.Perms.LikeItem {
|
if !user.Perms.ViewTopic || !user.Perms.LikeItem {
|
||||||
return common.NoPermissionsJSQ(w, r, user, isJs)
|
return c.NoPermissionsJSQ(w, r, user, isJs)
|
||||||
}
|
}
|
||||||
if reply.CreatedBy == user.ID {
|
if reply.CreatedBy == user.ID {
|
||||||
return common.LocalErrorJSQ("You can't like your own replies", w, r, user, isJs)
|
return c.LocalErrorJSQ("You can't like your own replies", w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = common.Users.Get(reply.CreatedBy)
|
_, err = c.Users.Get(reply.CreatedBy)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.LocalErrorJSQ("The target user doesn't exist", w, r, user, isJs)
|
return c.LocalErrorJSQ("The target user doesn't exist", w, r, user, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = reply.Like(user.ID)
|
err = reply.Like(user.ID)
|
||||||
if err == common.ErrAlreadyLiked {
|
if err == c.ErrAlreadyLiked {
|
||||||
return common.LocalErrorJSQ("You've already liked this!", w, r, user, isJs)
|
return c.LocalErrorJSQ("You've already liked this!", w, r, user, isJs)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ! Be careful about leaking per-route permission state with &user
|
// ! Be careful about leaking per-route permission state with &user
|
||||||
alert := common.Alert{0, user.ID, reply.CreatedBy, "like", "post", rid, &user}
|
alert := c.Alert{0, user.ID, reply.CreatedBy, "like", "post", rid, &user}
|
||||||
err = common.AddActivityAndNotifyTarget(alert)
|
err = c.AddActivityAndNotifyTarget(alert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalErrorJSQ(err, w, r, isJs)
|
return c.InternalErrorJSQ(err, w, r, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
skip, rerr := lite.Hooks.VhookSkippable("action_end_like_reply", reply.ID, &user)
|
skip, rerr := lite.Hooks.VhookSkippable("action_end_like_reply", reply.ID, &user)
|
||||||
|
|
|
@ -5,12 +5,12 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/common/counters"
|
"github.com/Azareal/Gosora/common/counters"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ReportSubmit(w http.ResponseWriter, r *http.Request, user common.User, sitemID string) common.RouteError {
|
func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError {
|
||||||
headerLite, ferr := common.SimpleUserCheck(w, r, &user)
|
headerLite, ferr := c.SimpleUserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
|
@ -18,51 +18,51 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user common.User, site
|
||||||
|
|
||||||
itemID, err := strconv.Atoi(sitemID)
|
itemID, err := strconv.Atoi(sitemID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("Bad ID", w, r, user)
|
return c.LocalError("Bad ID", w, r, user)
|
||||||
}
|
}
|
||||||
itemType := r.FormValue("type")
|
itemType := r.FormValue("type")
|
||||||
|
|
||||||
// TODO: Localise these titles and bodies
|
// TODO: Localise these titles and bodies
|
||||||
var title, content string
|
var title, content string
|
||||||
if itemType == "reply" {
|
if itemType == "reply" {
|
||||||
reply, err := common.Rstore.Get(itemID)
|
reply, err := c.Rstore.Get(itemID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.LocalError("We were unable to find the reported post", w, r, user)
|
return c.LocalError("We were unable to find the reported post", w, r, user)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
topic, err := common.Topics.Get(reply.ParentID)
|
topic, err := c.Topics.Get(reply.ParentID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.LocalError("We weren't able to find the topic the reported post is supposed to be in", w, r, user)
|
return c.LocalError("We weren't able to find the topic the reported post is supposed to be in", w, r, user)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
title = "Reply: " + topic.Title
|
title = "Reply: " + topic.Title
|
||||||
content = reply.Content + "\n\nOriginal Post: #rid-" + strconv.Itoa(itemID)
|
content = reply.Content + "\n\nOriginal Post: #rid-" + strconv.Itoa(itemID)
|
||||||
} else if itemType == "user-reply" {
|
} else if itemType == "user-reply" {
|
||||||
userReply, err := common.Prstore.Get(itemID)
|
userReply, err := c.Prstore.Get(itemID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.LocalError("We weren't able to find the reported post", w, r, user)
|
return c.LocalError("We weren't able to find the reported post", w, r, user)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
profileOwner, err := common.Users.Get(userReply.ParentID)
|
profileOwner, err := c.Users.Get(userReply.ParentID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.LocalError("We weren't able to find the profile the reported post is supposed to be on", w, r, user)
|
return c.LocalError("We weren't able to find the profile the reported post is supposed to be on", w, r, user)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
title = "Profile: " + profileOwner.Name
|
title = "Profile: " + profileOwner.Name
|
||||||
content = userReply.Content + "\n\nOriginal Post: @" + strconv.Itoa(userReply.ParentID)
|
content = userReply.Content + "\n\nOriginal Post: @" + strconv.Itoa(userReply.ParentID)
|
||||||
} else if itemType == "topic" {
|
} else if itemType == "topic" {
|
||||||
topic, err := common.Topics.Get(itemID)
|
topic, err := c.Topics.Get(itemID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return common.NotFound(w, r, nil)
|
return c.NotFound(w, r, nil)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
title = "Topic: " + topic.Title
|
title = "Topic: " + topic.Title
|
||||||
content = topic.Content + "\n\nOriginal Post: #tid-" + strconv.Itoa(itemID)
|
content = topic.Content + "\n\nOriginal Post: #tid-" + strconv.Itoa(itemID)
|
||||||
|
@ -73,13 +73,13 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user common.User, site
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't try to guess the type
|
// Don't try to guess the type
|
||||||
return common.LocalError("Unknown type", w, r, user)
|
return c.LocalError("Unknown type", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Repost attachments in the reports forum, so that the mods can see them
|
// TODO: Repost attachments in the reports forum, so that the mods can see them
|
||||||
_, err = common.Reports.Create(title, content, &user, itemType, itemID)
|
_, err = c.Reports.Create(title, content, &user, itemType, itemID)
|
||||||
if err == common.ErrAlreadyReported {
|
if err == c.ErrAlreadyReported {
|
||||||
return common.LocalError("Someone has already reported this!", w, r, user)
|
return c.LocalError("Someone has already reported this!", w, r, user)
|
||||||
}
|
}
|
||||||
counters.PostCounter.Bump()
|
counters.PostCounter.Bump()
|
||||||
|
|
||||||
|
|
422
routes/topic.go
422
routes/topic.go
File diff suppressed because it is too large
Load Diff
|
@ -7,37 +7,37 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
"github.com/Azareal/Gosora/common/phrases"
|
"github.com/Azareal/Gosora/common/phrases"
|
||||||
)
|
)
|
||||||
|
|
||||||
func wsTopicList(topicList []*common.TopicsRow, lastPage int) *common.WsTopicList {
|
func wsTopicList(topicList []*c.TopicsRow, lastPage int) *c.WsTopicList {
|
||||||
wsTopicList := make([]*common.WsTopicsRow, len(topicList))
|
wsTopicList := make([]*c.WsTopicsRow, len(topicList))
|
||||||
for i, topicRow := range topicList {
|
for i, topicRow := range topicList {
|
||||||
wsTopicList[i] = topicRow.WebSockets()
|
wsTopicList[i] = topicRow.WebSockets()
|
||||||
}
|
}
|
||||||
return &common.WsTopicList{wsTopicList, lastPage}
|
return &c.WsTopicList{wsTopicList, lastPage}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TopicList(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
|
func TopicList(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
|
||||||
return TopicListCommon(w, r, user, header, "lastupdated", "")
|
return TopicListCommon(w, r, user, header, "lastupdated", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
|
func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
|
||||||
return TopicListCommon(w, r, user, header, "mostviewed", "most-viewed")
|
return TopicListCommon(w, r, user, header, "mostviewed", "most-viewed")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement search
|
// TODO: Implement search
|
||||||
func TopicListCommon(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header, torder string, tsorder string) common.RouteError {
|
func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header, torder string, tsorder string) c.RouteError {
|
||||||
header.Title = phrases.GetTitlePhrase("topics")
|
header.Title = phrases.GetTitlePhrase("topics")
|
||||||
header.Zone = "topics"
|
header.Zone = "topics"
|
||||||
header.Path = "/topics/"
|
header.Path = "/topics/"
|
||||||
header.MetaDesc = header.Settings["meta_desc"].(string)
|
header.MetaDesc = header.Settings["meta_desc"].(string)
|
||||||
|
|
||||||
group, err := common.Groups.Get(user.Group)
|
group, err := c.Groups.Get(user.Group)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Group #%d doesn't exist despite being used by common.User #%d", user.Group, user.ID)
|
log.Printf("Group #%d doesn't exist despite being used by c.User #%d", user.Group, user.ID)
|
||||||
return common.LocalError("Something weird happened", w, r, user)
|
return c.LocalError("Something weird happened", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the current page
|
// Get the current page
|
||||||
|
@ -48,14 +48,14 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user common.User, h
|
||||||
for _, sfid := range strings.Split(sfids, ",") {
|
for _, sfid := range strings.Split(sfids, ",") {
|
||||||
fid, err := strconv.Atoi(sfid)
|
fid, err := strconv.Atoi(sfid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("Invalid fid", w, r, user)
|
return c.LocalError("Invalid fid", w, r, user)
|
||||||
}
|
}
|
||||||
fids = append(fids, fid)
|
fids = append(fids, fid)
|
||||||
}
|
}
|
||||||
if len(fids) == 1 {
|
if len(fids) == 1 {
|
||||||
forum, err := common.Forums.Get(fids[0])
|
forum, err := c.Forums.Get(fids[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.LocalError("Invalid fid forum", w, r, user)
|
return c.LocalError("Invalid fid forum", w, r, user)
|
||||||
}
|
}
|
||||||
header.Title = forum.Name
|
header.Title = forum.Name
|
||||||
header.ZoneID = forum.ID
|
header.ZoneID = forum.ID
|
||||||
|
@ -64,16 +64,16 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user common.User, h
|
||||||
|
|
||||||
// TODO: Allow multiple forums in searches
|
// TODO: Allow multiple forums in searches
|
||||||
// TODO: Simplify this block after initially landing search
|
// TODO: Simplify this block after initially landing search
|
||||||
var topicList []*common.TopicsRow
|
var topicList []*c.TopicsRow
|
||||||
var forumList []common.Forum
|
var forumList []c.Forum
|
||||||
var paginator common.Paginator
|
var paginator c.Paginator
|
||||||
q := r.FormValue("q")
|
q := r.FormValue("q")
|
||||||
if q != "" && common.RepliesSearch != nil {
|
if q != "" && c.RepliesSearch != nil {
|
||||||
var canSee []int
|
var canSee []int
|
||||||
if user.IsSuperAdmin {
|
if user.IsSuperAdmin {
|
||||||
canSee, err = common.Forums.GetAllVisibleIDs()
|
canSee, err = c.Forums.GetAllVisibleIDs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
canSee = group.CanSee
|
canSee = group.CanSee
|
||||||
|
@ -91,7 +91,7 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user common.User, h
|
||||||
}
|
}
|
||||||
for _, fid := range fids {
|
for _, fid := range fids {
|
||||||
if inSlice(canSee, fid) {
|
if inSlice(canSee, fid) {
|
||||||
forum := common.Forums.DirtyGet(fid)
|
forum := c.Forums.DirtyGet(fid)
|
||||||
if forum.Name != "" && forum.Active && (forum.ParentType == "" || forum.ParentType == "forum") {
|
if forum.Name != "" && forum.Active && (forum.ParentType == "" || forum.ParentType == "forum") {
|
||||||
// TODO: Add a hook here for plugin_guilds?
|
// TODO: Add a hook here for plugin_guilds?
|
||||||
cfids = append(cfids, fid)
|
cfids = append(cfids, fid)
|
||||||
|
@ -102,16 +102,16 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user common.User, h
|
||||||
cfids = canSee
|
cfids = canSee
|
||||||
}
|
}
|
||||||
|
|
||||||
tids, err := common.RepliesSearch.Query(q, cfids)
|
tids, err := c.RepliesSearch.Query(q, cfids)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
//fmt.Printf("tids %+v\n", tids)
|
//fmt.Printf("tids %+v\n", tids)
|
||||||
// TODO: Handle the case where there aren't any items...
|
// TODO: Handle the case where there aren't any items...
|
||||||
// TODO: Add a BulkGet method which returns a slice?
|
// TODO: Add a BulkGet method which returns a slice?
|
||||||
tMap, err := common.Topics.BulkGetMap(tids)
|
tMap, err := c.Topics.BulkGetMap(tids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
var reqUserList = make(map[int]bool)
|
var reqUserList = make(map[int]bool)
|
||||||
for _, topic := range tMap {
|
for _, topic := range tMap {
|
||||||
|
@ -131,21 +131,21 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user common.User, h
|
||||||
|
|
||||||
// TODO: What if a user is deleted via the Control Panel?
|
// TODO: What if a user is deleted via the Control Panel?
|
||||||
//fmt.Printf("idSlice %+v\n", idSlice)
|
//fmt.Printf("idSlice %+v\n", idSlice)
|
||||||
userList, err := common.Users.BulkGetMap(idSlice)
|
userList, err := c.Users.BulkGetMap(idSlice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil // TODO: Implement this!
|
return nil // TODO: Implement this!
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: De-dupe this logic in common/topic_list.go?
|
// TODO: De-dupe this logic in common/topic_list.go?
|
||||||
for _, topic := range topicList {
|
for _, topic := range topicList {
|
||||||
topic.Link = common.BuildTopicURL(common.NameToSlug(topic.Title), topic.ID)
|
topic.Link = c.BuildTopicURL(c.NameToSlug(topic.Title), topic.ID)
|
||||||
// TODO: Pass forum to something like topic.Forum and use that instead of these two properties? Could be more flexible.
|
// TODO: Pass forum to something like topic.Forum and use that instead of these two properties? Could be more flexible.
|
||||||
forum := common.Forums.DirtyGet(topic.ParentID)
|
forum := c.Forums.DirtyGet(topic.ParentID)
|
||||||
topic.ForumName = forum.Name
|
topic.ForumName = forum.Name
|
||||||
topic.ForumLink = forum.Link
|
topic.ForumLink = forum.Link
|
||||||
|
|
||||||
// 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 := common.PageOffset(topic.PostCount, 1, common.Config.ItemsPerPage)
|
_, _, lastPage := c.PageOffset(topic.PostCount, 1, c.Config.ItemsPerPage)
|
||||||
topic.LastPage = lastPage
|
topic.LastPage = lastPage
|
||||||
topic.Creator = userList[topic.CreatedBy]
|
topic.Creator = userList[topic.CreatedBy]
|
||||||
topic.LastUser = userList[topic.LastReplyBy]
|
topic.LastUser = userList[topic.LastReplyBy]
|
||||||
|
@ -155,41 +155,41 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user common.User, h
|
||||||
if r.FormValue("js") == "1" {
|
if r.FormValue("js") == "1" {
|
||||||
outBytes, err := wsTopicList(topicList, paginator.LastPage).MarshalJSON()
|
outBytes, err := wsTopicList(topicList, paginator.LastPage).MarshalJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
w.Write(outBytes)
|
w.Write(outBytes)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
header.Title = phrases.GetTitlePhrase("topics_search")
|
header.Title = phrases.GetTitlePhrase("topics_search")
|
||||||
pi := common.TopicListPage{header, topicList, forumList, common.Config.DefaultForum, common.TopicListSort{torder, false}, paginator}
|
pi := c.TopicListPage{header, topicList, forumList, c.Config.DefaultForum, c.TopicListSort{torder, false}, paginator}
|
||||||
return renderTemplate("topics", w, r, header, pi)
|
return renderTemplate("topics", w, r, header, pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Pass a struct back rather than passing back so many variables
|
// TODO: Pass a struct back rather than passing back so many variables
|
||||||
if user.IsSuperAdmin {
|
if user.IsSuperAdmin {
|
||||||
topicList, forumList, paginator, err = common.TopicList.GetList(page, tsorder, fids)
|
topicList, forumList, paginator, err = c.TopicList.GetList(page, tsorder, fids)
|
||||||
} else {
|
} else {
|
||||||
topicList, forumList, paginator, err = common.TopicList.GetListByGroup(group, page, tsorder, fids)
|
topicList, forumList, paginator, err = c.TopicList.GetListByGroup(group, page, tsorder, fids)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
// ! Need an inline error not a page level error
|
// ! Need an inline error not a page level error
|
||||||
if len(topicList) == 0 {
|
if len(topicList) == 0 {
|
||||||
return common.NotFound(w, r, header)
|
return c.NotFound(w, r, header)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Reduce the amount of boilerplate here
|
// TODO: Reduce the amount of boilerplate here
|
||||||
if r.FormValue("js") == "1" {
|
if r.FormValue("js") == "1" {
|
||||||
outBytes, err := wsTopicList(topicList, paginator.LastPage).MarshalJSON()
|
outBytes, err := wsTopicList(topicList, paginator.LastPage).MarshalJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
w.Write(outBytes)
|
w.Write(outBytes)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := common.TopicListPage{header, topicList, forumList, common.Config.DefaultForum, common.TopicListSort{torder, false}, paginator}
|
pi := c.TopicListPage{header, topicList, forumList, c.Config.DefaultForum, c.TopicListSort{torder, false}, paginator}
|
||||||
return renderTemplate("topics", w, r, header, pi)
|
return renderTemplate("topics", w, r, header, pi)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue