Shorten the common namespaces in some areas to reduce the amount of boilerplate.

This commit is contained in:
Azareal 2019-04-19 16:36:26 +10:00
parent 00e30460b5
commit 20a6a22e78
27 changed files with 1250 additions and 1250 deletions

View File

@ -10,25 +10,25 @@ import (
"os"
"strconv"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/query_gen"
"gopkg.in/olivere/elastic.v6"
)
func main() {
log.Print("Loading the configuration data")
err := common.LoadConfig()
err := c.LoadConfig()
if err != nil {
log.Fatal(err)
}
log.Print("Processing configuration data")
err = common.ProcessConfig()
err = c.ProcessConfig()
if err != nil {
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")
}
@ -59,11 +59,11 @@ func main() {
func prepMySQL() error {
return qgen.Builder.Init("mysql", map[string]string{
"host": common.DbConfig.Host,
"port": common.DbConfig.Port,
"name": common.DbConfig.Dbname,
"username": common.DbConfig.Username,
"password": common.DbConfig.Password,
"host": c.DbConfig.Host,
"port": c.DbConfig.Port,
"name": c.DbConfig.Dbname,
"username": c.DbConfig.Username,
"password": c.DbConfig.Password,
"collation": "utf8mb4_general_ci",
})
}

View File

@ -3,7 +3,7 @@ package counters
import (
"database/sql"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/query_gen"
)
@ -23,9 +23,9 @@ func NewDefaultAgentViewCounter(acc *qgen.Accumulator) (*DefaultAgentViewCounter
agentBuckets: agentBuckets,
insert: acc.Insert("viewchunks_agents").Columns("count, createdAt, browser").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
}
common.AddScheduledFifteenMinuteTask(counter.Tick)
//common.AddScheduledSecondTask(counter.Tick)
common.AddShutdownTask(counter.Tick)
c.AddScheduledFifteenMinuteTask(counter.Tick)
//c.AddScheduledSecondTask(counter.Tick)
c.AddShutdownTask(counter.Tick)
return counter, acc.FirstError()
}
@ -50,14 +50,14 @@ func (counter *DefaultAgentViewCounter) insertChunk(count int, agent int) error
return nil
}
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)
return err
}
func (counter *DefaultAgentViewCounter) Bump(agent int) {
// 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 {
return
}

View File

@ -4,7 +4,7 @@ import (
"database/sql"
"sync"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/query_gen"
)
@ -28,9 +28,9 @@ func NewDefaultForumViewCounter() (*DefaultForumViewCounter, error) {
evenMap: make(map[int]*RWMutexCounterBucket),
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
//common.AddScheduledSecondTask(counter.Tick)
common.AddShutdownTask(counter.Tick)
c.AddScheduledFifteenMinuteTask(counter.Tick) // There could be a lot of routes, so we don't want to be running this every second
//c.AddScheduledSecondTask(counter.Tick)
c.AddShutdownTask(counter.Tick)
return counter, acc.FirstError()
}
@ -78,7 +78,7 @@ func (counter *DefaultForumViewCounter) insertChunk(count int, forum int) error
if count == 0 {
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)
return err
}

View File

@ -1,7 +1,7 @@
package counters
import "database/sql"
import "github.com/Azareal/Gosora/common"
import c "github.com/Azareal/Gosora/common"
import "github.com/Azareal/Gosora/query_gen"
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(),
}
common.AddScheduledFifteenMinuteTask(counter.Tick)
//common.AddScheduledSecondTask(counter.Tick)
common.AddShutdownTask(counter.Tick)
c.AddScheduledFifteenMinuteTask(counter.Tick)
//c.AddScheduledSecondTask(counter.Tick)
c.AddShutdownTask(counter.Tick)
return counter, acc.FirstError()
}
@ -143,7 +143,7 @@ func (counter *DefaultLangViewCounter) insertChunk(count int, id int) error {
return nil
}
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)
return err
}
@ -158,7 +158,7 @@ func (counter *DefaultLangViewCounter) Bump(langCode string) (validCode bool) {
}
// 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 {
return validCode
}

View File

@ -4,7 +4,7 @@ import (
"database/sql"
"sync/atomic"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/query_gen"
)
@ -23,9 +23,9 @@ func NewPostCounter() (*DefaultPostCounter, error) {
currentBucket: 0,
insert: acc.Insert("postchunks").Columns("count, createdAt").Fields("?,UTC_TIMESTAMP()").Prepare(),
}
common.AddScheduledFifteenMinuteTask(counter.Tick)
//common.AddScheduledSecondTask(counter.Tick)
common.AddShutdownTask(counter.Tick)
c.AddScheduledFifteenMinuteTask(counter.Tick)
//c.AddScheduledSecondTask(counter.Tick)
c.AddShutdownTask(counter.Tick)
return counter, acc.FirstError()
}
@ -52,7 +52,7 @@ func (counter *DefaultPostCounter) insertChunk(count int64) error {
if count == 0 {
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)
return err
}

View File

@ -5,7 +5,7 @@ import (
"sync"
"sync/atomic"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/query_gen"
)
@ -28,9 +28,9 @@ func NewDefaultTopicViewCounter() (*DefaultTopicViewCounter, error) {
evenTopics: make(map[int]*RWMutexCounterBucket),
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
//common.AddScheduledSecondTask(counter.Tick)
common.AddShutdownTask(counter.Tick)
c.AddScheduledFifteenMinuteTask(counter.Tick) // Who knows how many topics we have queued up, we probably don't want this running too frequently
//c.AddScheduledSecondTask(counter.Tick)
c.AddShutdownTask(counter.Tick)
return counter, acc.FirstError()
}
@ -82,14 +82,14 @@ func (counter *DefaultTopicViewCounter) insertChunk(count int, topicID int) erro
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)
if err != nil {
return err
}
// TODO: Add a way to disable this for extra speed ;)
tcache := common.Topics.GetCache()
tcache := c.Topics.GetCache()
if tcache != nil {
topic, err := tcache.Get(topicID)
if err != nil {

View File

@ -10,7 +10,7 @@ import (
"strconv"
"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
@ -43,16 +43,16 @@ type Guild struct {
LastUpdateTime string
MainForumID int
MainForum *common.Forum
Forums []*common.Forum
ExtData common.ExtData
MainForum *c.Forum
Forums []*c.Forum
ExtData c.ExtData
}
type Page struct {
Title string
Header *common.Header
ItemList []*common.TopicsRow
Forum *common.Forum
Header *c.Header
ItemList []*c.TopicsRow
Forum *c.Forum
Guild *Guild
Page int
LastPage int
@ -61,13 +61,13 @@ type Page struct {
// ListPage is a page struct for constructing a list of every guild
type ListPage struct {
Title string
Header *common.Header
Header *c.Header
GuildList []*Guild
}
type MemberListPage struct {
Title string
Header *common.Header
Header *c.Header
ItemList []Member
Guild *Guild
Page int
@ -83,15 +83,15 @@ type Member struct {
JoinedAt string
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{
&Guild{
ID: 1,
Name: "lol",
Link: BuildGuildURL(common.NameToSlug("lol"), 1),
Link: BuildGuildURL(c.NameToSlug("lol"), 1),
Desc: "A group for people who like to laugh",
Active: true,
MemberCount: 1,
@ -99,26 +99,26 @@ func PrebuildTmplList(user common.User, header *common.Header) common.CTmpl {
CreatedAt: "date",
LastUpdateTime: "date",
MainForumID: 1,
MainForum: common.Forums.DirtyGet(1),
Forums: []*common.Forum{common.Forums.DirtyGet(1)},
MainForum: c.Forums.DirtyGet(1),
Forums: []*c.Forum{c.Forums.DirtyGet(1)},
},
}
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: REWRITE THIS
func CommonAreaWidgets(header *common.Header) {
func CommonAreaWidgets(header *c.Header) {
// TODO: Hot Groups? Featured Groups? Official Groups?
var b bytes.Buffer
var menu = common.WidgetMenu{"Guilds", []common.WidgetMenuItem{
common.WidgetMenuItem{"Create Guild", "/guild/create/", false},
var menu = c.WidgetMenu{"Guilds", []c.WidgetMenuItem{
c.WidgetMenuItem{"Create Guild", "/guild/create/", false},
}}
err := header.Theme.RunTmpl("widget_menu", pi, w)
if err != nil {
common.LogError(err)
c.LogError(err)
return
}
@ -131,7 +131,7 @@ func CommonAreaWidgets(header *common.Header) {
// TODO: Do this properly via the 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
/*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)
if err != nil {
common.LogError(err)
c.LogError(err)
return false
}
@ -160,16 +160,16 @@ func GuildWidgets(header *common.Header, guildItem *Guild) (success bool) {
Custom Pages
*/
func RouteGuildList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
func RouteGuildList(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
header, ferr := c.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
CommonAreaWidgets(header)
rows, err := ListStmt.Query()
if err != nil && err != common.ErrNoRows {
return common.InternalError(err, w, r)
if err != nil && err != c.ErrNoRows {
return c.InternalError(err, w, r)
}
defer rows.Close()
@ -178,37 +178,37 @@ func RouteGuildList(w http.ResponseWriter, r *http.Request, user common.User) co
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)
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)
}
err = rows.Err()
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
pi := ListPage{"Guild List", user, header, guildList}
err = header.Theme.RunTmpl("guilds_guild_list", pi, w)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
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/"):])
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)
if err != nil {
return common.LocalError("Bad guild", w, r, user)
return c.LocalError("Bad guild", w, r, user)
}
// TODO: Build and pass header
if !guildItem.Active {
return common.NotFound(w, r, nil)
return c.NotFound(w, r, 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))
}
func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
header, ferr := c.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
header.Title = "Create Guild"
// TODO: Add an approval queue mode for group creation
if !user.Loggedin || !user.PluginPerms["CreateGuild"] {
return common.NoPermissions(w, r, user)
return c.NoPermissions(w, r, user)
}
CommonAreaWidgets(header)
pi := common.Page{header, tList, nil}
pi := c.Page{header, tList, nil}
err := header.Theme.RunTmpl("guilds_create_guild", pi, w)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
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
if !user.Loggedin || !user.PluginPerms["CreateGuild"] {
return common.NoPermissions(w, r, user)
return c.NoPermissions(w, r, user)
}
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?
var guildDesc = common.SanitiseBody(r.PostFormValue("group_desc"))
var guildDesc = c.SanitiseBody(r.PostFormValue("group_desc"))
var gprivacy = r.PostFormValue("group_privacy")
var guildPrivacy int
@ -264,53 +264,53 @@ func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user common.
}
// Create the backing forum
fid, err := common.Forums.Create(guildName, "", true, "")
fid, err := c.Forums.Create(guildName, "", true, "")
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)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
// Add the main backing forum to the forum list
err = AttachForum(gid, fid)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
_, err = AddMemberStmt.Exec(gid, user.ID, 2)
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
}
func RouteMemberList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
func RouteMemberList(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
header, ferr := c.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
_, guildID, err := routes.ParseSEOURL(r.URL.Path[len("/guild/members/"):])
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)
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)
rows, err := MemberListJoinStmt.Query(guildID)
if err != nil && err != common.ErrNoRows {
return common.InternalError(err, w, r)
if err != nil && err != c.ErrNoRows {
return c.InternalError(err, w, r)
}
var guildMembers []Member
@ -318,11 +318,11 @@ func RouteMemberList(w http.ResponseWriter, r *http.Request, user common.User) c
guildMember := Member{PostCount: 0}
err := rows.Scan(&guildMember.User.ID, &guildMember.Rank, &guildMember.PostCount, &guildMember.JoinedAt, &guildMember.User.Name, &guildMember.User.RawAvatar)
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.User.Avatar, guildMember.User.MicroAvatar = common.BuildAvatar(guildMember.User.ID, guildMember.User.RawAvatar)
guildMember.JoinedAt, _ = common.RelativeTimeFromString(guildMember.JoinedAt)
guildMember.Link = c.BuildProfileURL(c.NameToSlug(guildMember.User.Name), guildMember.User.ID)
guildMember.User.Avatar, guildMember.User.MicroAvatar = c.BuildAvatar(guildMember.User.ID, guildMember.User.RawAvatar)
guildMember.JoinedAt, _ = c.RelativeTimeFromString(guildMember.JoinedAt)
if guildItem.Owner == guildMember.User.ID {
guildMember.RankString = "Owner"
} else {
@ -339,18 +339,18 @@ func RouteMemberList(w http.ResponseWriter, r *http.Request, user common.User) c
}
err = rows.Err()
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
rows.Close()
pi := MemberListPage{"Guild Member List", user, header, guildMembers, guildItem, 0, 0}
// 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
}
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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
return nil
}
@ -366,7 +366,7 @@ func UnattachForum(fid int) error {
}
func BuildGuildURL(slug string, id int) string {
if slug == "" || !common.Config.BuildSlugs {
if slug == "" || !c.Config.BuildSlugs {
return "/guild/" + strconv.Itoa(id)
}
return "/guild/" + slug + "." + strconv.Itoa(id)
@ -377,8 +377,8 @@ func BuildGuildURL(slug string, id int) string {
*/
// TODO: Prebuild this template
func PreRenderViewForum(w http.ResponseWriter, r *http.Request, user *common.User, data interface{}) (halt bool) {
pi := data.(*common.ForumPage)
func PreRenderViewForum(w http.ResponseWriter, r *http.Request, user *c.User, data interface{}) (halt bool) {
pi := data.(*c.ForumPage)
if pi.Header.ExtData.Items != nil {
if guildData, ok := pi.Header.ExtData.Items["guilds_current_group"]; ok {
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}
err := header.Theme.RunTmpl("guilds_view_guild", guildpi, w)
if err != nil {
common.LogError(err)
c.LogError(err)
return false
}
return true
@ -396,10 +396,10 @@ func PreRenderViewForum(w http.ResponseWriter, r *http.Request, user *common.Use
}
func TrowAssign(args ...interface{}) interface{} {
var forum = args[1].(*common.Forum)
var forum = args[1].(*c.Forum)
if forum.ParentType == "guild" {
var topicItem = args[0].(*common.TopicsRow)
topicItem.ForumLink = "/guild/" + strings.TrimPrefix(topicItem.ForumLink, common.GetForumURLPrefix())
var topicItem = args[0].(*c.TopicsRow)
topicItem.ForumLink = "/guild/" + strings.TrimPrefix(topicItem.ForumLink, c.GetForumURLPrefix())
}
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
func TopicCreatePreLoop(args ...interface{}) interface{} {
var fid = args[2].(int)
if common.Forums.DirtyGet(fid).ParentType == "guild" {
if c.Forums.DirtyGet(fid).ParentType == "guild" {
var strictmode = args[5].(*bool)
*strictmode = true
}
@ -417,10 +417,10 @@ func TopicCreatePreLoop(args ...interface{}) interface{} {
// TODO: Add privacy options
// TODO: Add support for multiple boards and add per-board simplified permissions
// 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 fid = args[3].(*int)
var forum = common.Forums.DirtyGet(*fid)
var forum = c.Forums.DirtyGet(*fid)
if forum.ParentType == "guild" {
var err error
@ -429,15 +429,15 @@ func ForumCheck(args ...interface{}) (skip bool, rerr common.RouteError) {
if !ok {
guildItem, err = Gstore.Get(forum.ParentID)
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 {
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))
}
var user = args[2].(*common.User)
var user = args[2].(*c.User)
var rank int
var posts int
var joinedAt string
@ -446,32 +446,32 @@ func ForumCheck(args ...interface{}) (skip bool, rerr common.RouteError) {
// Clear the default group permissions
// 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
err = GetMemberStmt.QueryRow(guildItem.ID, user.ID).Scan(&rank, &posts, &joinedAt)
if err != nil && err != common.ErrNoRows {
return true, common.InternalError(err, w, r)
if err != nil && err != c.ErrNoRows {
return true, c.InternalError(err, w, r)
} else if err != nil {
// 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: How does this even work? Refactor it along with the rest of this plugin!
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!
if guildItem.Owner == user.ID {
common.OverrideForumPerms(&user.Perms, true)
c.OverrideForumPerms(&user.Perms, true)
} else if rank == 0 {
user.Perms.LikeItem = true
user.Perms.CreateTopic = true
user.Perms.CreateReply = true
} else {
common.OverrideForumPerms(&user.Perms, true)
c.OverrideForumPerms(&user.Perms, true)
}
return true, nil
}
@ -483,19 +483,19 @@ func ForumCheck(args ...interface{}) (skip bool, rerr common.RouteError) {
func Widgets(args ...interface{}) interface{} {
var zone = args[0].(string)
var header = args[2].(*common.Header)
var header = args[2].(*c.Header)
var request = args[3].(*http.Request)
if zone != "view_forum" {
return false
}
var forum = args[1].(*common.Forum)
var forum = args[1].(*c.Forum)
if forum.ParentType == "guild" {
// 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)
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
}

View File

@ -11,7 +11,7 @@ import (
"runtime/debug"
"strconv"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/query_gen"
_ "github.com/go-sql-driver/mysql"
)
@ -38,18 +38,18 @@ func main() {
}()
log.Print("Loading the configuration data")
err := common.LoadConfig()
err := c.LoadConfig()
if err != nil {
log.Fatal(err)
}
log.Print("Processing configuration data")
err = common.ProcessConfig()
err = c.ProcessConfig()
if err != nil {
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")
}
@ -74,11 +74,11 @@ func pressAnyKey(scanner *bufio.Scanner) {
func prepMySQL() error {
return qgen.Builder.Init("mysql", map[string]string{
"host": common.DbConfig.Host,
"port": common.DbConfig.Port,
"name": common.DbConfig.Dbname,
"username": common.DbConfig.Username,
"password": common.DbConfig.Password,
"host": c.DbConfig.Host,
"port": c.DbConfig.Port,
"name": c.DbConfig.Dbname,
"username": c.DbConfig.Username,
"password": c.DbConfig.Password,
"collation": "utf8mb4_general_ci",
})
}

File diff suppressed because it is too large Load Diff

View File

@ -7,12 +7,12 @@ import (
"strconv"
"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: 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?
_, _ = w.Write([]byte(`User-agent: *
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
func SitemapXml(w http.ResponseWriter, r *http.Request) common.RouteError {
func SitemapXml(w http.ResponseWriter, r *http.Request) c.RouteError {
var sslBit string
if common.Site.EnableSsl {
if c.Site.EnableSsl {
sslBit = "s"
}
var sitemapItem = func(path string) {
w.Write([]byte(`<sitemap>
<loc>http` + sslBit + `://` + common.Site.URL + "/" + path + `</loc>
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
</sitemap>
`))
}
@ -55,13 +55,13 @@ func SitemapXml(w http.ResponseWriter, r *http.Request) common.RouteError {
type FuzzyRoute struct {
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: ^-- Make sure that the API is concurrent
// 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,
"topics.xml": SitemapTopics,
}
@ -71,7 +71,7 @@ var fuzzySitemapRoutes = map[string]FuzzyRoute{
"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/"):]
for name, fuzzy := range fuzzySitemapRoutes {
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)
if err != nil {
// ? 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)
return common.NotFound(w, r, nil)
c.DebugLogf("Unable to convert string '%s' to integer in fuzzy route", spath)
return c.NotFound(w, r, nil)
}
return fuzzy.Handle(w, r, page)
}
@ -89,26 +89,26 @@ func sitemapSwitch(w http.ResponseWriter, r *http.Request) common.RouteError {
route, ok := sitemapRoutes[path]
if !ok {
return common.NotFound(w, r, nil)
return c.NotFound(w, r, nil)
}
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
if common.Site.EnableSsl {
if c.Site.EnableSsl {
sslBit = "s"
}
var sitemapItem = func(path string) {
w.Write([]byte(`<url>
<loc>http` + sslBit + `://` + common.Site.URL + path + `</loc>
<loc>http` + sslBit + `://` + c.Site.URL + path + `</loc>
</url>
`))
}
group, err := common.Groups.Get(common.GuestUser.Group)
group, err := c.Groups.Get(c.GuestUser.Group)
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)
@ -116,9 +116,9 @@ func SitemapForums(w http.ResponseWriter, r *http.Request) common.RouteError {
for _, fid := range group.CanSee {
// Avoid data races by copying the struct into something we can freely mold without worrying about breaking something somewhere else
var forum = common.Forums.DirtyGet(fid).Copy()
var forum = c.Forums.DirtyGet(fid).Copy()
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?
// ? 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
if common.Site.EnableSsl {
if c.Site.EnableSsl {
sslBit = "s"
}
var sitemapItem = func(path string) {
w.Write([]byte(`<sitemap>
<loc>http` + sslBit + `://` + common.Site.URL + "/" + path + `</loc>
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
</sitemap>
`))
}
group, err := common.Groups.Get(common.GuestUser.Group)
group, err := c.Groups.Get(c.GuestUser.Group)
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 {
forum := common.Forums.DirtyGet(fid)
forum := c.Forums.DirtyGet(fid)
if forum.Name != "" && forum.Active {
visibleForums = append(visibleForums, forum.Copy())
}
}
topicCount, err := common.TopicCountInForums(visibleForums)
topicCount, err := c.TopicCountInForums(visibleForums)
if err != nil {
return common.InternalErrorXML(err, w, r)
return c.InternalErrorXML(err, w, r)
}
var pageCount = topicCount / sitemapPageCap
@ -170,35 +170,35 @@ func SitemapTopics(w http.ResponseWriter, r *http.Request) common.RouteError {
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
if common.Site.EnableSsl {
if c.Site.EnableSsl {
sslBit = "s"
}
var sitemapItem = func(path string) {
w.Write([]byte(`<url>
<loc>http` + sslBit + `://` + common.Site.URL + "/" + path + `</loc>
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
</url>
`))
}*/
group, err := common.Groups.Get(common.GuestUser.Group)
group, err := c.Groups.Get(c.GuestUser.Group)
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 {
forum := common.Forums.DirtyGet(fid)
forum := c.Forums.DirtyGet(fid)
if forum.Name != "" && forum.Active {
visibleForums = append(visibleForums, forum.Copy())
}
}
argList, qlist := common.ForumListToArgQ(visibleForums)
topicCount, err := common.ArgQToTopicCount(argList, qlist)
argList, qlist := c.ForumListToArgQ(visibleForums)
topicCount, err := c.ArgQToTopicCount(argList, qlist)
if err != nil {
return common.InternalErrorXML(err, w, r)
return c.InternalErrorXML(err, w, r)
}
var pageCount = topicCount / sitemapPageCap
@ -216,18 +216,18 @@ func SitemapTopic(w http.ResponseWriter, r *http.Request, page int) common.Route
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)
w.Write([]byte("<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n"))
return nil
}
type JsonMe struct {
User *common.MeUser
User *c.MeUser
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 {
MaxRequestSize int
}
@ -235,18 +235,18 @@ type MeSite struct {
// 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: 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
w.Header().Set("Content-Type", "application/json")
// We don't want an intermediary accidentally caching this
// TODO: Use this header anywhere with a user check?
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)
if err != nil {
return common.InternalErrorJS(err, w, r)
return c.InternalErrorJS(err, w, r)
}
w.Write(jsonBytes)

View File

@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/query_gen"
)
@ -20,7 +20,7 @@ var attachmentStmts AttachmentStmts
// TODO: Abstract this with an attachment store
func init() {
common.DbInits.Add(func(acc *qgen.Accumulator) error {
c.DbInits.Add(func(acc *qgen.Accumulator) error {
attachmentStmts = AttachmentStmts{
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 {
filename = common.Stripslashes(filename)
func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filename string) c.RouteError {
filename = c.Stripslashes(filename)
var ext = filepath.Ext("./attachs/" + filename)
if !common.AllowedFileExts.Contains(strings.TrimPrefix(ext, ".")) {
return common.LocalError("Bad extension", w, r, user)
if !c.AllowedFileExts.Contains(strings.TrimPrefix(ext, ".")) {
return c.LocalError("Bad extension", w, r, user)
}
sectionID, err := strconv.Atoi(r.FormValue("sectionID"))
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")
@ -45,37 +45,37 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user common.User, fi
var originID, uploadedBy int
err = attachmentStmts.get.QueryRow(filename, sectionID, sectionTable).Scan(&sectionID, &sectionTable, &originID, &originTable, &uploadedBy, &filename)
if err == sql.ErrNoRows {
return common.NotFound(w, r, nil)
return c.NotFound(w, r, nil)
} else if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
if sectionTable == "forums" {
_, ferr := common.SimpleForumUserCheck(w, r, &user, sectionID)
_, ferr := c.SimpleForumUserCheck(w, r, &user, sectionID)
if ferr != nil {
return ferr
}
if !user.Perms.ViewTopic {
return common.NoPermissions(w, r, user)
return c.NoPermissions(w, r, user)
}
} else {
return common.LocalError("Unknown section", w, r, user)
return c.LocalError("Unknown section", w, r, user)
}
if originTable != "topics" && originTable != "replies" {
return common.LocalError("Unknown origin", w, r, user)
return c.LocalError("Unknown origin", w, r, user)
}
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 {
guest := common.GuestUser
_, ferr := common.SimpleForumUserCheck(w, r, &guest, sectionID)
guest := c.GuestUser
_, ferr := c.SimpleForumUserCheck(w, r, &guest, sectionID)
if ferr != nil {
return ferr
}
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 {
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
func deleteAttachment(w http.ResponseWriter, r *http.Request, user common.User, aid int, js bool) common.RouteError {
attach, err := common.Attachments.Get(aid)
func deleteAttachment(w http.ResponseWriter, r *http.Request, user c.User, aid int, js bool) c.RouteError {
attach, err := c.Attachments.Get(aid)
if err == sql.ErrNoRows {
return common.NotFoundJSQ(w, r, nil, js)
return c.NotFoundJSQ(w, r, nil, js)
} 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 {
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 {
return common.InternalErrorJSQ(err, w, r, js)
return c.InternalErrorJSQ(err, w, r, js)
}
if count == 0 {
err := os.Remove("./attachs/" + attach.Path)
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: Use a transaction here
// 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)
files, rerr := uploadFilesWithHash(w, r, user, "./attachs/")
if rerr != nil {
@ -125,9 +125,9 @@ func uploadAttachment(w http.ResponseWriter, r *http.Request, user common.User,
}
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 {
return nil, common.InternalError(err, w, r)
return nil, c.InternalError(err, w, r)
}
_, ok := pathMap[filename]
@ -139,18 +139,18 @@ func uploadAttachment(w http.ResponseWriter, r *http.Request, user common.User,
switch originTable {
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 {
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 {
return nil, common.InternalError(err, w, r)
return nil, c.InternalError(err, w, r)
}
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 {
return nil, common.InternalError(err, w, r)
return nil, c.InternalError(err, w, r)
}
}
}

View File

@ -7,7 +7,7 @@ import (
"strings"
"time"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
)
var successJSONBytes = []byte(`{"success":"1"}`)
@ -21,9 +21,9 @@ func ParseSEOURL(urlBit string) (slug string, id int, err error) {
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")
if common.Config.EnableCDNPush {
if c.Config.EnableCDNPush {
// TODO: Faster string building...
var sbuf string
var push = func(in []string) {
@ -46,9 +46,9 @@ func doPush(w http.ResponseWriter, header *common.Header) {
sbuf = sbuf[:len(sbuf)-1]
w.Header().Set("Link", sbuf)
}
} else if !common.Config.DisableServerPush {
} else if !c.Config.DisableServerPush {
//fmt.Println("push enabled")
gzw, ok := w.(common.GzipResponseWriter)
gzw, ok := w.(c.GzipResponseWriter)
if ok {
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 {
header.MetaDesc = ""
header.OGDesc = ""
@ -83,7 +83,7 @@ func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, hea
header.OGDesc = header.MetaDesc
}
// 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")
}
header.AddScript("global.js")
@ -98,12 +98,12 @@ func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, hea
if header.CurrentUser.IsAdmin {
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
}
err := header.Theme.RunTmpl(tmplName, pi, w)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
return nil
}

View File

@ -5,7 +5,7 @@ import (
"net/http"
"strconv"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen"
@ -19,7 +19,7 @@ var forumStmts ForumStmts
// TODO: Move these DbInits into *Forum as Topics()
func init() {
common.DbInits.Add(func(acc *qgen.Accumulator) error {
c.DbInits.Add(func(acc *qgen.Accumulator) error {
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(),
}
@ -28,55 +28,55 @@ func init() {
}
// 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"))
_, fid, err := ParseSEOURL(sfid)
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 {
return ferr
}
if !user.Perms.ViewTopic {
return common.NoPermissions(w, r, user)
return c.NoPermissions(w, r, user)
}
header.Path = "/forums/"
// TODO: Fix this double-check
forum, err := common.Forums.Get(fid)
forum, err := c.Forums.Get(fid)
if err == sql.ErrNoRows {
return common.NotFound(w, r, header)
return c.NotFound(w, r, header)
} else if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
header.Title = forum.Name
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
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
rows, err := forumStmts.getTopics.Query(fid, offset, common.Config.ItemsPerPage)
rows, err := forumStmts.getTopics.Query(fid, offset, c.Config.ItemsPerPage)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
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?
var topicList []*common.TopicsRow
var topicList []*c.TopicsRow
var reqUserList = make(map[int]bool)
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)
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
_, _, lastPage := common.PageOffset(topicItem.PostCount, 1, common.Config.ItemsPerPage)
_, _, lastPage := c.PageOffset(topicItem.PostCount, 1, c.Config.ItemsPerPage)
topicItem.LastPage = lastPage
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()
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
@ -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?
userList, err := common.Users.BulkGetMap(idSlice)
userList, err := c.Users.BulkGetMap(idSlice)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
// 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" {
outBytes, err := wsTopicList(topicList, lastPage).MarshalJSON()
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
w.Write(outBytes)
return nil
}
pageList := common.Paginate(forum.TopicCount, common.Config.ItemsPerPage, 5)
pi := common.ForumPage{header, topicList, forum, common.Paginator{pageList, page, lastPage}}
pageList := c.Paginate(forum.TopicCount, c.Config.ItemsPerPage, 5)
pi := c.ForumPage{header, topicList, forum, c.Paginator{pageList, page, lastPage}}
ferr = renderTemplate("forum", w, r, header, pi)
counters.ForumViewCounter.Bump(forum.ID)
return ferr

View File

@ -4,40 +4,40 @@ import (
"log"
"net/http"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"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.Zone = "forums"
header.Path = "/forums/"
header.MetaDesc = header.Settings["meta_desc"].(string)
var err error
var forumList []common.Forum
var forumList []c.Forum
var canSee []int
if user.IsSuperAdmin {
canSee, err = common.Forums.GetAllVisibleIDs()
canSee, err = c.Forums.GetAllVisibleIDs()
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
} else {
group, err := common.Groups.Get(user.Group)
group, err := c.Groups.Get(user.Group)
if err != nil {
log.Printf("Group #%d doesn't exist despite being used by common.User #%d", user.Group, user.ID)
return common.LocalError("Something weird happened", w, r, user)
log.Printf("Group #%d doesn't exist despite being used by c.User #%d", user.Group, user.ID)
return c.LocalError("Something weird happened", w, r, user)
}
canSee = group.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
var forum = common.Forums.DirtyGet(fid).Copy()
var forum = c.Forums.DirtyGet(fid).Copy()
if forum.ParentID == 0 && forum.Name != "" && forum.Active {
if forum.LastTopicID != 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 {
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)
}

View File

@ -9,17 +9,17 @@ import (
"strings"
"time"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"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
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 {
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)
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()
}
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.Zone = "overview"
pi := common.Page{header, tList, nil}
pi := c.Page{header, tList, nil}
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"
name = common.SanitiseSingleLine(name)
page, err := common.Pages.GetByName(name)
name = c.SanitiseSingleLine(name)
page, err := c.Pages.GetByName(name)
if err == nil {
header.Title = page.Title
pi := common.CustomPagePage{header, page}
pi := c.CustomPagePage{header, page}
return renderTemplate("custom_page", w, r, header, pi)
} else if err != sql.ErrNoRows {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
// ! Is this safe?
if common.DefaultTemplates.Lookup("page_"+name+".html") == nil {
return common.NotFound(w, r, header)
if c.DefaultTemplates.Lookup("page_"+name+".html") == nil {
return c.NotFound(w, r, header)
}
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?
if common.RunPreRenderHook("pre_render_tmpl_page", w, r, &user, &pi) {
if c.RunPreRenderHook("pre_render_tmpl_page", w, r, &user, &pi) {
return nil
}
err = header.Theme.RunTmpl("page_"+name, pi, w)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
return nil
}
// 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)
// TODO: Rename isJs to something else, just in case we rewrite the JS side in WebAssembly?
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 {
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)
if !isJs {

View File

@ -3,37 +3,37 @@ package routes
import (
"net/http"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"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")
// TODO: How should we handle the permissions if we extend this into an alt detector of sorts?
if !user.Perms.ViewIPs {
return common.NoPermissions(w, r, user)
return c.NoPermissions(w, r, user)
}
// TODO: Reject IP Addresses with illegal characters
var ip = common.SanitiseSingleLine(r.FormValue("ip"))
uids, err := common.IPSearch.Lookup(ip)
var ip = c.SanitiseSingleLine(r.FormValue("ip"))
uids, err := c.IPSearch.Lookup(ip)
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
userList, err := common.Users.BulkGetMap(uids)
userList, err := c.Users.BulkGetMap(uids)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
pi := common.IPSearchPage{header, userList, ip}
if common.RunPreRenderHook("pre_render_ip_search", w, r, &user, &pi) {
pi := c.IPSearchPage{header, userList, ip}
if c.RunPreRenderHook("pre_render_ip_search", w, r, &user, &pi) {
return nil
}
err = header.Theme.RunTmpl("ip_search", pi, w)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
return nil
}

View File

@ -8,7 +8,7 @@ import (
"strconv"
"time"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen"
)
@ -103,7 +103,7 @@ func analyticsRowsToViewMap(rows *sql.Rows, labelList []int64, viewMap map[int64
}
var unixCreatedAt = createdAt.Unix()
// TODO: Bulk log this
if common.Dev.SuperDebug {
if c.Dev.SuperDebug {
log.Print("count: ", count)
log.Print("createdAt: ", createdAt)
log.Print("unixCreatedAt: ", unixCreatedAt)
@ -118,7 +118,7 @@ func analyticsRowsToViewMap(rows *sql.Rows, labelList []int64, viewMap map[int64
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")
if ferr != nil {
return nil, ferr
@ -129,336 +129,336 @@ func PreAnalyticsDetail(w http.ResponseWriter, r *http.Request, user *common.Use
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)
if ferr != nil {
return ferr
}
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
common.DebugLog("in panel.AnalyticsViews")
c.DebugLog("in panel.AnalyticsViews")
// 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()
if err != nil && err != sql.ErrNoRows {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var viewList []int64
var viewItems []common.PanelAnalyticsItem
var viewItems []c.PanelAnalyticsItem
for _, value := range revLabelList {
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}
common.DebugLogf("graph: %+v\n", graph)
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
c.DebugLogf("graph: %+v\n", graph)
var ttime string
if timeRange.Range == "six-hours" || timeRange.Range == "twelve-hours" || timeRange.Range == "one-day" {
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)
}
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)
if ferr != nil {
return ferr
}
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
common.DebugLog("in panel.AnalyticsRouteViews")
c.DebugLog("in panel.AnalyticsRouteViews")
// 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)
if err != nil && err != sql.ErrNoRows {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var viewList []int64
var viewItems []common.PanelAnalyticsItem
var viewItems []c.PanelAnalyticsItem
for _, value := range revLabelList {
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}
common.DebugLogf("graph: %+v\n", graph)
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
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)
}
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)
if ferr != nil {
return ferr
}
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
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
agent = common.SanitiseSingleLine(agent)
agent = c.SanitiseSingleLine(agent)
common.DebugLog("in panel.AnalyticsAgentViews")
c.DebugLog("in panel.AnalyticsAgentViews")
// 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)
if err != nil && err != sql.ErrNoRows {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var viewList []int64
for _, value := range revLabelList {
viewList = append(viewList, viewMap[value])
}
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
common.DebugLogf("graph: %+v\n", graph)
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
c.DebugLogf("graph: %+v\n", graph)
friendlyAgent, ok := phrases.GetUserAgentPhrase(agent)
if !ok {
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)
}
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)
if ferr != nil {
return ferr
}
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
fid, err := strconv.Atoi(sfid)
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
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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var viewList []int64
for _, value := range revLabelList {
viewList = append(viewList, viewMap[value])
}
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
common.DebugLogf("graph: %+v\n", graph)
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
c.DebugLogf("graph: %+v\n", graph)
forum, err := common.Forums.Get(fid)
forum, err := c.Forums.Get(fid)
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)
}
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)
if ferr != nil {
return ferr
}
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
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
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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var viewList []int64
for _, value := range revLabelList {
viewList = append(viewList, viewMap[value])
}
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
common.DebugLogf("graph: %+v\n", graph)
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
c.DebugLogf("graph: %+v\n", graph)
friendlySystem, ok := phrases.GetOSPhrase(system)
if !ok {
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)
}
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)
if ferr != nil {
return ferr
}
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
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
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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var viewList []int64
for _, value := range revLabelList {
viewList = append(viewList, viewMap[value])
}
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
common.DebugLogf("graph: %+v\n", graph)
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
c.DebugLogf("graph: %+v\n", graph)
friendlyLang, ok := phrases.GetHumanLangPhrase(lang)
if !ok {
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)
}
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)
if ferr != nil {
return ferr
}
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
common.DebugLog("in panel.AnalyticsReferrerViews")
c.DebugLog("in panel.AnalyticsReferrerViews")
// 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)
if err != nil && err != sql.ErrNoRows {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var viewList []int64
for _, value := range revLabelList {
viewList = append(viewList, viewMap[value])
}
graph := common.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
common.DebugLogf("graph: %+v\n", graph)
pi := common.PanelAnalyticsAgentPage{basePage, common.SanitiseSingleLine(domain), "", graph, timeRange.Range}
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
c.DebugLogf("graph: %+v\n", graph)
pi := c.PanelAnalyticsAgentPage{basePage, c.SanitiseSingleLine(domain), "", graph, timeRange.Range}
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)
if ferr != nil {
return ferr
}
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
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()
if err != nil && err != sql.ErrNoRows {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var viewList []int64
var viewItems []common.PanelAnalyticsItem
var viewItems []c.PanelAnalyticsItem
for _, value := range revLabelList {
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}
common.DebugLogf("graph: %+v\n", graph)
pi := common.PanelAnalyticsPage{basePage, graph, viewItems, timeRange.Range, timeRange.Unit, "time"}
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
c.DebugLogf("graph: %+v\n", graph)
pi := c.PanelAnalyticsPage{basePage, graph, viewItems, timeRange.Range, timeRange.Unit, "time"}
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)
if ferr != nil {
return ferr
}
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
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()
if err != nil && err != sql.ErrNoRows {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
viewMap, err = analyticsRowsToViewMap(rows, labelList, viewMap)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var viewList []int64
var viewItems []common.PanelAnalyticsItem
var viewItems []c.PanelAnalyticsItem
for _, value := range revLabelList {
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}
common.DebugLogf("graph: %+v\n", graph)
pi := common.PanelAnalyticsPage{basePage, graph, viewItems, timeRange.Range, timeRange.Unit, "time"}
graph := c.PanelTimeGraph{Series: [][]int64{viewList}, Labels: labelList}
c.DebugLogf("graph: %+v\n", graph)
pi := c.PanelAnalyticsPage{basePage, graph, viewItems, timeRange.Range, timeRange.Unit, "time"}
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
}
// TODO: Bulk log this
if common.Dev.SuperDebug {
if c.Dev.SuperDebug {
log.Print("count: ", count)
log.Print("name: ", name)
}
@ -497,7 +497,7 @@ func analyticsRowsToDuoMap(rows *sql.Rows, labelList []int64, viewMap map[int64]
// TODO: Bulk log this
var unixCreatedAt = createdAt.Unix()
if common.Dev.SuperDebug {
if c.Dev.SuperDebug {
log.Print("count: ", count)
log.Print("name: ", name)
log.Print("createdAt: ", createdAt)
@ -557,7 +557,7 @@ func analyticsVMapToOVList(vMap map[string]map[int64]int64) (ovList []OVItem) {
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)
if ferr != nil {
return ferr
@ -567,17 +567,17 @@ func AnalyticsForums(w http.ResponseWriter, r *http.Request, user common.User) c
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
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()
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)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
ovList := analyticsVMapToOVList(vMap)
@ -592,15 +592,15 @@ func AnalyticsForums(w http.ResponseWriter, r *http.Request, user common.User) c
vList = append(vList, viewList)
fid, err := strconv.Atoi(ovitem.name)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var lName string
forum, err := common.Forums.Get(fid)
forum, err := c.Forums.Get(fid)
if err == sql.ErrNoRows {
// TODO: Localise this
lName = "Deleted Forum"
} else if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
} else {
lName = forum.Name
}
@ -610,38 +610,38 @@ func AnalyticsForums(w http.ResponseWriter, r *http.Request, user common.User) c
}
i++
}
graph := common.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
common.DebugLogf("graph: %+v\n", graph)
graph := c.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
c.DebugLogf("graph: %+v\n", graph)
// TODO: Sort this slice
var forumItems []common.PanelAnalyticsAgentsItem
var forumItems []c.PanelAnalyticsAgentsItem
for sfid, count := range forumMap {
fid, err := strconv.Atoi(sfid)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var lName string
forum, err := common.Forums.Get(fid)
forum, err := c.Forums.Get(fid)
if err == sql.ErrNoRows {
// TODO: Localise this
lName = "Deleted Forum"
} else if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
} else {
lName = forum.Name
}
forumItems = append(forumItems, common.PanelAnalyticsAgentsItem{
forumItems = append(forumItems, c.PanelAnalyticsAgentsItem{
Agent: sfid,
FriendlyAgent: lName,
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)
}
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)
if ferr != nil {
return ferr
@ -651,17 +651,17 @@ func AnalyticsRoutes(w http.ResponseWriter, r *http.Request, user common.User) c
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
vMap, routeMap, err := analyticsRowsToDuoMap(rows, labelList, viewMap)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
ovList := analyticsVMapToOVList(vMap)
@ -680,24 +680,24 @@ func AnalyticsRoutes(w http.ResponseWriter, r *http.Request, user common.User) c
}
i++
}
graph := common.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
common.DebugLogf("graph: %+v\n", graph)
graph := c.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
c.DebugLogf("graph: %+v\n", graph)
// TODO: Sort this slice
var routeItems []common.PanelAnalyticsRoutesItem
var routeItems []c.PanelAnalyticsRoutesItem
for route, count := range routeMap {
routeItems = append(routeItems, common.PanelAnalyticsRoutesItem{
routeItems = append(routeItems, c.PanelAnalyticsRoutesItem{
Route: route,
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)
}
// 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)
if ferr != nil {
return ferr
@ -707,17 +707,17 @@ func AnalyticsAgents(w http.ResponseWriter, r *http.Request, user common.User) c
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
rows, err := qgen.NewAcc().Select("viewchunks_agents").Columns("count, browser, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
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)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
ovList := analyticsVMapToOVList(vMap)
@ -740,28 +740,28 @@ func AnalyticsAgents(w http.ResponseWriter, r *http.Request, user common.User) c
}
i++
}
graph := common.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
common.DebugLogf("graph: %+v\n", graph)
graph := c.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
c.DebugLogf("graph: %+v\n", graph)
// TODO: Sort this slice
var agentItems []common.PanelAnalyticsAgentsItem
var agentItems []c.PanelAnalyticsAgentsItem
for agent, count := range agentMap {
aAgent, ok := phrases.GetUserAgentPhrase(agent)
if !ok {
aAgent = agent
}
agentItems = append(agentItems, common.PanelAnalyticsAgentsItem{
agentItems = append(agentItems, c.PanelAnalyticsAgentsItem{
Agent: agent,
FriendlyAgent: aAgent,
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)
}
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)
if ferr != nil {
return ferr
@ -771,17 +771,17 @@ func AnalyticsSystems(w http.ResponseWriter, r *http.Request, user common.User)
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
rows, err := qgen.NewAcc().Select("viewchunks_systems").Columns("count, system, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
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)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
ovList := analyticsVMapToOVList(vMap)
@ -804,28 +804,28 @@ func AnalyticsSystems(w http.ResponseWriter, r *http.Request, user common.User)
}
i++
}
graph := common.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
common.DebugLogf("graph: %+v\n", graph)
graph := c.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
c.DebugLogf("graph: %+v\n", graph)
// TODO: Sort this slice
var systemItems []common.PanelAnalyticsAgentsItem
var systemItems []c.PanelAnalyticsAgentsItem
for system, count := range osMap {
sSystem, ok := phrases.GetOSPhrase(system)
if !ok {
sSystem = system
}
systemItems = append(systemItems, common.PanelAnalyticsAgentsItem{
systemItems = append(systemItems, c.PanelAnalyticsAgentsItem{
Agent: system,
FriendlyAgent: sSystem,
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)
}
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)
if ferr != nil {
return ferr
@ -835,17 +835,17 @@ func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user common.User
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
return c.LocalError(err.Error(), w, r, user)
}
revLabelList, labelList, viewMap := analyticsTimeRangeToLabelList(timeRange)
rows, err := qgen.NewAcc().Select("viewchunks_langs").Columns("count, lang, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
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)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
ovList := analyticsVMapToOVList(vMap)
@ -868,56 +868,56 @@ func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user common.User
}
i++
}
graph := common.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
common.DebugLogf("graph: %+v\n", graph)
graph := c.PanelTimeGraph{Series: vList, Labels: labelList, Legends: legendList}
c.DebugLogf("graph: %+v\n", graph)
// TODO: Can we de-duplicate these analytics functions further?
// TODO: Sort this slice
var langItems []common.PanelAnalyticsAgentsItem
var langItems []c.PanelAnalyticsAgentsItem
for lang, count := range langMap {
lLang, ok := phrases.GetHumanLangPhrase(lang)
if !ok {
lLang = lang
}
langItems = append(langItems, common.PanelAnalyticsAgentsItem{
langItems = append(langItems, c.PanelAnalyticsAgentsItem{
Agent: lang,
FriendlyAgent: lLang,
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)
}
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")
if ferr != nil {
return ferr
}
timeRange, err := analyticsTimeRange(r.FormValue("timeRange"))
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()
if err != nil && err != sql.ErrNoRows {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
refMap, err := analyticsRowsToNameMap(rows)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
// TODO: Sort this slice
var refItems []common.PanelAnalyticsAgentsItem
var refItems []c.PanelAnalyticsAgentsItem
for domain, count := range refMap {
refItems = append(refItems, common.PanelAnalyticsAgentsItem{
Agent: common.SanitiseSingleLine(domain),
refItems = append(refItems, c.PanelAnalyticsAgentsItem{
Agent: c.SanitiseSingleLine(domain),
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)
}

View File

@ -7,10 +7,10 @@ import (
"path/filepath"
"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")
if ferr != nil {
return ferr
@ -18,15 +18,15 @@ func Backups(w http.ResponseWriter, r *http.Request, user common.User, 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
backupURL = common.Stripslashes(backupURL)
backupURL = c.Stripslashes(backupURL)
var ext = filepath.Ext("./backups/" + backupURL)
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)
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))
@ -44,19 +44,19 @@ func Backups(w http.ResponseWriter, r *http.Request, user common.User, backupURL
return nil
}
var backupList []common.BackupItem
var backupList []c.BackupItem
backupFiles, err := ioutil.ReadDir("./backups")
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
for _, backupFile := range backupFiles {
var ext = filepath.Ext(backupFile.Name())
if ext != ".sql" {
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)
}

View File

@ -3,7 +3,7 @@ package panel
import (
"net/http"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/phrases"
)
@ -12,7 +12,7 @@ var tList []interface{}
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
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 {
http.Redirect(w, r, dest, http.StatusSeeOther)
} else {
@ -21,25 +21,25 @@ func successRedirect(dest string, w http.ResponseWriter, r *http.Request, isJs b
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")
if common.RunPreRenderHook("pre_render_"+tmplName, w, r, &header.CurrentUser, pi) {
if c.RunPreRenderHook("pre_render_"+tmplName, w, r, &header.CurrentUser, pi) {
return nil
}
// TODO: Prepend this with panel_?
err := header.Theme.RunTmpl(tmplName, pi, w)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
return nil
}
func buildBasePage(w http.ResponseWriter, r *http.Request, user *common.User, titlePhrase string, zone string) (*common.BasePanelPage, common.RouteError) {
header, stats, ferr := common.PanelUserCheck(w, r, user)
func buildBasePage(w http.ResponseWriter, r *http.Request, user *c.User, titlePhrase string, zone string) (*c.BasePanelPage, c.RouteError) {
header, stats, ferr := c.PanelUserCheck(w, r, user)
if ferr != nil {
return nil, ferr
}
header.Title = phrases.GetTitlePhrase("panel_" + titlePhrase)
return &common.BasePanelPage{header, stats, zone, common.ReportForumID}, nil
return &c.BasePanelPage{header, stats, zone, c.ReportForumID}, nil
}

View File

@ -6,11 +6,11 @@ import (
"strconv"
"time"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"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")
if ferr != nil {
return ferr
@ -19,7 +19,7 @@ func Debug(w http.ResponseWriter, r *http.Request, user common.User) common.Rout
goVersion := runtime.Version()
dbVersion := qgen.Builder.DbVersion()
var uptime string
upDuration := time.Since(common.StartTime)
upDuration := time.Since(c.StartTime)
hours := int(upDuration.Hours())
minutes := int(upDuration.Minutes())
if hours > 24 {
@ -41,6 +41,6 @@ func Debug(w http.ResponseWriter, r *http.Request, user common.User) common.Rout
var memStats runtime.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)
}

View File

@ -8,21 +8,21 @@ import (
"strconv"
"strings"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"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")
if ferr != nil {
return ferr
}
if !user.Perms.ManageThemes {
return common.NoPermissions(w, r, user)
return c.NoPermissions(w, r, user)
}
var pThemeList, vThemeList []*common.Theme
for _, theme := range common.Themes {
var pThemeList, vThemeList []*c.Theme
for _, theme := range c.Themes {
if theme.HideFromThemes {
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)
}
func ThemesSetDefault(w http.ResponseWriter, r *http.Request, user common.User, uname string) common.RouteError {
_, ferr := common.SimplePanelUserCheck(w, r, &user)
func ThemesSetDefault(w http.ResponseWriter, r *http.Request, user c.User, uname string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user)
if ferr != nil {
return ferr
}
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 {
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 {
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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
http.Redirect(w, r, "/panel/themes/", http.StatusSeeOther)
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")
if ferr != nil {
return ferr
}
if !user.Perms.ManageThemes {
return common.NoPermissions(w, r, user)
return c.NoPermissions(w, r, user)
}
var menuList []common.PanelMenuListItem
for mid, list := range common.Menus.GetAllMap() {
var menuList []c.PanelMenuListItem
for mid, list := range c.Menus.GetAllMap() {
var name = ""
if mid == 1 {
name = phrases.GetTmplPhrase("panel_themes_menus_main")
}
menuList = append(menuList, common.PanelMenuListItem{
menuList = append(menuList, c.PanelMenuListItem{
Name: name,
ID: mid,
ItemCount: len(list.List),
})
}
pi := common.PanelMenuListPage{basePage, menuList}
pi := c.PanelMenuListPage{basePage, menuList}
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?
basePage, ferr := buildBasePage(w, r, &user, "themes_menus_edit", "themes")
if ferr != nil {
return ferr
}
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")
mid, err := strconv.Atoi(smid)
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 {
return common.NotFound(w, r, basePage.Header)
return c.NotFound(w, r, basePage.Header)
} 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 {
var menuTmpls = map[string]common.MenuTmpl{
var menuTmpls = map[string]c.MenuTmpl{
item.TmplName: menuHold.Parse(item.Name, []byte("{{.Name}}")),
}
var renderBuffer [][]byte
@ -132,39 +132,39 @@ func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user common.User, s
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)
}
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?
basePage, ferr := buildBasePage(w, r, &user, "themes_menus_edit", "themes")
if ferr != nil {
return ferr
}
if !user.Perms.ManageThemes {
return common.NoPermissions(w, r, user)
return c.NoPermissions(w, r, user)
}
itemID, err := strconv.Atoi(sitemID)
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 {
return common.NotFound(w, r, basePage.Header)
return c.NotFound(w, r, basePage.Header)
} 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)
}
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 {
return common.SanitiseSingleLine(r.PostFormValue("item-" + name))
return c.SanitiseSingleLine(r.PostFormValue("item-" + name))
}
menuItem.Name = getItem("name")
menuItem.HTMLID = getItem("htmlid")
@ -208,113 +208,113 @@ func themesMenuItemSetters(r *http.Request, menuItem common.MenuItem) common.Men
return menuItem
}
func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, sitemID string) common.RouteError {
_, ferr := common.SimplePanelUserCheck(w, r, &user)
func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user)
if ferr != nil {
return ferr
}
isJs := (r.PostFormValue("js") == "1")
if !user.Perms.ManageThemes {
return common.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, isJs)
}
itemID, err := strconv.Atoi(sitemID)
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 {
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 {
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 = themesMenuItemSetters(r, menuItem)
err = menuItem.Commit()
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)
}
func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
_, ferr := common.SimplePanelUserCheck(w, r, &user)
func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user)
if ferr != nil {
return ferr
}
isJs := (r.PostFormValue("js") == "1")
if !user.Perms.ManageThemes {
return common.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, isJs)
}
smenuID := r.PostFormValue("mid")
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)
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)
itemID, err := menuItem.Create()
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)
}
func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, user common.User, sitemID string) common.RouteError {
_, ferr := common.SimplePanelUserCheck(w, r, &user)
func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user)
if ferr != nil {
return ferr
}
isJs := (r.PostFormValue("js") == "1")
if !user.Perms.ManageThemes {
return common.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, isJs)
}
itemID, err := strconv.Atoi(sitemID)
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 {
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 {
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
err = menuItem.Delete()
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)
}
func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user common.User, smid string) common.RouteError {
_, ferr := common.SimplePanelUserCheck(w, r, &user)
func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user c.User, smid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user)
if ferr != nil {
return ferr
}
isJs := (r.PostFormValue("js") == "1")
if !user.Perms.ManageThemes {
return common.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, isJs)
}
mid, err := strconv.Atoi(smid)
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 {
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 {
return common.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, isJs)
}
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, ",") {
miid, err := strconv.Atoi(smiid)
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
}
@ -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)
}
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")
if ferr != nil {
return ferr
}
if !user.Perms.ManageThemes {
return common.NoPermissions(w, r, user)
return c.NoPermissions(w, r, user)
}
basePage.Header.AddScript("widgets.js")
var docks = make(map[string][]common.WidgetEdit)
for _, name := range common.GetDockList() {
var docks = make(map[string][]c.WidgetEdit)
for _, name := range c.GetDockList() {
if name == "leftOfNav" || name == "rightOfNav" {
continue
}
var widgets []common.WidgetEdit
for _, widget := range common.GetDock(name) {
var widgets []c.WidgetEdit
for _, widget := range c.GetDock(name) {
var data = make(map[string]string)
err := json.Unmarshal([]byte(widget.RawBody), &data)
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
}
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)
}
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)
widget.Enabled = (r.FormValue("wenabled") == "1")
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.")
}
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.")
}
@ -394,95 +394,95 @@ func widgetsParseInputs(r *http.Request, widget *common.Widget) (*common.WidgetE
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
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")
_, ferr := common.SimplePanelUserCheck(w, r, &user)
_, ferr := c.SimplePanelUserCheck(w, r, &user)
if ferr != nil {
return ferr
}
isJs := (r.PostFormValue("js") == "1")
if !user.Perms.ManageThemes {
return common.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, isJs)
}
wid, err := strconv.Atoi(swid)
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 {
return common.NotFoundJSQ(w, r, nil, isJs)
return c.NotFoundJSQ(w, r, nil, isJs)
} else if err != nil {
return common.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, isJs)
}
ewidget, err := widgetsParseInputs(r, widget.Copy())
if err != nil {
return common.LocalErrorJSQ(err.Error(), w, r, user, isJs)
return c.LocalErrorJSQ(err.Error(), w, r, user, isJs)
}
err = ewidget.Commit()
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)
}
// 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")
isJs := (r.PostFormValue("js") == "1")
_, ferr := common.SimplePanelUserCheck(w, r, &user)
_, ferr := c.SimplePanelUserCheck(w, r, &user)
if ferr != nil {
return ferr
}
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 {
return common.LocalErrorJSQ(err.Error(), w, r, user, isJs)
return c.LocalErrorJSQ(err.Error(), w, r, user, isJs)
}
err = ewidget.Create()
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)
}
func ThemesWidgetsDeleteSubmit(w http.ResponseWriter, r *http.Request, user common.User, swid string) common.RouteError {
_, ferr := common.SimplePanelUserCheck(w, r, &user)
func ThemesWidgetsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, swid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user)
if ferr != nil {
return ferr
}
isJs := (r.PostFormValue("js") == "1")
if !user.Perms.ManageThemes {
return common.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, isJs)
}
wid, err := strconv.Atoi(swid)
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 {
return common.NotFound(w, r, nil)
return c.NotFound(w, r, nil)
} else if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
err = widget.Delete()
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
return successRedirect("/panel/themes/widgets/", w, r, isJs)

View File

@ -6,85 +6,85 @@ import (
"net/http"
"strconv"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"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)
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 {
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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var topic *common.Topic
var topic *c.Topic
if poll.ParentTable == "replies" {
reply, err := common.Rstore.Get(poll.ParentID)
reply, err := c.Rstore.Get(poll.ParentID)
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 {
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" {
topic, err = common.Topics.Get(poll.ParentID)
topic, err = c.Topics.Get(poll.ParentID)
} 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 {
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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
// 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 {
return ferr
}
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"))
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)
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)
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")
pollID, err := strconv.Atoi(sPollID)
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 {
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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
// TODO: Abstract this
rows, err := qgen.NewAcc().Select("polls_options").Columns("votes").Where("pollID = ?").Orderby("option ASC").Query(poll.ID)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
defer rows.Close()
@ -93,13 +93,13 @@ func PollResults(w http.ResponseWriter, r *http.Request, user common.User, sPoll
var votes int
err := rows.Scan(&votes)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
optionList += strconv.Itoa(votes) + ","
}
err = rows.Err()
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

View File

@ -6,7 +6,7 @@ import (
"strings"
"time"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen"
)
@ -19,7 +19,7 @@ var profileStmts ProfileStmts
// TODO: Move these DbInits into some sort of abstraction
func init() {
common.DbInits.Add(func(acc *qgen.Accumulator) error {
c.DbInits.Add(func(acc *qgen.Accumulator) error {
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 = ?", "", ""),
}
@ -28,7 +28,7 @@ func init() {
}
// 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?
header.AddSheet(header.Theme.Name + "/profile.css")
if user.Loggedin {
@ -39,57 +39,57 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User, heade
var replyCreatedAt time.Time
var replyContent, replyCreatedByName, replyAvatar, replyMicroAvatar, replyTag, replyClassName string
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?
_, pid, err := ParseSEOURL(r.URL.Path[len("/user/"):])
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 {
user.IsMod = true
puser = &user
} else {
// Fetch the user data
// 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 {
return common.NotFound(w, r, header)
return c.NotFound(w, r, header)
} else if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
puser.Init()
}
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..
rows, err := profileStmts.getReplies.Query(puser.ID)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
defer rows.Close()
for rows.Next() {
err := rows.Scan(&rid, &replyContent, &replyCreatedBy, &replyCreatedAt, &replyLastEdit, &replyLastEditBy, &replyAvatar, &replyCreatedByName, &replyGroup)
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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
replyLines = strings.Count(replyContent, "\n")
if group.IsMod {
replyClassName = common.Config.StaffCSS
replyClassName = c.Config.StaffCSS
} else {
replyClassName = ""
}
replyAvatar, replyMicroAvatar = common.BuildAvatar(replyCreatedBy, replyAvatar)
replyAvatar, replyMicroAvatar = c.BuildAvatar(replyCreatedBy, replyAvatar)
if group.Tag != "" {
replyTag = group.Tag
@ -103,18 +103,18 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User, heade
replyLikeCount := 0
// 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()
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
prevScore := common.GetLevelScore(puser.Level)
prevScore := c.GetLevelScore(puser.Level)
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)
}

View File

@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen"
@ -23,7 +23,7 @@ var replyStmts ReplyStmts
// TODO: Move this statement somewhere else
func init() {
common.DbInits.Add(func(acc *qgen.Accumulator) error {
c.DbInits.Add(func(acc *qgen.Accumulator) error {
replyStmts = ReplyStmts{
// TODO: Less race-y attachment count updates
updateAttachs: acc.Update("replies").Set("attachCount = ?").Where("rid = ?").Prepare(),
@ -37,43 +37,43 @@ type JsonReply struct {
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
js := r.FormValue("js") == "1"
tid, err := strconv.Atoi(r.PostFormValue("tid"))
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 {
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 {
return common.InternalErrorJSQ(err, w, r, js)
return c.InternalErrorJSQ(err, w, r, js)
}
// 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 {
return ferr
}
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 {
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
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 {
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 {
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
@ -89,26 +89,26 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User)
var maxPollOptions = 10
var pollInputItems = make(map[int]string)
for key, values := range r.Form {
//common.DebugDetail("key: ", key)
//common.DebugDetailf("values: %+v\n", values)
//c.DebugDetail("key: ", key)
//c.DebugDetailf("values: %+v\n", values)
for _, value := range values {
if strings.HasPrefix(key, "pollinputitem[") {
halves := strings.Split(key, "[")
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], "]")
index, err := strconv.Atoi(halves[1])
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
_, exists := pollInputItems[index]
// TODO: Should we use SanitiseBody instead to keep the newlines?
if !exists && len(common.SanitiseSingleLine(value)) != 0 {
pollInputItems[index] = common.SanitiseSingleLine(value)
if !exists && len(c.SanitiseSingleLine(value)) != 0 {
pollInputItems[index] = c.SanitiseSingleLine(value)
if len(pollInputItems) >= maxPollOptions {
break
}
@ -124,40 +124,40 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User)
}
pollType := 0 // Basic single choice
_, err := common.Polls.Create(reply, pollType, seqPollInputItems)
_, err := c.Polls.Create(reply, pollType, seqPollInputItems)
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 {
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 {
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)
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 {
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 {
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)
if err != nil && err != sql.ErrNoRows {
return common.InternalErrorJSQ(err, w, r, js)
return c.InternalErrorJSQ(err, w, r, js)
}
defer rows.Close()
@ -166,16 +166,16 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User)
var rid int
err := rows.Scan(&rid)
if err != nil {
return common.InternalErrorJSQ(err, w, r, js)
return c.InternalErrorJSQ(err, w, r, js)
}
rids = append(rids, rid)
}
err = rows.Err()
if err != nil {
return common.InternalErrorJSQ(err, w, r, js)
return c.InternalErrorJSQ(err, w, r, js)
}
if len(rids) == 0 {
return common.NotFoundJSQ(w, r, nil, js)
return c.NotFoundJSQ(w, r, nil, js)
}
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 {
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()
@ -196,9 +196,9 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user common.User)
prid, _ := strconv.Atoi(r.FormValue("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 {
return common.InternalErrorJSQ(err, w, r, js)
return c.InternalErrorJSQ(err, w, r, js)
}
w.Write(outBytes)
} 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: 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")
rid, err := strconv.Atoi(srid)
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 {
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 {
return common.InternalErrorJSQ(err, w, r, js)
return c.InternalErrorJSQ(err, w, r, js)
}
topic, err := reply.Topic()
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 {
return common.InternalErrorJSQ(err, w, r, js)
return c.InternalErrorJSQ(err, w, r, js)
}
// 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 {
return ferr
}
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 {
return common.NoPermissionsJSQ(w, r, user, js)
return c.NoPermissionsJSQ(w, r, user, js)
}
err = reply.SetPost(r.PostFormValue("edit_item"))
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 {
return common.InternalErrorJSQ(err, w, r, js)
return c.InternalErrorJSQ(err, w, r, js)
}
// TODO: Avoid the load to get this faster?
reply, err = common.Rstore.Get(rid)
reply, err = c.Rstore.Get(rid)
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 {
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)
@ -269,9 +269,9 @@ func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, s
if !js {
http.Redirect(w, r, "/topic/"+strconv.Itoa(topic.ID)+"#reply-"+strconv.Itoa(rid), http.StatusSeeOther)
} 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 {
return common.InternalErrorJSQ(err, w, r, js)
return c.InternalErrorJSQ(err, w, r, js)
}
w.Write(outBytes)
}
@ -281,39 +281,39 @@ func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user common.User, s
// TODO: Refactor this
// 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")
rid, err := strconv.Atoi(srid)
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 {
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 {
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 {
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 {
return common.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, isJs)
}
// 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 {
return ferr
}
if !user.Perms.ViewTopic || !user.Perms.DeleteReply {
return common.NoPermissionsJSQ(w, r, user, isJs)
return c.NoPermissionsJSQ(w, r, user, isJs)
}
err = reply.Delete()
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)
@ -321,7 +321,7 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user common.User,
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 {
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
} 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...?
replyCreator, err := common.Users.Get(reply.CreatedBy)
replyCreator, err := c.Users.Get(reply.CreatedBy)
if err == nil {
wcount := common.WordCount(reply.Content)
wcount := c.WordCount(reply.Content)
err = replyCreator.DecreasePostStats(wcount, false)
if err != nil {
return common.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, isJs)
}
} 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 {
return common.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, isJs)
}
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: Enforce the max request limit on all of this topic's attachments
// 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)
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 {
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 {
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 {
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 {
return ferr
}
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 {
return common.NoPermissionsJS(w, r, user)
return c.NoPermissionsJS(w, r, user)
}
// Handle the file attachments
@ -386,7 +386,7 @@ func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user common.
return rerr
}
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)
@ -407,43 +407,43 @@ func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user common.
}
// 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)
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 {
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 {
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 {
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 {
return ferr
}
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 {
return common.NoPermissionsJS(w, r, user)
return c.NoPermissionsJS(w, r, user)
}
saids := strings.Split(r.PostFormValue("aids"), ",")
if len(saids) == 0 {
return common.LocalErrorJS("No aids provided", w, r)
return c.LocalErrorJS("No aids provided", w, r)
}
for _, said := range saids {
aid, err := strconv.Atoi(said)
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)
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?
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 {
return common.NoPermissions(w, r, user)
return c.NoPermissions(w, r, user)
}
uid, err := strconv.Atoi(r.PostFormValue("uid"))
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 {
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 {
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
_, 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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
// ! Be careful about leaking per-route permission state with &user
alert := common.Alert{0, user.ID, profileOwner.ID, "reply", "user", profileOwner.ID, &user}
err = common.AddActivityAndNotifyTarget(alert)
alert := c.Alert{0, user.ID, profileOwner.ID, "reply", "user", profileOwner.ID, &user}
err = c.AddActivityAndNotifyTarget(alert)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
counters.PostCounter.Bump()
@ -498,34 +498,34 @@ func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user commo
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")
rid, err := strconv.Atoi(srid)
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 {
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 {
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 {
return common.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, isJs)
}
// ? Does the admin understand that this group perm affects this?
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"))
if err != nil {
return common.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, isJs)
}
if !isJs {
@ -536,35 +536,35 @@ func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user common.
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")
rid, err := strconv.Atoi(srid)
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 {
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 {
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 {
return common.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, isJs)
}
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()
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 {
//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
}
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")
rid, err := strconv.Atoi(srid)
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 {
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 {
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 {
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 {
return common.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, isJs)
}
// 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 {
return ferr
}
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 {
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 {
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 {
return common.InternalErrorJSQ(err, w, r, isJs)
return c.InternalErrorJSQ(err, w, r, isJs)
}
err = reply.Like(user.ID)
if err == common.ErrAlreadyLiked {
return common.LocalErrorJSQ("You've already liked this!", w, r, user, isJs)
if err == c.ErrAlreadyLiked {
return c.LocalErrorJSQ("You've already liked this!", w, r, user, isJs)
} 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
alert := common.Alert{0, user.ID, reply.CreatedBy, "like", "post", rid, &user}
err = common.AddActivityAndNotifyTarget(alert)
alert := c.Alert{0, user.ID, reply.CreatedBy, "like", "post", rid, &user}
err = c.AddActivityAndNotifyTarget(alert)
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)

View File

@ -5,12 +5,12 @@ import (
"net/http"
"strconv"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters"
)
func ReportSubmit(w http.ResponseWriter, r *http.Request, user common.User, sitemID string) common.RouteError {
headerLite, ferr := common.SimpleUserCheck(w, r, &user)
func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError {
headerLite, ferr := c.SimpleUserCheck(w, r, &user)
if ferr != nil {
return ferr
}
@ -18,51 +18,51 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user common.User, site
itemID, err := strconv.Atoi(sitemID)
if err != nil {
return common.LocalError("Bad ID", w, r, user)
return c.LocalError("Bad ID", w, r, user)
}
itemType := r.FormValue("type")
// TODO: Localise these titles and bodies
var title, content string
if itemType == "reply" {
reply, err := common.Rstore.Get(itemID)
reply, err := c.Rstore.Get(itemID)
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 {
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 {
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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
title = "Reply: " + topic.Title
content = reply.Content + "\n\nOriginal Post: #rid-" + strconv.Itoa(itemID)
} else if itemType == "user-reply" {
userReply, err := common.Prstore.Get(itemID)
userReply, err := c.Prstore.Get(itemID)
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 {
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 {
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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
title = "Profile: " + profileOwner.Name
content = userReply.Content + "\n\nOriginal Post: @" + strconv.Itoa(userReply.ParentID)
} else if itemType == "topic" {
topic, err := common.Topics.Get(itemID)
topic, err := c.Topics.Get(itemID)
if err == sql.ErrNoRows {
return common.NotFound(w, r, nil)
return c.NotFound(w, r, nil)
} else if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
title = "Topic: " + topic.Title
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
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
_, err = common.Reports.Create(title, content, &user, itemType, itemID)
if err == common.ErrAlreadyReported {
return common.LocalError("Someone has already reported this!", w, r, user)
_, err = c.Reports.Create(title, content, &user, itemType, itemID)
if err == c.ErrAlreadyReported {
return c.LocalError("Someone has already reported this!", w, r, user)
}
counters.PostCounter.Bump()

File diff suppressed because it is too large Load Diff

View File

@ -7,37 +7,37 @@ import (
"strconv"
"strings"
"github.com/Azareal/Gosora/common"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/phrases"
)
func wsTopicList(topicList []*common.TopicsRow, lastPage int) *common.WsTopicList {
wsTopicList := make([]*common.WsTopicsRow, len(topicList))
func wsTopicList(topicList []*c.TopicsRow, lastPage int) *c.WsTopicList {
wsTopicList := make([]*c.WsTopicsRow, len(topicList))
for i, topicRow := range topicList {
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", "")
}
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")
}
// 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.Zone = "topics"
header.Path = "/topics/"
header.MetaDesc = header.Settings["meta_desc"].(string)
group, err := common.Groups.Get(user.Group)
group, err := c.Groups.Get(user.Group)
if err != nil {
log.Printf("Group #%d doesn't exist despite being used by common.User #%d", user.Group, user.ID)
return common.LocalError("Something weird happened", w, r, user)
log.Printf("Group #%d doesn't exist despite being used by c.User #%d", user.Group, user.ID)
return c.LocalError("Something weird happened", w, r, user)
}
// 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, ",") {
fid, err := strconv.Atoi(sfid)
if err != nil {
return common.LocalError("Invalid fid", w, r, user)
return c.LocalError("Invalid fid", w, r, user)
}
fids = append(fids, fid)
}
if len(fids) == 1 {
forum, err := common.Forums.Get(fids[0])
forum, err := c.Forums.Get(fids[0])
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.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: Simplify this block after initially landing search
var topicList []*common.TopicsRow
var forumList []common.Forum
var paginator common.Paginator
var topicList []*c.TopicsRow
var forumList []c.Forum
var paginator c.Paginator
q := r.FormValue("q")
if q != "" && common.RepliesSearch != nil {
if q != "" && c.RepliesSearch != nil {
var canSee []int
if user.IsSuperAdmin {
canSee, err = common.Forums.GetAllVisibleIDs()
canSee, err = c.Forums.GetAllVisibleIDs()
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
} else {
canSee = group.CanSee
@ -91,7 +91,7 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user common.User, h
}
for _, fid := range fids {
if inSlice(canSee, fid) {
forum := common.Forums.DirtyGet(fid)
forum := c.Forums.DirtyGet(fid)
if forum.Name != "" && forum.Active && (forum.ParentType == "" || forum.ParentType == "forum") {
// TODO: Add a hook here for plugin_guilds?
cfids = append(cfids, fid)
@ -102,16 +102,16 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user common.User, h
cfids = canSee
}
tids, err := common.RepliesSearch.Query(q, cfids)
tids, err := c.RepliesSearch.Query(q, cfids)
if err != nil && err != sql.ErrNoRows {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
//fmt.Printf("tids %+v\n", tids)
// TODO: Handle the case where there aren't any items...
// TODO: Add a BulkGet method which returns a slice?
tMap, err := common.Topics.BulkGetMap(tids)
tMap, err := c.Topics.BulkGetMap(tids)
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
var reqUserList = make(map[int]bool)
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?
//fmt.Printf("idSlice %+v\n", idSlice)
userList, err := common.Users.BulkGetMap(idSlice)
userList, err := c.Users.BulkGetMap(idSlice)
if err != nil {
return nil // TODO: Implement this!
}
// TODO: De-dupe this logic in common/topic_list.go?
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.
forum := common.Forums.DirtyGet(topic.ParentID)
forum := c.Forums.DirtyGet(topic.ParentID)
topic.ForumName = forum.Name
topic.ForumLink = forum.Link
// 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.Creator = userList[topic.CreatedBy]
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" {
outBytes, err := wsTopicList(topicList, paginator.LastPage).MarshalJSON()
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
w.Write(outBytes)
return nil
}
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)
}
// TODO: Pass a struct back rather than passing back so many variables
if user.IsSuperAdmin {
topicList, forumList, paginator, err = common.TopicList.GetList(page, tsorder, fids)
topicList, forumList, paginator, err = c.TopicList.GetList(page, tsorder, fids)
} 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 {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
// ! Need an inline error not a page level error
if len(topicList) == 0 {
return common.NotFound(w, r, header)
return c.NotFound(w, r, header)
}
// TODO: Reduce the amount of boilerplate here
if r.FormValue("js") == "1" {
outBytes, err := wsTopicList(topicList, paginator.LastPage).MarshalJSON()
if err != nil {
return common.InternalError(err, w, r)
return c.InternalError(err, w, r)
}
w.Write(outBytes)
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)
}