Alerts are now rendered via a client side transpiled template rather than being hard-coded.
Tweaked some bits to make them more 32-bit friendly for GopherJS, but this might not be necessary now. Added notice.html Added an alerts package to fix the import cycles, more things may be moved here soon. Saved a few lines of accumulator code in a few stores. Moved the AccountEditCriticalSubmit, AccountEditAvatar, AccountEditAvatarSubmit, AccountEditUsername, and AccountEditUsernameSubmit routes into the routes package. Added a QueryRow method to AccSelectBuilder. Tweaked the indentation in the generated templates. Simplified the template render in the AccountEditUsernameSubmit route into a redirect back to the previous page. Run the update script / patcher to replace the route names in the viewchunks table.
This commit is contained in:
parent
185f00e019
commit
9075798128
|
@ -4,7 +4,8 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
"../common"
|
"../common"
|
||||||
"../tmpl_gen/client"
|
"../common/alerts"
|
||||||
|
"../tmpl_gen"
|
||||||
"github.com/gopherjs/gopherjs/js"
|
"github.com/gopherjs/gopherjs/js"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,7 +20,7 @@ func main() {
|
||||||
|
|
||||||
js.Global.Set("renderAlert", func(asid int, path string, msg string, avatar string) string {
|
js.Global.Set("renderAlert", func(asid int, path string, msg string, avatar string) string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
alertItem := common.AlertItem{asid, path, msg, avatar}
|
alertItem := alerts.AlertItem{asid, path, msg, avatar}
|
||||||
err := tmpl.Template_alert(alertItem, &buf)
|
err := tmpl.Template_alert(alertItem, &buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
println(err.Error())
|
println(err.Error())
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package alerts
|
||||||
|
|
||||||
|
// TODO: Move the other alert related stuff to package alerts, maybe move notification logic here too?
|
||||||
|
|
||||||
|
type AlertItem struct {
|
||||||
|
ASID int
|
||||||
|
Path string
|
||||||
|
Message string
|
||||||
|
Avatar string
|
||||||
|
}
|
|
@ -101,18 +101,18 @@ func (auth *DefaultAuth) ForceLogout(uid int) error {
|
||||||
|
|
||||||
// Logout logs you out of the computer you requested the logout for, but not the other computers you're logged in with
|
// Logout logs you out of the computer you requested the logout for, but not the other computers you're logged in with
|
||||||
func (auth *DefaultAuth) Logout(w http.ResponseWriter, _ int) {
|
func (auth *DefaultAuth) Logout(w http.ResponseWriter, _ int) {
|
||||||
cookie := http.Cookie{Name: "uid", Value: "", Path: "/", MaxAge: Year}
|
cookie := http.Cookie{Name: "uid", Value: "", Path: "/", MaxAge: int(Year)}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
cookie = http.Cookie{Name: "session", Value: "", Path: "/", MaxAge: Year}
|
cookie = http.Cookie{Name: "session", Value: "", Path: "/", MaxAge: int(Year)}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Set the cookie domain
|
// TODO: Set the cookie domain
|
||||||
// SetCookies sets the two cookies required for the current user to be recognised as a specific user in future requests
|
// SetCookies sets the two cookies required for the current user to be recognised as a specific user in future requests
|
||||||
func (auth *DefaultAuth) SetCookies(w http.ResponseWriter, uid int, session string) {
|
func (auth *DefaultAuth) SetCookies(w http.ResponseWriter, uid int, session string) {
|
||||||
cookie := http.Cookie{Name: "uid", Value: strconv.Itoa(uid), Path: "/", MaxAge: Year}
|
cookie := http.Cookie{Name: "uid", Value: strconv.Itoa(uid), Path: "/", MaxAge: int(Year)}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
cookie = http.Cookie{Name: "session", Value: session, Path: "/", MaxAge: Year}
|
cookie = http.Cookie{Name: "session", Value: session, Path: "/", MaxAge: int(Year)}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,16 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// nolint I don't want to write comments for each of these o.o
|
// nolint I don't want to write comments for each of these o.o
|
||||||
const Hour int = 60 * 60
|
const Hour int64 = 60 * 60
|
||||||
const Day int = Hour * 24
|
const Day int64 = Hour * 24
|
||||||
const Week int = Day * 7
|
const Week int64 = Day * 7
|
||||||
const Month int = Day * 30
|
const Month int64 = Day * 30
|
||||||
const Year int = Day * 365
|
const Year int64 = Day * 365
|
||||||
const Kilobyte int = 1024
|
const Kilobyte int64 = 1024
|
||||||
const Megabyte int = Kilobyte * 1024
|
const Megabyte int64 = Kilobyte * 1024
|
||||||
const Gigabyte int = Megabyte * 1024
|
const Gigabyte int64 = Megabyte * 1024
|
||||||
const Terabyte int = Gigabyte * 1024
|
const Terabyte int64 = Gigabyte * 1024
|
||||||
const Petabyte int = Terabyte * 1024
|
const Petabyte int64 = Terabyte * 1024
|
||||||
|
|
||||||
const SaltLength int = 32
|
const SaltLength int = 32
|
||||||
const SessionLength int = 80
|
const SessionLength int = 80
|
||||||
|
|
151
common/files.go
151
common/files.go
|
@ -2,6 +2,8 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"mime"
|
"mime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -11,6 +13,8 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"../tmpl_gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SFileList map[string]SFile
|
type SFileList map[string]SFile
|
||||||
|
@ -33,6 +37,153 @@ type CSSData struct {
|
||||||
Phrases map[string]string
|
Phrases map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (list SFileList) JSTmplInit() error {
|
||||||
|
var fragMap = make(map[string][][]byte)
|
||||||
|
fragMap["alert"] = tmpl.Get_alert_frags() // TODO: Add a generic fetch function, so we don't rely on the presence of the template files for this
|
||||||
|
fmt.Println("fragMap: ", fragMap)
|
||||||
|
return filepath.Walk("./tmpl_gen", func(path string, f os.FileInfo, err error) error {
|
||||||
|
if f.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(path, "template_list.go") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
path = strings.Replace(path, "\\", "/", -1)
|
||||||
|
DebugLog("Processing client template " + path)
|
||||||
|
data, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var replace = func(data []byte, replaceThis string, withThis string) []byte {
|
||||||
|
return bytes.Replace(data, []byte(replaceThis), []byte(withThis), -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
startIndex, hasFunc := skipAllUntilCharsExist(data, 0, []byte("func Template"))
|
||||||
|
if !hasFunc {
|
||||||
|
return errors.New("no template function found")
|
||||||
|
}
|
||||||
|
data = data[startIndex-len([]byte("func Template")):]
|
||||||
|
data = replace(data, "func ", "function ")
|
||||||
|
data = replace(data, " error {\n", " {\nlet out = \"\"\n")
|
||||||
|
spaceIndex, hasSpace := skipUntilIfExists(data, 10, ' ')
|
||||||
|
if !hasSpace {
|
||||||
|
return errors.New("no spaces found after the template function name")
|
||||||
|
}
|
||||||
|
endBrace, hasBrace := skipUntilIfExists(data, spaceIndex, ')')
|
||||||
|
if !hasBrace {
|
||||||
|
return errors.New("no right brace found after the template function name")
|
||||||
|
}
|
||||||
|
fmt.Println("spaceIndex: ", spaceIndex)
|
||||||
|
fmt.Println("endBrace: ", endBrace)
|
||||||
|
fmt.Println("string(data[spaceIndex:endBrace]): ", string(data[spaceIndex:endBrace]))
|
||||||
|
preLen := len(data)
|
||||||
|
data = replace(data, string(data[spaceIndex:endBrace]), "")
|
||||||
|
data = replace(data, "))\n", "\n")
|
||||||
|
endBrace -= preLen - len(data) // Offset it as we've deleted portions
|
||||||
|
|
||||||
|
var showPos = func(data []byte, index int) (out string) {
|
||||||
|
out = "["
|
||||||
|
for j, char := range data {
|
||||||
|
if index == j {
|
||||||
|
out += "[" + string(char) + "] "
|
||||||
|
} else {
|
||||||
|
out += string(char) + " "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out + "]"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ? Can we just use a regex? I'm thinking of going more efficient, or just outright rolling wasm, this is a temp hack in a place where performance doesn't particularly matter
|
||||||
|
var each = func(phrase string, handle func(index int)) {
|
||||||
|
fmt.Println("find each '" + phrase + "'")
|
||||||
|
var index = endBrace
|
||||||
|
var foundIt bool
|
||||||
|
for {
|
||||||
|
fmt.Println("in index: ", index)
|
||||||
|
fmt.Println("pos: ", showPos(data, index))
|
||||||
|
index, foundIt = skipAllUntilCharsExist(data, index, []byte(phrase))
|
||||||
|
if !foundIt {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
handle(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
each("strconv.Itoa(", func(index int) {
|
||||||
|
braceAt, hasEndBrace := skipUntilIfExists(data, index, ')')
|
||||||
|
// TODO: Make sure we don't go onto the next line in case someone misplaced a brace
|
||||||
|
if hasEndBrace {
|
||||||
|
data[braceAt] = ' ' // Blank it
|
||||||
|
}
|
||||||
|
})
|
||||||
|
each("w.Write([]byte(", func(index int) {
|
||||||
|
braceAt, hasEndBrace := skipUntilIfExists(data, index, ')')
|
||||||
|
// TODO: Make sure we don't go onto the next line in case someone misplaced a brace
|
||||||
|
if hasEndBrace {
|
||||||
|
data[braceAt] = ' ' // Blank it
|
||||||
|
}
|
||||||
|
braceAt, hasEndBrace = skipUntilIfExists(data, braceAt, ')')
|
||||||
|
if hasEndBrace {
|
||||||
|
data[braceAt] = ' ' // Blank this one too
|
||||||
|
}
|
||||||
|
})
|
||||||
|
each("w.Write(", func(index int) {
|
||||||
|
braceAt, hasEndBrace := skipUntilIfExists(data, index, ')')
|
||||||
|
// TODO: Make sure we don't go onto the next line in case someone misplaced a brace
|
||||||
|
if hasEndBrace {
|
||||||
|
data[braceAt] = ' ' // Blank it
|
||||||
|
}
|
||||||
|
})
|
||||||
|
each("if ", func(index int) {
|
||||||
|
fmt.Println("if index: ", index)
|
||||||
|
braceAt, hasBrace := skipUntilIfExists(data, index, '{')
|
||||||
|
if hasBrace {
|
||||||
|
if data[braceAt-1] != ' ' {
|
||||||
|
panic("couldn't find space before brace, found ' " + string(data[braceAt-1]) + "' instead")
|
||||||
|
}
|
||||||
|
data[braceAt-1] = ')' // Drop a brace here to satisfy JS
|
||||||
|
}
|
||||||
|
})
|
||||||
|
data = replace(data, "w.Write([]byte(", "out += ")
|
||||||
|
data = replace(data, "w.Write(", "out += ")
|
||||||
|
data = replace(data, "strconv.Itoa(", "")
|
||||||
|
data = replace(data, "if ", "if(")
|
||||||
|
data = replace(data, "return nil", "return out")
|
||||||
|
data = replace(data, " )", ")")
|
||||||
|
data = replace(data, " \n", "\n")
|
||||||
|
data = replace(data, "\n", ";\n")
|
||||||
|
data = replace(data, "{;", "{")
|
||||||
|
data = replace(data, "};", "}")
|
||||||
|
data = replace(data, ";;", ";")
|
||||||
|
|
||||||
|
path = strings.TrimPrefix(path, "tmpl_gen/")
|
||||||
|
tmplName := strings.TrimSuffix(path, ".go")
|
||||||
|
fragset, ok := fragMap[strings.TrimPrefix(tmplName, "template_")]
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("tmplName: ", tmplName)
|
||||||
|
return errors.New("couldn't find template in fragmap")
|
||||||
|
}
|
||||||
|
|
||||||
|
var sfrags = []byte("let alert_frags = [];\n")
|
||||||
|
for _, frags := range fragset {
|
||||||
|
sfrags = append(sfrags, []byte("alert_frags.push(`"+string(frags)+"`);\n")...)
|
||||||
|
}
|
||||||
|
data = append(sfrags, data...)
|
||||||
|
data = replace(data, "\n;", "\n")
|
||||||
|
|
||||||
|
path = tmplName + ".js"
|
||||||
|
DebugLog("js path: ", path)
|
||||||
|
var ext = filepath.Ext("/tmpl_gen/" + path)
|
||||||
|
gzipData := compressBytesGzip(data)
|
||||||
|
|
||||||
|
list.Set("/static/"+path, SFile{data, gzipData, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)})
|
||||||
|
|
||||||
|
DebugLogf("Added the '%s' static file.", path)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (list SFileList) Init() error {
|
func (list SFileList) Init() error {
|
||||||
return filepath.Walk("./public", func(path string, f os.FileInfo, err error) error {
|
return filepath.Walk("./public", func(path string, f os.FileInfo, err error) error {
|
||||||
if f.IsDir() {
|
if f.IsDir() {
|
||||||
|
|
|
@ -168,6 +168,13 @@ func nextCharIs(tmplData []byte, i int, expects byte) bool {
|
||||||
return tmplData[i+1] == expects
|
return tmplData[i+1] == expects
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func peekNextChar(tmplData []byte, i int) byte {
|
||||||
|
if len(tmplData) <= (i + 1) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return tmplData[i+1]
|
||||||
|
}
|
||||||
|
|
||||||
func skipUntilIfExists(tmplData []byte, i int, expects byte) (newI int, hasIt bool) {
|
func skipUntilIfExists(tmplData []byte, i int, expects byte) (newI int, hasIt bool) {
|
||||||
j := i
|
j := i
|
||||||
for ; j < len(tmplData); j++ {
|
for ; j < len(tmplData); j++ {
|
||||||
|
@ -182,14 +189,47 @@ func skipUntilCharsExist(tmplData []byte, i int, expects []byte) (newI int, hasI
|
||||||
j := i
|
j := i
|
||||||
expectIndex := 0
|
expectIndex := 0
|
||||||
for ; j < len(tmplData) && expectIndex < len(expects); j++ {
|
for ; j < len(tmplData) && expectIndex < len(expects); j++ {
|
||||||
|
//fmt.Println("tmplData[j]: ", string(tmplData[j]))
|
||||||
if tmplData[j] != expects[expectIndex] {
|
if tmplData[j] != expects[expectIndex] {
|
||||||
return j, false
|
return j, false
|
||||||
}
|
}
|
||||||
|
//fmt.Printf("found %+v at %d\n", string(expects[expectIndex]), expectIndex)
|
||||||
expectIndex++
|
expectIndex++
|
||||||
}
|
}
|
||||||
return j, true
|
return j, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func skipAllUntilCharsExist(tmplData []byte, i int, expects []byte) (newI int, hasIt bool) {
|
||||||
|
j := i
|
||||||
|
expectIndex := 0
|
||||||
|
//fmt.Printf("tmplData: %+v\n", string(tmplData))
|
||||||
|
for ; j < len(tmplData) && expectIndex < len(expects); j++ {
|
||||||
|
//fmt.Println("tmplData[j]: ", string(tmplData[j]) + " ")
|
||||||
|
if tmplData[j] == expects[expectIndex] {
|
||||||
|
//fmt.Printf("expects[expectIndex]: %+v - %d\n", string(expects[expectIndex]), expectIndex)
|
||||||
|
expectIndex++
|
||||||
|
if len(expects) <= expectIndex {
|
||||||
|
//fmt.Println("breaking")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*if expectIndex != 0 {
|
||||||
|
fmt.Println("broke expectations")
|
||||||
|
fmt.Println("expected: ", string(expects[expectIndex]))
|
||||||
|
fmt.Println("got: ", string(tmplData[j]))
|
||||||
|
fmt.Println("next: ", string(peekNextChar(tmplData, j)))
|
||||||
|
fmt.Println("next: ", string(peekNextChar(tmplData, j+1)))
|
||||||
|
fmt.Println("next: ", string(peekNextChar(tmplData, j+2)))
|
||||||
|
fmt.Println("next: ", string(peekNextChar(tmplData, j+3)))
|
||||||
|
}*/
|
||||||
|
expectIndex = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//fmt.Println("len(expects): ", len(expects))
|
||||||
|
//fmt.Println("expectIndex: ", expectIndex)
|
||||||
|
return j, len(expects) == expectIndex
|
||||||
|
}
|
||||||
|
|
||||||
type menuRenderItem struct {
|
type menuRenderItem struct {
|
||||||
Type int // 0: text, 1: variable
|
Type int // 0: text, 1: variable
|
||||||
Index int
|
Index int
|
||||||
|
|
|
@ -59,13 +59,6 @@ type ExtData struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type AlertItem struct {
|
|
||||||
ASID int
|
|
||||||
Path string
|
|
||||||
Message string
|
|
||||||
Avatar string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
Title string
|
Title string
|
||||||
CurrentUser User
|
CurrentUser User
|
||||||
|
|
|
@ -100,7 +100,6 @@ func InitPhrases() error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,7 @@ type SQLProfileReplyStore struct {
|
||||||
create *sql.Stmt
|
create *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSQLProfileReplyStore() (*SQLProfileReplyStore, error) {
|
func NewSQLProfileReplyStore(acc *qgen.Accumulator) (*SQLProfileReplyStore, error) {
|
||||||
acc := qgen.Builder.Accumulator()
|
|
||||||
return &SQLProfileReplyStore{
|
return &SQLProfileReplyStore{
|
||||||
get: acc.Select("users_replies").Columns("uid, content, createdBy, createdAt, lastEdit, lastEditBy, ipaddress").Where("rid = ?").Prepare(),
|
get: acc.Select("users_replies").Columns("uid, content, createdBy, createdAt, lastEdit, lastEditBy, ipaddress").Where("rid = ?").Prepare(),
|
||||||
create: acc.Insert("users_replies").Columns("uid, content, parsed_content, createdAt, createdBy, ipaddress").Fields("?,?,?,UTC_TIMESTAMP(),?,?").Prepare(),
|
create: acc.Insert("users_replies").Columns("uid, content, parsed_content, createdAt, createdBy, ipaddress").Fields("?,?,?,UTC_TIMESTAMP(),?,?").Prepare(),
|
||||||
|
|
|
@ -15,8 +15,7 @@ type SQLReplyStore struct {
|
||||||
create *sql.Stmt
|
create *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSQLReplyStore() (*SQLReplyStore, error) {
|
func NewSQLReplyStore(acc *qgen.Accumulator) (*SQLReplyStore, error) {
|
||||||
acc := qgen.Builder.Accumulator()
|
|
||||||
return &SQLReplyStore{
|
return &SQLReplyStore{
|
||||||
get: acc.Select("replies").Columns("tid, content, createdBy, createdAt, lastEdit, lastEditBy, ipaddress, likeCount").Where("rid = ?").Prepare(),
|
get: acc.Select("replies").Columns("tid, content, createdBy, createdAt, lastEdit, lastEditBy, ipaddress, likeCount").Where("rid = ?").Prepare(),
|
||||||
create: acc.Insert("replies").Columns("tid, content, parsed_content, createdAt, lastUpdated, ipaddress, words, createdBy").Fields("?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?").Prepare(),
|
create: acc.Insert("replies").Columns("tid, content, parsed_content, createdAt, lastUpdated, ipaddress, words, createdBy").Fields("?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?").Prepare(),
|
||||||
|
|
|
@ -52,7 +52,7 @@ type config struct {
|
||||||
SslPrivkey string
|
SslPrivkey string
|
||||||
SslFullchain string
|
SslFullchain string
|
||||||
|
|
||||||
MaxRequestSize int
|
MaxRequestSize int64
|
||||||
CacheTopicUser int
|
CacheTopicUser int
|
||||||
UserCacheCapacity int
|
UserCacheCapacity int
|
||||||
TopicCacheCapacity int
|
TopicCacheCapacity int
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"./alerts"
|
||||||
"./templates"
|
"./templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -297,24 +298,25 @@ func CompileJSTemplates() error {
|
||||||
config.Minify = Config.MinifyTemplates
|
config.Minify = Config.MinifyTemplates
|
||||||
config.SuperDebug = Dev.TemplateDebug
|
config.SuperDebug = Dev.TemplateDebug
|
||||||
config.SkipHandles = true
|
config.SkipHandles = true
|
||||||
|
config.SkipInitBlock = true
|
||||||
config.PackageName = "tmpl"
|
config.PackageName = "tmpl"
|
||||||
|
|
||||||
c := tmpl.NewCTemplateSet()
|
c := tmpl.NewCTemplateSet()
|
||||||
c.SetConfig(config)
|
c.SetConfig(config)
|
||||||
c.SetBaseImportMap(map[string]string{
|
c.SetBaseImportMap(map[string]string{
|
||||||
"io": "io",
|
"io": "io",
|
||||||
"../../common": "../../common",
|
"../common/alerts": "../common/alerts",
|
||||||
})
|
})
|
||||||
var varList = make(map[string]tmpl.VarItem)
|
var varList = make(map[string]tmpl.VarItem)
|
||||||
|
|
||||||
// TODO: Check what sort of path is sent exactly and use it here
|
// TODO: Check what sort of path is sent exactly and use it here
|
||||||
alertItem := AlertItem{Avatar: "", ASID: 1, Path: "/", Message: "uh oh, something happened"}
|
alertItem := alerts.AlertItem{Avatar: "", ASID: 1, Path: "/", Message: "uh oh, something happened"}
|
||||||
alertTmpl, err := c.Compile("alert.html", "templates/", "common.AlertItem", alertItem, varList)
|
alertTmpl, err := c.Compile("alert.html", "templates/", "alerts.AlertItem", alertItem, varList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var dirPrefix = "./tmpl_gen/client/"
|
var dirPrefix = "./tmpl_gen/"
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var writeTemplate = func(name string, content string) {
|
var writeTemplate = func(name string, content string) {
|
||||||
log.Print("Writing template '" + name + "'")
|
log.Print("Writing template '" + name + "'")
|
||||||
|
@ -343,6 +345,7 @@ func writeTemplateList(c *tmpl.CTemplateSet, wg *sync.WaitGroup, prefix string)
|
||||||
out := "package " + c.GetConfig().PackageName + "\n\n"
|
out := "package " + c.GetConfig().PackageName + "\n\n"
|
||||||
for templateName, count := range c.TemplateFragmentCount {
|
for templateName, count := range c.TemplateFragmentCount {
|
||||||
out += "var " + templateName + "_frags = make([][]byte," + strconv.Itoa(count) + ")\n"
|
out += "var " + templateName + "_frags = make([][]byte," + strconv.Itoa(count) + ")\n"
|
||||||
|
out += "\n// nolint\nfunc Get_" + templateName + "_frags() [][]byte {\nreturn " + templateName + "_frags\n}\n"
|
||||||
}
|
}
|
||||||
out += "\n// nolint\nfunc init() {\n" + c.FragOut + "}\n"
|
out += "\n// nolint\nfunc init() {\n" + c.FragOut + "}\n"
|
||||||
err := writeFile(prefix+"template_list.go", out)
|
err := writeFile(prefix+"template_list.go", out)
|
||||||
|
|
|
@ -107,7 +107,6 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe
|
||||||
if c.config.Debug {
|
if c.config.Debug {
|
||||||
fmt.Println("Compiling template '" + name + "'")
|
fmt.Println("Compiling template '" + name + "'")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.importMap = map[string]string{}
|
c.importMap = map[string]string{}
|
||||||
for index, item := range c.baseImportMap {
|
for index, item := range c.baseImportMap {
|
||||||
c.importMap[index] = item
|
c.importMap[index] = item
|
||||||
|
@ -135,7 +134,6 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
content := string(res)
|
content := string(res)
|
||||||
if c.config.Minify {
|
if c.config.Minify {
|
||||||
content = minify(content)
|
content = minify(content)
|
||||||
|
@ -149,7 +147,6 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe
|
||||||
}
|
}
|
||||||
c.detail(name)
|
c.detail(name)
|
||||||
|
|
||||||
out = ""
|
|
||||||
fname := strings.TrimSuffix(name, filepath.Ext(name))
|
fname := strings.TrimSuffix(name, filepath.Ext(name))
|
||||||
c.templateList = map[string]*parse.Tree{fname: tree}
|
c.templateList = map[string]*parse.Tree{fname: tree}
|
||||||
varholder := "tmpl_" + fname + "_vars"
|
varholder := "tmpl_" + fname + "_vars"
|
||||||
|
@ -212,7 +209,7 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe
|
||||||
if len(c.langIndexToName) > 0 {
|
if len(c.langIndexToName) > 0 {
|
||||||
fout += "var phrases = common.GetTmplPhrasesBytes(" + fname + "_tmpl_phrase_id)\n"
|
fout += "var phrases = common.GetTmplPhrasesBytes(" + fname + "_tmpl_phrase_id)\n"
|
||||||
}
|
}
|
||||||
fout += varString + out + "\treturn nil\n}\n"
|
fout += varString + out + "return nil\n}\n"
|
||||||
|
|
||||||
fout = strings.Replace(fout, `))
|
fout = strings.Replace(fout, `))
|
||||||
w.Write([]byte(`, " + ", -1)
|
w.Write([]byte(`, " + ", -1)
|
||||||
|
@ -278,7 +275,6 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value
|
||||||
c.detail("Selected Branch 1")
|
c.detail("Selected Branch 1")
|
||||||
return out + "\n"
|
return out + "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
c.detail("Selected Branch 2")
|
c.detail("Selected Branch 2")
|
||||||
return out + " else {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.ElseList) + "}\n"
|
return out + " else {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.ElseList) + "}\n"
|
||||||
case *parse.ListNode:
|
case *parse.ListNode:
|
||||||
|
@ -947,7 +943,6 @@ func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflec
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
content := string(res)
|
content := string(res)
|
||||||
if c.config.Minify {
|
if c.config.Minify {
|
||||||
content = minify(content)
|
content = minify(content)
|
||||||
|
|
|
@ -148,10 +148,11 @@ func ConvertByteInUnit(bytes float64, unit string) (count float64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
|
// TODO: Re-add T as int64
|
||||||
func ConvertUnit(num int) (int, string) {
|
func ConvertUnit(num int) (int, string) {
|
||||||
switch {
|
switch {
|
||||||
case num >= 1000000000000:
|
//case num >= 1000000000000:
|
||||||
return num / 1000000000000, "T"
|
// return num / 1000000000000, "T"
|
||||||
case num >= 1000000000:
|
case num >= 1000000000:
|
||||||
return num / 1000000000, "B"
|
return num / 1000000000, "B"
|
||||||
case num >= 1000000:
|
case num >= 1000000:
|
||||||
|
@ -164,12 +165,14 @@ func ConvertUnit(num int) (int, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Write a test for this
|
// TODO: Write a test for this
|
||||||
|
// TODO: Re-add quadrillion as int64
|
||||||
|
// TODO: Re-add trillion as int64
|
||||||
func ConvertFriendlyUnit(num int) (int, string) {
|
func ConvertFriendlyUnit(num int) (int, string) {
|
||||||
switch {
|
switch {
|
||||||
case num >= 1000000000000000:
|
//case num >= 1000000000000000:
|
||||||
return 0, " quadrillion"
|
// return 0, " quadrillion"
|
||||||
case num >= 1000000000000:
|
//case num >= 1000000000000:
|
||||||
return 0, " trillion"
|
// return 0, " trillion"
|
||||||
case num >= 1000000000:
|
case num >= 1000000000:
|
||||||
return num / 1000000000, " billion"
|
return num / 1000000000, " billion"
|
||||||
case num >= 1000000:
|
case num >= 1000000:
|
||||||
|
|
|
@ -9,7 +9,6 @@ import "./common"
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
type Stmts struct {
|
type Stmts struct {
|
||||||
getPassword *sql.Stmt
|
|
||||||
isPluginActive *sql.Stmt
|
isPluginActive *sql.Stmt
|
||||||
getUsersOffset *sql.Stmt
|
getUsersOffset *sql.Stmt
|
||||||
isThemeDefault *sql.Stmt
|
isThemeDefault *sql.Stmt
|
||||||
|
@ -59,14 +58,6 @@ type Stmts struct {
|
||||||
func _gen_mssql() (err error) {
|
func _gen_mssql() (err error) {
|
||||||
common.DebugLog("Building the generated statements")
|
common.DebugLog("Building the generated statements")
|
||||||
|
|
||||||
common.DebugLog("Preparing getPassword statement.")
|
|
||||||
stmts.getPassword, err = db.Prepare("SELECT [password],[salt] FROM [users] WHERE [uid] = ?1")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Error in getPassword statement.")
|
|
||||||
log.Print("Bad Query: ","SELECT [password],[salt] FROM [users] WHERE [uid] = ?1")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
common.DebugLog("Preparing isPluginActive statement.")
|
common.DebugLog("Preparing isPluginActive statement.")
|
||||||
stmts.isPluginActive, err = db.Prepare("SELECT [active] FROM [plugins] WHERE [uname] = ?1")
|
stmts.isPluginActive, err = db.Prepare("SELECT [active] FROM [plugins] WHERE [uname] = ?1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -11,7 +11,6 @@ import "./common"
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
type Stmts struct {
|
type Stmts struct {
|
||||||
getPassword *sql.Stmt
|
|
||||||
isPluginActive *sql.Stmt
|
isPluginActive *sql.Stmt
|
||||||
getUsersOffset *sql.Stmt
|
getUsersOffset *sql.Stmt
|
||||||
isThemeDefault *sql.Stmt
|
isThemeDefault *sql.Stmt
|
||||||
|
@ -61,13 +60,6 @@ type Stmts struct {
|
||||||
func _gen_mysql() (err error) {
|
func _gen_mysql() (err error) {
|
||||||
common.DebugLog("Building the generated statements")
|
common.DebugLog("Building the generated statements")
|
||||||
|
|
||||||
common.DebugLog("Preparing getPassword statement.")
|
|
||||||
stmts.getPassword, err = db.Prepare("SELECT `password`,`salt` FROM `users` WHERE `uid` = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Print("Error in getPassword statement.")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
common.DebugLog("Preparing isPluginActive statement.")
|
common.DebugLog("Preparing isPluginActive statement.")
|
||||||
stmts.isPluginActive, err = db.Prepare("SELECT `active` FROM `plugins` WHERE `uname` = ?")
|
stmts.isPluginActive, err = db.Prepare("SELECT `active` FROM `plugins` WHERE `uname` = ?")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -89,11 +89,11 @@ var RouteMap = map[string]interface{}{
|
||||||
"routePanelDebug": routePanelDebug,
|
"routePanelDebug": routePanelDebug,
|
||||||
"routePanelDashboard": routePanelDashboard,
|
"routePanelDashboard": routePanelDashboard,
|
||||||
"routes.AccountEditCritical": routes.AccountEditCritical,
|
"routes.AccountEditCritical": routes.AccountEditCritical,
|
||||||
"routeAccountEditCriticalSubmit": routeAccountEditCriticalSubmit,
|
"routes.AccountEditCriticalSubmit": routes.AccountEditCriticalSubmit,
|
||||||
"routeAccountEditAvatar": routeAccountEditAvatar,
|
"routes.AccountEditAvatar": routes.AccountEditAvatar,
|
||||||
"routeAccountEditAvatarSubmit": routeAccountEditAvatarSubmit,
|
"routes.AccountEditAvatarSubmit": routes.AccountEditAvatarSubmit,
|
||||||
"routeAccountEditUsername": routeAccountEditUsername,
|
"routes.AccountEditUsername": routes.AccountEditUsername,
|
||||||
"routeAccountEditUsernameSubmit": routeAccountEditUsernameSubmit,
|
"routes.AccountEditUsernameSubmit": routes.AccountEditUsernameSubmit,
|
||||||
"routeAccountEditEmail": routeAccountEditEmail,
|
"routeAccountEditEmail": routeAccountEditEmail,
|
||||||
"routeAccountEditEmailTokenSubmit": routeAccountEditEmailTokenSubmit,
|
"routeAccountEditEmailTokenSubmit": routeAccountEditEmailTokenSubmit,
|
||||||
"routes.ViewProfile": routes.ViewProfile,
|
"routes.ViewProfile": routes.ViewProfile,
|
||||||
|
@ -205,11 +205,11 @@ var routeMapEnum = map[string]int{
|
||||||
"routePanelDebug": 67,
|
"routePanelDebug": 67,
|
||||||
"routePanelDashboard": 68,
|
"routePanelDashboard": 68,
|
||||||
"routes.AccountEditCritical": 69,
|
"routes.AccountEditCritical": 69,
|
||||||
"routeAccountEditCriticalSubmit": 70,
|
"routes.AccountEditCriticalSubmit": 70,
|
||||||
"routeAccountEditAvatar": 71,
|
"routes.AccountEditAvatar": 71,
|
||||||
"routeAccountEditAvatarSubmit": 72,
|
"routes.AccountEditAvatarSubmit": 72,
|
||||||
"routeAccountEditUsername": 73,
|
"routes.AccountEditUsername": 73,
|
||||||
"routeAccountEditUsernameSubmit": 74,
|
"routes.AccountEditUsernameSubmit": 74,
|
||||||
"routeAccountEditEmail": 75,
|
"routeAccountEditEmail": 75,
|
||||||
"routeAccountEditEmailTokenSubmit": 76,
|
"routeAccountEditEmailTokenSubmit": 76,
|
||||||
"routes.ViewProfile": 77,
|
"routes.ViewProfile": 77,
|
||||||
|
@ -319,11 +319,11 @@ var reverseRouteMapEnum = map[int]string{
|
||||||
67: "routePanelDebug",
|
67: "routePanelDebug",
|
||||||
68: "routePanelDashboard",
|
68: "routePanelDashboard",
|
||||||
69: "routes.AccountEditCritical",
|
69: "routes.AccountEditCritical",
|
||||||
70: "routeAccountEditCriticalSubmit",
|
70: "routes.AccountEditCriticalSubmit",
|
||||||
71: "routeAccountEditAvatar",
|
71: "routes.AccountEditAvatar",
|
||||||
72: "routeAccountEditAvatarSubmit",
|
72: "routes.AccountEditAvatarSubmit",
|
||||||
73: "routeAccountEditUsername",
|
73: "routes.AccountEditUsername",
|
||||||
74: "routeAccountEditUsernameSubmit",
|
74: "routes.AccountEditUsernameSubmit",
|
||||||
75: "routeAccountEditEmail",
|
75: "routeAccountEditEmail",
|
||||||
76: "routeAccountEditEmailTokenSubmit",
|
76: "routeAccountEditEmailTokenSubmit",
|
||||||
77: "routes.ViewProfile",
|
77: "routes.ViewProfile",
|
||||||
|
@ -529,7 +529,7 @@ func NewGenRouter(uploads http.Handler) (*GenRouter, error) {
|
||||||
writ := NewWriterIntercept(w)
|
writ := NewWriterIntercept(w)
|
||||||
http.StripPrefix("/uploads/",uploads).ServeHTTP(writ,req)
|
http.StripPrefix("/uploads/",uploads).ServeHTTP(writ,req)
|
||||||
if writ.GetCode() == 200 {
|
if writ.GetCode() == 200 {
|
||||||
w.Header().Set("Cache-Control", "max-age=" + strconv.Itoa(common.Day))
|
w.Header().Set("Cache-Control", "max-age=" + strconv.Itoa(int(common.Day)))
|
||||||
w.Header().Set("Vary", "Accept-Encoding")
|
w.Header().Set("Vary", "Accept-Encoding")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1337,7 +1337,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(70)
|
counters.RouteViewCounter.Bump(70)
|
||||||
err = routeAccountEditCriticalSubmit(w,req,user)
|
err = routes.AccountEditCriticalSubmit(w,req,user)
|
||||||
case "/user/edit/avatar/":
|
case "/user/edit/avatar/":
|
||||||
err = common.MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1346,7 +1346,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(71)
|
counters.RouteViewCounter.Bump(71)
|
||||||
err = routeAccountEditAvatar(w,req,user)
|
err = routes.AccountEditAvatar(w,req,user)
|
||||||
case "/user/edit/avatar/submit/":
|
case "/user/edit/avatar/submit/":
|
||||||
err = common.MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1354,7 +1354,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = common.HandleUploadRoute(w,req,user,common.Config.MaxRequestSize)
|
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -1366,7 +1366,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(72)
|
counters.RouteViewCounter.Bump(72)
|
||||||
err = routeAccountEditAvatarSubmit(w,req,user)
|
err = routes.AccountEditAvatarSubmit(w,req,user)
|
||||||
case "/user/edit/username/":
|
case "/user/edit/username/":
|
||||||
err = common.MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1375,7 +1375,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(73)
|
counters.RouteViewCounter.Bump(73)
|
||||||
err = routeAccountEditUsername(w,req,user)
|
err = routes.AccountEditUsername(w,req,user)
|
||||||
case "/user/edit/username/submit/":
|
case "/user/edit/username/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1390,7 +1390,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(74)
|
counters.RouteViewCounter.Bump(74)
|
||||||
err = routeAccountEditUsernameSubmit(w,req,user)
|
err = routes.AccountEditUsernameSubmit(w,req,user)
|
||||||
case "/user/edit/email/":
|
case "/user/edit/email/":
|
||||||
err = common.MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1492,7 +1492,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = common.HandleUploadRoute(w,req,user,common.Config.MaxRequestSize)
|
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
@ -1649,7 +1649,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = common.HandleUploadRoute(w,req,user,common.Config.MaxRequestSize)
|
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
return
|
return
|
||||||
|
|
10
main.go
10
main.go
|
@ -22,6 +22,7 @@ import (
|
||||||
"./common"
|
"./common"
|
||||||
"./common/counters"
|
"./common/counters"
|
||||||
"./config"
|
"./config"
|
||||||
|
"./query_gen/lib"
|
||||||
"github.com/fsnotify/fsnotify"
|
"github.com/fsnotify/fsnotify"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -38,11 +39,12 @@ type Globs struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func afterDBInit() (err error) {
|
func afterDBInit() (err error) {
|
||||||
common.Rstore, err = common.NewSQLReplyStore()
|
acc := qgen.Builder.Accumulator()
|
||||||
|
common.Rstore, err = common.NewSQLReplyStore(acc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
common.Prstore, err = common.NewSQLProfileReplyStore()
|
common.Prstore, err = common.NewSQLProfileReplyStore(acc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -65,6 +67,10 @@ func afterDBInit() (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
err = common.StaticFiles.JSTmplInit()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
log.Print("Initialising the widgets")
|
log.Print("Initialising the widgets")
|
||||||
err = common.InitWidgets()
|
err = common.InitWidgets()
|
||||||
|
|
177
member_routes.go
177
member_routes.go
|
@ -1,12 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"html"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -258,179 +254,6 @@ func routeReportSubmit(w http.ResponseWriter, r *http.Request, user common.User,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func routeAccountEditCriticalSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
|
||||||
_, ferr := common.SimpleUserCheck(w, r, &user)
|
|
||||||
if ferr != nil {
|
|
||||||
return ferr
|
|
||||||
}
|
|
||||||
|
|
||||||
var realPassword, salt string
|
|
||||||
currentPassword := r.PostFormValue("account-current-password")
|
|
||||||
newPassword := r.PostFormValue("account-new-password")
|
|
||||||
confirmPassword := r.PostFormValue("account-confirm-password")
|
|
||||||
|
|
||||||
err := stmts.getPassword.QueryRow(user.ID).Scan(&realPassword, &salt)
|
|
||||||
if err == ErrNoRows {
|
|
||||||
return common.LocalError("Your account no longer exists.", w, r, user)
|
|
||||||
} else if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = common.CheckPassword(realPassword, currentPassword, salt)
|
|
||||||
if err == common.ErrMismatchedHashAndPassword {
|
|
||||||
return common.LocalError("That's not the correct password.", w, r, user)
|
|
||||||
} else if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
if newPassword != confirmPassword {
|
|
||||||
return common.LocalError("The two passwords don't match.", w, r, user)
|
|
||||||
}
|
|
||||||
common.SetPassword(user.ID, newPassword)
|
|
||||||
|
|
||||||
// Log the user out as a safety precaution
|
|
||||||
common.Auth.ForceLogout(user.ID)
|
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func routeAccountEditAvatar(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
|
||||||
headerVars, ferr := common.UserCheck(w, r, &user)
|
|
||||||
if ferr != nil {
|
|
||||||
return ferr
|
|
||||||
}
|
|
||||||
|
|
||||||
pi := common.Page{"Edit Avatar", user, headerVars, tList, nil}
|
|
||||||
if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
err := common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func routeAccountEditAvatarSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
|
||||||
headerVars, ferr := common.UserCheck(w, r, &user)
|
|
||||||
if ferr != nil {
|
|
||||||
return ferr
|
|
||||||
}
|
|
||||||
|
|
||||||
var filename, ext string
|
|
||||||
for _, fheaders := range r.MultipartForm.File {
|
|
||||||
for _, hdr := range fheaders {
|
|
||||||
if hdr.Filename == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
infile, err := hdr.Open()
|
|
||||||
if err != nil {
|
|
||||||
return common.LocalError("Upload failed", w, r, user)
|
|
||||||
}
|
|
||||||
defer infile.Close()
|
|
||||||
|
|
||||||
// We don't want multiple files
|
|
||||||
// TODO: Check the length of r.MultipartForm.File and error rather than doing this x.x
|
|
||||||
if filename != "" {
|
|
||||||
if filename != hdr.Filename {
|
|
||||||
os.Remove("./uploads/avatar_" + strconv.Itoa(user.ID) + "." + ext)
|
|
||||||
return common.LocalError("You may only upload one avatar", w, r, user)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
filename = hdr.Filename
|
|
||||||
}
|
|
||||||
|
|
||||||
if ext == "" {
|
|
||||||
extarr := strings.Split(hdr.Filename, ".")
|
|
||||||
if len(extarr) < 2 {
|
|
||||||
return common.LocalError("Bad file", w, r, user)
|
|
||||||
}
|
|
||||||
ext = extarr[len(extarr)-1]
|
|
||||||
|
|
||||||
// TODO: Can we do this without a regex?
|
|
||||||
reg, err := regexp.Compile("[^A-Za-z0-9]+")
|
|
||||||
if err != nil {
|
|
||||||
return common.LocalError("Bad file extension", w, r, user)
|
|
||||||
}
|
|
||||||
ext = reg.ReplaceAllString(ext, "")
|
|
||||||
ext = strings.ToLower(ext)
|
|
||||||
}
|
|
||||||
|
|
||||||
outfile, err := os.Create("./uploads/avatar_" + strconv.Itoa(user.ID) + "." + ext)
|
|
||||||
if err != nil {
|
|
||||||
return common.LocalError("Upload failed [File Creation Failed]", w, r, user)
|
|
||||||
}
|
|
||||||
defer outfile.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(outfile, infile)
|
|
||||||
if err != nil {
|
|
||||||
return common.LocalError("Upload failed [Copy Failed]", w, r, user)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ext == "" {
|
|
||||||
return common.LocalError("No file", w, r, user)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := user.ChangeAvatar("." + ext)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + "." + ext
|
|
||||||
headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_avatar_updated"))
|
|
||||||
|
|
||||||
pi := common.Page{"Edit Avatar", user, headerVars, tList, nil}
|
|
||||||
if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func routeAccountEditUsername(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
|
||||||
headerVars, ferr := common.UserCheck(w, r, &user)
|
|
||||||
if ferr != nil {
|
|
||||||
return ferr
|
|
||||||
}
|
|
||||||
|
|
||||||
pi := common.Page{"Edit Username", user, headerVars, tList, user.Name}
|
|
||||||
if common.RunPreRenderHook("pre_render_account_own_edit_username", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
err := common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func routeAccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
|
||||||
headerVars, ferr := common.UserCheck(w, r, &user)
|
|
||||||
if ferr != nil {
|
|
||||||
return ferr
|
|
||||||
}
|
|
||||||
|
|
||||||
newUsername := html.EscapeString(strings.Replace(r.PostFormValue("account-new-username"), "\n", "", -1))
|
|
||||||
err := user.ChangeName(newUsername)
|
|
||||||
if err != nil {
|
|
||||||
return common.LocalError("Unable to change the username. Does someone else already have this name?", w, r, user)
|
|
||||||
}
|
|
||||||
user.Name = newUsername
|
|
||||||
|
|
||||||
headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_username_updated"))
|
|
||||||
pi := common.Page{"Edit Username", user, headerVars, tList, nil}
|
|
||||||
if common.RunPreRenderHook("pre_render_account_own_edit_username", w, r, &user, &pi) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
err = common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi)
|
|
||||||
if err != nil {
|
|
||||||
return common.InternalError(err, w, r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func routeAccountEditEmail(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
func routeAccountEditEmail(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
headerVars, ferr := common.UserCheck(w, r, &user)
|
headerVars, ferr := common.UserCheck(w, r, &user)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"../common"
|
"../common"
|
||||||
"../config"
|
"../config"
|
||||||
|
@ -85,10 +86,19 @@ func patcher(scanner *bufio.Scanner) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_ = schemaFile
|
dbVersion, err := strconv.Atoi(schemaFile.DBVersion)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println("Applying the patches")
|
fmt.Println("Applying the patches")
|
||||||
return patch0(scanner)
|
if dbVersion < 1 {
|
||||||
|
err := patch0(scanner)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return patch1(scanner)
|
||||||
}
|
}
|
||||||
|
|
||||||
func execStmt(stmt *sql.Stmt, err error) error {
|
func execStmt(stmt *sql.Stmt, err error) error {
|
||||||
|
|
|
@ -120,5 +120,35 @@ func patch0(scanner *bufio.Scanner) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch1(scanner *bufio.Scanner) error {
|
func patch1(scanner *bufio.Scanner) error {
|
||||||
|
// ! Don't reuse this function blindly, it doesn't escape apostrophes
|
||||||
|
var replaceTextWhere = func(replaceThis string, withThis string) error {
|
||||||
|
return execStmt(qgen.Builder.SimpleUpdate("viewchunks", "route = '"+withThis+"'", "route = '"+replaceThis+"'"))
|
||||||
|
}
|
||||||
|
|
||||||
|
err := replaceTextWhere("routeAccountEditCriticalSubmit", "routes.AccountEditCriticalSubmit")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = replaceTextWhere("routeAccountEditAvatar", "routes.AccountEditAvatar")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = replaceTextWhere("routeAccountEditAvatarSubmit", "routes.AccountEditAvatarSubmit")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = replaceTextWhere("routeAccountEditUsername", "routes.AccountEditUsername")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = replaceTextWhere("routeAccountEditUsernameSubmit", "routes.AccountEditUsernameSubmit")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,9 +49,12 @@ function bindToAlerts() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var alertsInitted = false;
|
||||||
// TODO: Add the ability for users to dismiss alerts
|
// TODO: Add the ability for users to dismiss alerts
|
||||||
function loadAlerts(menuAlerts)
|
function loadAlerts(menuAlerts)
|
||||||
{
|
{
|
||||||
|
if(!alertsInitted) return;
|
||||||
|
|
||||||
var alertListNode = menuAlerts.getElementsByClassName("alertList")[0];
|
var alertListNode = menuAlerts.getElementsByClassName("alertList")[0];
|
||||||
var alertCounterNode = menuAlerts.getElementsByClassName("alert_counter")[0];
|
var alertCounterNode = menuAlerts.getElementsByClassName("alert_counter")[0];
|
||||||
alertCounterNode.textContent = "0";
|
alertCounterNode.textContent = "0";
|
||||||
|
@ -59,7 +62,7 @@ function loadAlerts(menuAlerts)
|
||||||
type: 'get',
|
type: 'get',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
url:'/api/?action=get&module=alerts',
|
url:'/api/?action=get&module=alerts',
|
||||||
success: function(data) {
|
success: (data) => {
|
||||||
if("errmsg" in data) {
|
if("errmsg" in data) {
|
||||||
alertListNode.innerHTML = "<div class='alertItem'>"+data.errmsg+"</div>";
|
alertListNode.innerHTML = "<div class='alertItem'>"+data.errmsg+"</div>";
|
||||||
return;
|
return;
|
||||||
|
@ -76,14 +79,12 @@ function loadAlerts(menuAlerts)
|
||||||
//console.log("Sub #" + i + ":",msg.sub[i]);
|
//console.log("Sub #" + i + ":",msg.sub[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
alist += Template_alert({
|
||||||
if("avatar" in msg) {
|
ASID: msg.asid || 0,
|
||||||
alist += "<div class='alertItem withAvatar' style='background-image:url(\""+msg.avatar+"\");'><img src='"+msg.avatar+"' class='bgsub' /><a class='text' data-asid='"+msg.asid+"' href=\""+msg.path+"\">"+mmsg+"</a></div>";
|
Path: msg.path,
|
||||||
alertList.push("<div class='alertItem withAvatar' style='background-image:url(\""+msg.avatar+"\");'><img src='"+msg.avatar+"' class='bgsub' /><a class='text' data-asid='"+msg.asid+"' href=\""+msg.path+"\">"+mmsg+"</a></div>");
|
Avatar: msg.avatar || "",
|
||||||
} else {
|
Message: mmsg
|
||||||
alist += "<div class='alertItem'><a href=\""+msg.path+"\" class='text'>"+mmsg+"</a></div>";
|
})
|
||||||
alertList.push("<div class='alertItem'><a href=\""+msg.path+"\" class='text'>"+mmsg+"</a></div>");
|
|
||||||
}
|
|
||||||
//console.log(msg);
|
//console.log(msg);
|
||||||
//console.log(mmsg);
|
//console.log(mmsg);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +102,7 @@ function loadAlerts(menuAlerts)
|
||||||
|
|
||||||
bindToAlerts();
|
bindToAlerts();
|
||||||
},
|
},
|
||||||
error: function(magic,theStatus,error) {
|
error: (magic,theStatus,error) => {
|
||||||
let errtxt
|
let errtxt
|
||||||
try {
|
try {
|
||||||
var data = JSON.parse(magic.responseText);
|
var data = JSON.parse(magic.responseText);
|
||||||
|
@ -218,6 +219,14 @@ function runWebSockets() {
|
||||||
|
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
runHook("start_init");
|
runHook("start_init");
|
||||||
|
$.getScript( "./static/template_alert.js", () => {
|
||||||
|
console.log("Loaded template_alert.js");
|
||||||
|
alertsInitted = true;
|
||||||
|
var alertMenuList = document.getElementsByClassName("menu_alerts");
|
||||||
|
for(var i = 0; i < alertMenuList.length; i++) {
|
||||||
|
loadAlerts(alertMenuList[i]);
|
||||||
|
}
|
||||||
|
});
|
||||||
if(window["WebSocket"]) runWebSockets();
|
if(window["WebSocket"]) runWebSockets();
|
||||||
else conn = false;
|
else conn = false;
|
||||||
|
|
||||||
|
@ -445,11 +454,6 @@ $(document).ready(function(){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var alertMenuList = document.getElementsByClassName("menu_alerts");
|
|
||||||
for(var i = 0; i < alertMenuList.length; i++) {
|
|
||||||
loadAlerts(alertMenuList[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$(".menu_alerts").click(function(event) {
|
$(".menu_alerts").click(function(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
if($(this).hasClass("selectedAlert")) return;
|
if($(this).hasClass("selectedAlert")) return;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
This file is here so that Git will include this folder in the repository.
|
|
@ -132,6 +132,27 @@ func (selectItem *AccSelectBuilder) Query(args ...interface{}) (*sql.Rows, error
|
||||||
return nil, selectItem.build.FirstError()
|
return nil, selectItem.build.FirstError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AccRowWrap struct {
|
||||||
|
row *sql.Row
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wrap *AccRowWrap) Scan(dest ...interface{}) error {
|
||||||
|
if wrap.err != nil {
|
||||||
|
return wrap.err
|
||||||
|
}
|
||||||
|
return wrap.row.Scan(dest...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Test to make sure the errors are passed up properly
|
||||||
|
func (selectItem *AccSelectBuilder) QueryRow(args ...interface{}) *AccRowWrap {
|
||||||
|
stmt := selectItem.Prepare()
|
||||||
|
if stmt != nil {
|
||||||
|
return &AccRowWrap{stmt.QueryRow(args...), nil}
|
||||||
|
}
|
||||||
|
return &AccRowWrap{nil, selectItem.build.FirstError()}
|
||||||
|
}
|
||||||
|
|
||||||
// Experimental, reduces lines
|
// Experimental, reduces lines
|
||||||
func (selectItem *AccSelectBuilder) Each(handle func(*sql.Rows) error) error {
|
func (selectItem *AccSelectBuilder) Each(handle func(*sql.Rows) error) error {
|
||||||
rows, err := selectItem.Query()
|
rows, err := selectItem.Query()
|
||||||
|
|
|
@ -257,8 +257,6 @@ func writeSelects(adapter qgen.Adapter) error {
|
||||||
|
|
||||||
// Looking for getTopic? Your statement is in another castle
|
// Looking for getTopic? Your statement is in another castle
|
||||||
|
|
||||||
build.Select("getPassword").Table("users").Columns("password, salt").Where("uid = ?").Parse()
|
|
||||||
|
|
||||||
build.Select("isPluginActive").Table("plugins").Columns("active").Where("uname = ?").Parse()
|
build.Select("isPluginActive").Table("plugins").Columns("active").Where("uname = ?").Parse()
|
||||||
|
|
||||||
//build.Select("isPluginInstalled").Table("plugins").Columns("installed").Where("uname = ?").Parse()
|
//build.Select("isPluginInstalled").Table("plugins").Columns("installed").Where("uname = ?").Parse()
|
||||||
|
|
|
@ -348,7 +348,7 @@ func NewGenRouter(uploads http.Handler) (*GenRouter, error) {
|
||||||
writ := NewWriterIntercept(w)
|
writ := NewWriterIntercept(w)
|
||||||
http.StripPrefix("/uploads/",uploads).ServeHTTP(writ,req)
|
http.StripPrefix("/uploads/",uploads).ServeHTTP(writ,req)
|
||||||
if writ.GetCode() == 200 {
|
if writ.GetCode() == 200 {
|
||||||
w.Header().Set("Cache-Control", "max-age=" + strconv.Itoa(common.Day))
|
w.Header().Set("Cache-Control", "max-age=" + strconv.Itoa(int(common.Day)))
|
||||||
w.Header().Set("Vary", "Accept-Encoding")
|
w.Header().Set("Vary", "Accept-Encoding")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -41,11 +41,11 @@ func buildUserRoutes() {
|
||||||
userGroup.Routes(
|
userGroup.Routes(
|
||||||
View("routes.ViewProfile", "/user/").LitBefore("req.URL.Path += extraData"),
|
View("routes.ViewProfile", "/user/").LitBefore("req.URL.Path += extraData"),
|
||||||
MemberView("routes.AccountEditCritical", "/user/edit/critical/"),
|
MemberView("routes.AccountEditCritical", "/user/edit/critical/"),
|
||||||
Action("routeAccountEditCriticalSubmit", "/user/edit/critical/submit/"), // TODO: Full test this
|
Action("routes.AccountEditCriticalSubmit", "/user/edit/critical/submit/"), // TODO: Full test this
|
||||||
MemberView("routeAccountEditAvatar", "/user/edit/avatar/"),
|
MemberView("routes.AccountEditAvatar", "/user/edit/avatar/"),
|
||||||
UploadAction("routeAccountEditAvatarSubmit", "/user/edit/avatar/submit/").MaxSizeVar("common.Config.MaxRequestSize"),
|
UploadAction("routes.AccountEditAvatarSubmit", "/user/edit/avatar/submit/").MaxSizeVar("int(common.Config.MaxRequestSize)"),
|
||||||
MemberView("routeAccountEditUsername", "/user/edit/username/"),
|
MemberView("routes.AccountEditUsername", "/user/edit/username/"),
|
||||||
Action("routeAccountEditUsernameSubmit", "/user/edit/username/submit/"), // TODO: Full test this
|
Action("routes.AccountEditUsernameSubmit", "/user/edit/username/submit/"), // TODO: Full test this
|
||||||
MemberView("routeAccountEditEmail", "/user/edit/email/"),
|
MemberView("routeAccountEditEmail", "/user/edit/email/"),
|
||||||
Action("routeAccountEditEmailTokenSubmit", "/user/edit/token/", "extraData"),
|
Action("routeAccountEditEmailTokenSubmit", "/user/edit/token/", "extraData"),
|
||||||
)
|
)
|
||||||
|
@ -66,7 +66,7 @@ func buildTopicRoutes() {
|
||||||
topicGroup := newRouteGroup("/topic/")
|
topicGroup := newRouteGroup("/topic/")
|
||||||
topicGroup.Routes(
|
topicGroup.Routes(
|
||||||
View("routes.ViewTopic", "/topic/", "extraData"),
|
View("routes.ViewTopic", "/topic/", "extraData"),
|
||||||
UploadAction("routes.CreateTopicSubmit", "/topic/create/submit/").MaxSizeVar("common.Config.MaxRequestSize"),
|
UploadAction("routes.CreateTopicSubmit", "/topic/create/submit/").MaxSizeVar("int(common.Config.MaxRequestSize)"),
|
||||||
Action("routes.EditTopicSubmit", "/topic/edit/submit/", "extraData"),
|
Action("routes.EditTopicSubmit", "/topic/edit/submit/", "extraData"),
|
||||||
Action("routes.DeleteTopicSubmit", "/topic/delete/submit/").LitBefore("req.URL.Path += extraData"),
|
Action("routes.DeleteTopicSubmit", "/topic/delete/submit/").LitBefore("req.URL.Path += extraData"),
|
||||||
Action("routes.StickTopicSubmit", "/topic/stick/submit/", "extraData"),
|
Action("routes.StickTopicSubmit", "/topic/stick/submit/", "extraData"),
|
||||||
|
@ -85,7 +85,7 @@ func buildReplyRoutes() {
|
||||||
replyGroup := newRouteGroup("/reply/")
|
replyGroup := newRouteGroup("/reply/")
|
||||||
replyGroup.Routes(
|
replyGroup.Routes(
|
||||||
// TODO: Reduce this to 1MB for attachments for each file?
|
// TODO: Reduce this to 1MB for attachments for each file?
|
||||||
UploadAction("routes.CreateReplySubmit", "/reply/create/").MaxSizeVar("common.Config.MaxRequestSize"), // TODO: Rename the route so it's /reply/create/submit/
|
UploadAction("routes.CreateReplySubmit", "/reply/create/").MaxSizeVar("int(common.Config.MaxRequestSize)"), // TODO: Rename the route so it's /reply/create/submit/
|
||||||
Action("routes.ReplyEditSubmit", "/reply/edit/submit/", "extraData"),
|
Action("routes.ReplyEditSubmit", "/reply/edit/submit/", "extraData"),
|
||||||
Action("routes.ReplyDeleteSubmit", "/reply/delete/submit/", "extraData"),
|
Action("routes.ReplyDeleteSubmit", "/reply/delete/submit/", "extraData"),
|
||||||
Action("routeReplyLikeSubmit", "/reply/like/submit/", "extraData").Before("ParseForm"),
|
Action("routeReplyLikeSubmit", "/reply/like/submit/", "extraData").Before("ParseForm"),
|
||||||
|
|
|
@ -53,7 +53,7 @@ func routeChangeTheme(w http.ResponseWriter, r *http.Request, user common.User)
|
||||||
return common.LocalErrorJSQ("That theme doesn't exist", w, r, user, isJs)
|
return common.LocalErrorJSQ("That theme doesn't exist", w, r, user, isJs)
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: common.Year}
|
cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: int(common.Year)}
|
||||||
http.SetCookie(w, &cookie)
|
http.SetCookie(w, &cookie)
|
||||||
|
|
||||||
if !isJs {
|
if !isJs {
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package routes
|
package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"html"
|
"html"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -184,3 +188,172 @@ func AccountEditCritical(w http.ResponseWriter, r *http.Request, user common.Use
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AccountEditCriticalSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
_, ferr := common.SimpleUserCheck(w, r, &user)
|
||||||
|
if ferr != nil {
|
||||||
|
return ferr
|
||||||
|
}
|
||||||
|
|
||||||
|
var realPassword, salt string
|
||||||
|
currentPassword := r.PostFormValue("account-current-password")
|
||||||
|
newPassword := r.PostFormValue("account-new-password")
|
||||||
|
confirmPassword := r.PostFormValue("account-confirm-password")
|
||||||
|
|
||||||
|
// TODO: Use a reusable statement
|
||||||
|
acc := qgen.Builder.Accumulator()
|
||||||
|
err := acc.Select("users").Columns("password, salt").Where("uid = ?").QueryRow(user.ID).Scan(&realPassword, &salt)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return common.LocalError("Your account no longer exists.", w, r, user)
|
||||||
|
} else if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = common.CheckPassword(realPassword, currentPassword, salt)
|
||||||
|
if err == common.ErrMismatchedHashAndPassword {
|
||||||
|
return common.LocalError("That's not the correct password.", w, r, user)
|
||||||
|
} else if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
if newPassword != confirmPassword {
|
||||||
|
return common.LocalError("The two passwords don't match.", w, r, user)
|
||||||
|
}
|
||||||
|
common.SetPassword(user.ID, newPassword)
|
||||||
|
|
||||||
|
// Log the user out as a safety precaution
|
||||||
|
common.Auth.ForceLogout(user.ID)
|
||||||
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AccountEditAvatar(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
headerVars, ferr := common.UserCheck(w, r, &user)
|
||||||
|
if ferr != nil {
|
||||||
|
return ferr
|
||||||
|
}
|
||||||
|
|
||||||
|
pi := common.Page{"Edit Avatar", user, headerVars, tList, nil}
|
||||||
|
if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err := common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi)
|
||||||
|
if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AccountEditAvatarSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
headerVars, ferr := common.UserCheck(w, r, &user)
|
||||||
|
if ferr != nil {
|
||||||
|
return ferr
|
||||||
|
}
|
||||||
|
|
||||||
|
var filename, ext string
|
||||||
|
for _, fheaders := range r.MultipartForm.File {
|
||||||
|
for _, hdr := range fheaders {
|
||||||
|
if hdr.Filename == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
infile, err := hdr.Open()
|
||||||
|
if err != nil {
|
||||||
|
return common.LocalError("Upload failed", w, r, user)
|
||||||
|
}
|
||||||
|
defer infile.Close()
|
||||||
|
|
||||||
|
// We don't want multiple files
|
||||||
|
// TODO: Check the length of r.MultipartForm.File and error rather than doing this x.x
|
||||||
|
if filename != "" {
|
||||||
|
if filename != hdr.Filename {
|
||||||
|
os.Remove("./uploads/avatar_" + strconv.Itoa(user.ID) + "." + ext)
|
||||||
|
return common.LocalError("You may only upload one avatar", w, r, user)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filename = hdr.Filename
|
||||||
|
}
|
||||||
|
|
||||||
|
if ext == "" {
|
||||||
|
extarr := strings.Split(hdr.Filename, ".")
|
||||||
|
if len(extarr) < 2 {
|
||||||
|
return common.LocalError("Bad file", w, r, user)
|
||||||
|
}
|
||||||
|
ext = extarr[len(extarr)-1]
|
||||||
|
|
||||||
|
// TODO: Can we do this without a regex?
|
||||||
|
reg, err := regexp.Compile("[^A-Za-z0-9]+")
|
||||||
|
if err != nil {
|
||||||
|
return common.LocalError("Bad file extension", w, r, user)
|
||||||
|
}
|
||||||
|
ext = reg.ReplaceAllString(ext, "")
|
||||||
|
ext = strings.ToLower(ext)
|
||||||
|
}
|
||||||
|
|
||||||
|
outfile, err := os.Create("./uploads/avatar_" + strconv.Itoa(user.ID) + "." + ext)
|
||||||
|
if err != nil {
|
||||||
|
return common.LocalError("Upload failed [File Creation Failed]", w, r, user)
|
||||||
|
}
|
||||||
|
defer outfile.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(outfile, infile)
|
||||||
|
if err != nil {
|
||||||
|
return common.LocalError("Upload failed [Copy Failed]", w, r, user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ext == "" {
|
||||||
|
return common.LocalError("No file", w, r, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := user.ChangeAvatar("." + ext)
|
||||||
|
if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + "." + ext
|
||||||
|
headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_avatar_updated"))
|
||||||
|
|
||||||
|
pi := common.Page{"Edit Avatar", user, headerVars, tList, nil}
|
||||||
|
if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err = common.Templates.ExecuteTemplate(w, "account_own_edit_avatar.html", pi)
|
||||||
|
if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AccountEditUsername(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
headerVars, ferr := common.UserCheck(w, r, &user)
|
||||||
|
if ferr != nil {
|
||||||
|
return ferr
|
||||||
|
}
|
||||||
|
if r.FormValue("updated") == "1" {
|
||||||
|
headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_username_updated"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pi := common.Page{"Edit Username", user, headerVars, tList, user.Name}
|
||||||
|
if common.RunPreRenderHook("pre_render_account_own_edit_username", w, r, &user, &pi) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err := common.Templates.ExecuteTemplate(w, "account_own_edit_username.html", pi)
|
||||||
|
if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
||||||
|
_, ferr := common.SimpleUserCheck(w, r, &user)
|
||||||
|
if ferr != nil {
|
||||||
|
return ferr
|
||||||
|
}
|
||||||
|
|
||||||
|
newUsername := html.EscapeString(strings.Replace(r.PostFormValue("account-new-username"), "\n", "", -1))
|
||||||
|
err := user.ChangeName(newUsername)
|
||||||
|
if err != nil {
|
||||||
|
return common.LocalError("Unable to change the username. Does someone else already have this name?", w, r, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, r, "/user/edit/username/?updated=1", http.StatusSeeOther)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"../common"
|
"../common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cacheControlMaxAge = "max-age=" + strconv.Itoa(common.Day) // TODO: Make this a common.Config value
|
var cacheControlMaxAge = "max-age=" + strconv.Itoa(int(common.Day)) // TODO: Make this a common.Config value
|
||||||
|
|
||||||
// GET functions
|
// GET functions
|
||||||
func StaticFile(w http.ResponseWriter, r *http.Request) {
|
func StaticFile(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
|
@ -60,9 +60,9 @@ func BanUserSubmit(w http.ResponseWriter, r *http.Request, user common.User, sui
|
||||||
duration, _ = time.ParseDuration("0")
|
duration, _ = time.ParseDuration("0")
|
||||||
} else {
|
} else {
|
||||||
var seconds int
|
var seconds int
|
||||||
seconds += durationDays * common.Day
|
seconds += durationDays * int(common.Day)
|
||||||
seconds += durationWeeks * common.Week
|
seconds += durationWeeks * int(common.Week)
|
||||||
seconds += durationMonths * common.Month
|
seconds += durationMonths * int(common.Month)
|
||||||
duration, _ = time.ParseDuration(strconv.Itoa(seconds) + "s")
|
duration, _ = time.ParseDuration(strconv.Itoa(seconds) + "s")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"DBVersion":"1",
|
"DBVersion":"2",
|
||||||
"DynamicFileVersion":"0",
|
"DynamicFileVersion":"0",
|
||||||
"MinGoVersion":"1.10",
|
"MinGoVersion":"1.10",
|
||||||
"MinVersion":""
|
"MinVersion":""
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
// Code generated by Gosora. More below:
|
// Code generated by Gosora. More below:
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||||
package main
|
package main
|
||||||
import "./common"
|
|
||||||
import "io"
|
import "io"
|
||||||
|
import "./common"
|
||||||
|
|
||||||
var error_tmpl_phrase_id int
|
var error_tmpl_phrase_id int
|
||||||
|
|
||||||
|
@ -79,12 +79,12 @@ w.Write(header_frags[22])
|
||||||
w.Write(header_frags[23])
|
w.Write(header_frags[23])
|
||||||
if len(tmpl_error_vars.Header.NoticeList) != 0 {
|
if len(tmpl_error_vars.Header.NoticeList) != 0 {
|
||||||
for _, item := range tmpl_error_vars.Header.NoticeList {
|
for _, item := range tmpl_error_vars.Header.NoticeList {
|
||||||
w.Write(header_frags[24])
|
w.Write(notice_frags[0])
|
||||||
w.Write([]byte(item))
|
w.Write([]byte(item))
|
||||||
w.Write(header_frags[25])
|
w.Write(notice_frags[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Write(header_frags[26])
|
w.Write(header_frags[24])
|
||||||
w.Write(error_frags[0])
|
w.Write(error_frags[0])
|
||||||
w.Write(phrases[1])
|
w.Write(phrases[1])
|
||||||
w.Write(error_frags[1])
|
w.Write(error_frags[1])
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
// Code generated by Gosora. More below:
|
// Code generated by Gosora. More below:
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||||
package main
|
package main
|
||||||
import "./common"
|
|
||||||
import "io"
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
import "io"
|
||||||
|
import "./common"
|
||||||
|
|
||||||
var forum_tmpl_phrase_id int
|
var forum_tmpl_phrase_id int
|
||||||
|
|
||||||
|
@ -112,12 +112,12 @@ w.Write(header_frags[22])
|
||||||
w.Write(header_frags[23])
|
w.Write(header_frags[23])
|
||||||
if len(tmpl_forum_vars.Header.NoticeList) != 0 {
|
if len(tmpl_forum_vars.Header.NoticeList) != 0 {
|
||||||
for _, item := range tmpl_forum_vars.Header.NoticeList {
|
for _, item := range tmpl_forum_vars.Header.NoticeList {
|
||||||
w.Write(header_frags[24])
|
w.Write(notice_frags[0])
|
||||||
w.Write([]byte(item))
|
w.Write([]byte(item))
|
||||||
w.Write(header_frags[25])
|
w.Write(notice_frags[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Write(header_frags[26])
|
w.Write(header_frags[24])
|
||||||
if tmpl_forum_vars.Page > 1 {
|
if tmpl_forum_vars.Page > 1 {
|
||||||
w.Write(forum_frags[0])
|
w.Write(forum_frags[0])
|
||||||
w.Write(phrases[1])
|
w.Write(phrases[1])
|
||||||
|
|
|
@ -82,12 +82,12 @@ w.Write(header_frags[22])
|
||||||
w.Write(header_frags[23])
|
w.Write(header_frags[23])
|
||||||
if len(tmpl_forums_vars.Header.NoticeList) != 0 {
|
if len(tmpl_forums_vars.Header.NoticeList) != 0 {
|
||||||
for _, item := range tmpl_forums_vars.Header.NoticeList {
|
for _, item := range tmpl_forums_vars.Header.NoticeList {
|
||||||
w.Write(header_frags[24])
|
w.Write(notice_frags[0])
|
||||||
w.Write([]byte(item))
|
w.Write([]byte(item))
|
||||||
w.Write(header_frags[25])
|
w.Write(notice_frags[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Write(header_frags[26])
|
w.Write(header_frags[24])
|
||||||
w.Write(forums_frags[0])
|
w.Write(forums_frags[0])
|
||||||
w.Write(phrases[1])
|
w.Write(phrases[1])
|
||||||
w.Write(forums_frags[1])
|
w.Write(forums_frags[1])
|
||||||
|
|
|
@ -77,12 +77,12 @@ w.Write(header_frags[22])
|
||||||
w.Write(header_frags[23])
|
w.Write(header_frags[23])
|
||||||
if len(tmpl_guilds_guild_list_vars.Header.NoticeList) != 0 {
|
if len(tmpl_guilds_guild_list_vars.Header.NoticeList) != 0 {
|
||||||
for _, item := range tmpl_guilds_guild_list_vars.Header.NoticeList {
|
for _, item := range tmpl_guilds_guild_list_vars.Header.NoticeList {
|
||||||
w.Write(header_frags[24])
|
w.Write(notice_frags[0])
|
||||||
w.Write([]byte(item))
|
w.Write([]byte(item))
|
||||||
w.Write(header_frags[25])
|
w.Write(notice_frags[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Write(header_frags[26])
|
w.Write(header_frags[24])
|
||||||
w.Write(guilds_guild_list_frags[0])
|
w.Write(guilds_guild_list_frags[0])
|
||||||
if len(tmpl_guilds_guild_list_vars.GuildList) != 0 {
|
if len(tmpl_guilds_guild_list_vars.GuildList) != 0 {
|
||||||
for _, item := range tmpl_guilds_guild_list_vars.GuildList {
|
for _, item := range tmpl_guilds_guild_list_vars.GuildList {
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
// Code generated by Gosora. More below:
|
// Code generated by Gosora. More below:
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||||
package main
|
package main
|
||||||
import "./common"
|
|
||||||
import "io"
|
import "io"
|
||||||
|
import "./common"
|
||||||
|
|
||||||
var ip_search_tmpl_phrase_id int
|
var ip_search_tmpl_phrase_id int
|
||||||
|
|
||||||
|
@ -81,12 +81,12 @@ w.Write(header_frags[22])
|
||||||
w.Write(header_frags[23])
|
w.Write(header_frags[23])
|
||||||
if len(tmpl_ip_search_vars.Header.NoticeList) != 0 {
|
if len(tmpl_ip_search_vars.Header.NoticeList) != 0 {
|
||||||
for _, item := range tmpl_ip_search_vars.Header.NoticeList {
|
for _, item := range tmpl_ip_search_vars.Header.NoticeList {
|
||||||
w.Write(header_frags[24])
|
w.Write(notice_frags[0])
|
||||||
w.Write([]byte(item))
|
w.Write([]byte(item))
|
||||||
w.Write(header_frags[25])
|
w.Write(notice_frags[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Write(header_frags[26])
|
w.Write(header_frags[24])
|
||||||
w.Write(ip_search_frags[0])
|
w.Write(ip_search_frags[0])
|
||||||
w.Write(phrases[1])
|
w.Write(phrases[1])
|
||||||
w.Write(ip_search_frags[1])
|
w.Write(ip_search_frags[1])
|
||||||
|
|
108
template_list.go
108
template_list.go
|
@ -1,21 +1,102 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
var guilds_guild_list_frags = make([][]byte,10)
|
|
||||||
var forums_frags = make([][]byte,26)
|
|
||||||
var topics_frags = make([][]byte,98)
|
|
||||||
var register_frags = make([][]byte,9)
|
|
||||||
var header_frags = make([][]byte,28)
|
|
||||||
var topic_frags = make([][]byte,199)
|
|
||||||
var topic_alt_frags = make([][]byte,200)
|
|
||||||
var login_frags = make([][]byte,8)
|
|
||||||
var error_frags = make([][]byte,4)
|
var error_frags = make([][]byte,4)
|
||||||
var footer_frags = make([][]byte,13)
|
|
||||||
|
// nolint
|
||||||
|
func Get_error_frags() [][]byte {
|
||||||
|
return error_frags
|
||||||
|
}
|
||||||
var profile_comments_row_frags = make([][]byte,51)
|
var profile_comments_row_frags = make([][]byte,51)
|
||||||
var paginator_frags = make([][]byte,16)
|
|
||||||
|
// nolint
|
||||||
|
func Get_profile_comments_row_frags() [][]byte {
|
||||||
|
return profile_comments_row_frags
|
||||||
|
}
|
||||||
|
var topic_alt_frags = make([][]byte,200)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_topic_alt_frags() [][]byte {
|
||||||
|
return topic_alt_frags
|
||||||
|
}
|
||||||
var profile_frags = make([][]byte,50)
|
var profile_frags = make([][]byte,50)
|
||||||
var forum_frags = make([][]byte,90)
|
|
||||||
|
// nolint
|
||||||
|
func Get_profile_frags() [][]byte {
|
||||||
|
return profile_frags
|
||||||
|
}
|
||||||
var ip_search_frags = make([][]byte,18)
|
var ip_search_frags = make([][]byte,18)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_ip_search_frags() [][]byte {
|
||||||
|
return ip_search_frags
|
||||||
|
}
|
||||||
|
var header_frags = make([][]byte,26)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_header_frags() [][]byte {
|
||||||
|
return header_frags
|
||||||
|
}
|
||||||
|
var forums_frags = make([][]byte,26)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_forums_frags() [][]byte {
|
||||||
|
return forums_frags
|
||||||
|
}
|
||||||
|
var login_frags = make([][]byte,8)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_login_frags() [][]byte {
|
||||||
|
return login_frags
|
||||||
|
}
|
||||||
|
var register_frags = make([][]byte,9)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_register_frags() [][]byte {
|
||||||
|
return register_frags
|
||||||
|
}
|
||||||
|
var footer_frags = make([][]byte,13)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_footer_frags() [][]byte {
|
||||||
|
return footer_frags
|
||||||
|
}
|
||||||
|
var topic_frags = make([][]byte,199)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_topic_frags() [][]byte {
|
||||||
|
return topic_frags
|
||||||
|
}
|
||||||
|
var paginator_frags = make([][]byte,16)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_paginator_frags() [][]byte {
|
||||||
|
return paginator_frags
|
||||||
|
}
|
||||||
|
var topics_frags = make([][]byte,98)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_topics_frags() [][]byte {
|
||||||
|
return topics_frags
|
||||||
|
}
|
||||||
|
var forum_frags = make([][]byte,90)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_forum_frags() [][]byte {
|
||||||
|
return forum_frags
|
||||||
|
}
|
||||||
|
var guilds_guild_list_frags = make([][]byte,10)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_guilds_guild_list_frags() [][]byte {
|
||||||
|
return guilds_guild_list_frags
|
||||||
|
}
|
||||||
|
var notice_frags = make([][]byte,3)
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
func Get_notice_frags() [][]byte {
|
||||||
|
return notice_frags
|
||||||
|
}
|
||||||
|
|
||||||
// nolint
|
// nolint
|
||||||
func init() {
|
func init() {
|
||||||
header_frags[0] = []byte(`<!doctype html>
|
header_frags[0] = []byte(`<!doctype html>
|
||||||
|
@ -81,10 +162,9 @@ header_frags[21] = []byte(`</div>
|
||||||
header_frags[22] = []byte(`class="shrink_main"`)
|
header_frags[22] = []byte(`class="shrink_main"`)
|
||||||
header_frags[23] = []byte(`>
|
header_frags[23] = []byte(`>
|
||||||
<div class="alertbox">`)
|
<div class="alertbox">`)
|
||||||
|
notice_frags[0] = []byte(`<div class="alert">`)
|
||||||
|
notice_frags[1] = []byte(`</div>`)
|
||||||
header_frags[24] = []byte(`
|
header_frags[24] = []byte(`
|
||||||
<div class="alert">`)
|
|
||||||
header_frags[25] = []byte(`</div>`)
|
|
||||||
header_frags[26] = []byte(`
|
|
||||||
</div>
|
</div>
|
||||||
`)
|
`)
|
||||||
topic_frags[0] = []byte(`
|
topic_frags[0] = []byte(`
|
||||||
|
|
|
@ -84,12 +84,12 @@ w.Write(header_frags[22])
|
||||||
w.Write(header_frags[23])
|
w.Write(header_frags[23])
|
||||||
if len(tmpl_login_vars.Header.NoticeList) != 0 {
|
if len(tmpl_login_vars.Header.NoticeList) != 0 {
|
||||||
for _, item := range tmpl_login_vars.Header.NoticeList {
|
for _, item := range tmpl_login_vars.Header.NoticeList {
|
||||||
w.Write(header_frags[24])
|
w.Write(notice_frags[0])
|
||||||
w.Write([]byte(item))
|
w.Write([]byte(item))
|
||||||
w.Write(header_frags[25])
|
w.Write(notice_frags[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Write(header_frags[26])
|
w.Write(header_frags[24])
|
||||||
w.Write(login_frags[0])
|
w.Write(login_frags[0])
|
||||||
w.Write(phrases[1])
|
w.Write(phrases[1])
|
||||||
w.Write(login_frags[1])
|
w.Write(login_frags[1])
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
// Code generated by Gosora. More below:
|
// Code generated by Gosora. More below:
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||||
package main
|
package main
|
||||||
|
import "strconv"
|
||||||
import "io"
|
import "io"
|
||||||
import "./common"
|
import "./common"
|
||||||
import "strconv"
|
|
||||||
|
|
||||||
var profile_tmpl_phrase_id int
|
var profile_tmpl_phrase_id int
|
||||||
|
|
||||||
|
@ -107,12 +107,12 @@ w.Write(header_frags[22])
|
||||||
w.Write(header_frags[23])
|
w.Write(header_frags[23])
|
||||||
if len(tmpl_profile_vars.Header.NoticeList) != 0 {
|
if len(tmpl_profile_vars.Header.NoticeList) != 0 {
|
||||||
for _, item := range tmpl_profile_vars.Header.NoticeList {
|
for _, item := range tmpl_profile_vars.Header.NoticeList {
|
||||||
w.Write(header_frags[24])
|
w.Write(notice_frags[0])
|
||||||
w.Write([]byte(item))
|
w.Write([]byte(item))
|
||||||
w.Write(header_frags[25])
|
w.Write(notice_frags[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Write(header_frags[26])
|
w.Write(header_frags[24])
|
||||||
w.Write(profile_frags[0])
|
w.Write(profile_frags[0])
|
||||||
w.Write([]byte(tmpl_profile_vars.ProfileOwner.Avatar))
|
w.Write([]byte(tmpl_profile_vars.ProfileOwner.Avatar))
|
||||||
w.Write(profile_frags[1])
|
w.Write(profile_frags[1])
|
||||||
|
|
|
@ -85,12 +85,12 @@ w.Write(header_frags[22])
|
||||||
w.Write(header_frags[23])
|
w.Write(header_frags[23])
|
||||||
if len(tmpl_register_vars.Header.NoticeList) != 0 {
|
if len(tmpl_register_vars.Header.NoticeList) != 0 {
|
||||||
for _, item := range tmpl_register_vars.Header.NoticeList {
|
for _, item := range tmpl_register_vars.Header.NoticeList {
|
||||||
w.Write(header_frags[24])
|
w.Write(notice_frags[0])
|
||||||
w.Write([]byte(item))
|
w.Write([]byte(item))
|
||||||
w.Write(header_frags[25])
|
w.Write(notice_frags[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Write(header_frags[26])
|
w.Write(header_frags[24])
|
||||||
w.Write(register_frags[0])
|
w.Write(register_frags[0])
|
||||||
w.Write(phrases[1])
|
w.Write(phrases[1])
|
||||||
w.Write(register_frags[1])
|
w.Write(register_frags[1])
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
// Code generated by Gosora. More below:
|
// Code generated by Gosora. More below:
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||||
package main
|
package main
|
||||||
import "./common"
|
|
||||||
import "io"
|
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
import "io"
|
||||||
|
import "./common"
|
||||||
|
|
||||||
var topic_tmpl_phrase_id int
|
var topic_tmpl_phrase_id int
|
||||||
|
|
||||||
|
@ -138,12 +138,12 @@ w.Write(header_frags[22])
|
||||||
w.Write(header_frags[23])
|
w.Write(header_frags[23])
|
||||||
if len(tmpl_topic_vars.Header.NoticeList) != 0 {
|
if len(tmpl_topic_vars.Header.NoticeList) != 0 {
|
||||||
for _, item := range tmpl_topic_vars.Header.NoticeList {
|
for _, item := range tmpl_topic_vars.Header.NoticeList {
|
||||||
w.Write(header_frags[24])
|
w.Write(notice_frags[0])
|
||||||
w.Write([]byte(item))
|
w.Write([]byte(item))
|
||||||
w.Write(header_frags[25])
|
w.Write(notice_frags[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Write(header_frags[26])
|
w.Write(header_frags[24])
|
||||||
w.Write(topic_frags[0])
|
w.Write(topic_frags[0])
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
||||||
w.Write(topic_frags[1])
|
w.Write(topic_frags[1])
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
// Code generated by Gosora. More below:
|
// Code generated by Gosora. More below:
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||||
package main
|
package main
|
||||||
|
import "./common"
|
||||||
import "strconv"
|
import "strconv"
|
||||||
import "io"
|
import "io"
|
||||||
import "./common"
|
|
||||||
|
|
||||||
var topic_alt_tmpl_phrase_id int
|
var topic_alt_tmpl_phrase_id int
|
||||||
|
|
||||||
|
@ -125,12 +125,12 @@ w.Write(header_frags[22])
|
||||||
w.Write(header_frags[23])
|
w.Write(header_frags[23])
|
||||||
if len(tmpl_topic_alt_vars.Header.NoticeList) != 0 {
|
if len(tmpl_topic_alt_vars.Header.NoticeList) != 0 {
|
||||||
for _, item := range tmpl_topic_alt_vars.Header.NoticeList {
|
for _, item := range tmpl_topic_alt_vars.Header.NoticeList {
|
||||||
w.Write(header_frags[24])
|
w.Write(notice_frags[0])
|
||||||
w.Write([]byte(item))
|
w.Write([]byte(item))
|
||||||
w.Write(header_frags[25])
|
w.Write(notice_frags[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Write(header_frags[26])
|
w.Write(header_frags[24])
|
||||||
if tmpl_topic_alt_vars.Page > 1 {
|
if tmpl_topic_alt_vars.Page > 1 {
|
||||||
w.Write(topic_alt_frags[0])
|
w.Write(topic_alt_frags[0])
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
// Code generated by Gosora. More below:
|
// Code generated by Gosora. More below:
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||||
package main
|
package main
|
||||||
import "./common"
|
|
||||||
import "io"
|
import "io"
|
||||||
|
import "./common"
|
||||||
import "strconv"
|
import "strconv"
|
||||||
|
|
||||||
var topics_tmpl_phrase_id int
|
var topics_tmpl_phrase_id int
|
||||||
|
@ -112,12 +112,12 @@ w.Write(header_frags[22])
|
||||||
w.Write(header_frags[23])
|
w.Write(header_frags[23])
|
||||||
if len(tmpl_topics_vars.Header.NoticeList) != 0 {
|
if len(tmpl_topics_vars.Header.NoticeList) != 0 {
|
||||||
for _, item := range tmpl_topics_vars.Header.NoticeList {
|
for _, item := range tmpl_topics_vars.Header.NoticeList {
|
||||||
w.Write(header_frags[24])
|
w.Write(notice_frags[0])
|
||||||
w.Write([]byte(item))
|
w.Write([]byte(item))
|
||||||
w.Write(header_frags[25])
|
w.Write(notice_frags[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.Write(header_frags[26])
|
w.Write(header_frags[24])
|
||||||
w.Write(topics_frags[0])
|
w.Write(topics_frags[0])
|
||||||
if tmpl_topics_vars.CurrentUser.ID != 0 {
|
if tmpl_topics_vars.CurrentUser.ID != 0 {
|
||||||
w.Write(topics_frags[1])
|
w.Write(topics_frags[1])
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
{{if .Avatar}}<div class='alertItem withAvatar' style='background-image:url("{{.Avatar}}");'><a class='text' data-asid='{{.ASID}}' href="{{.Path}}">{{.Message}}</a></div>{{else}}
|
{{if .Avatar}}<div class='alertItem withAvatar' style='background-image:url("{{.Avatar}}");'><img src='{{.Avatar}}' class='bgsub' /><a class='text' data-asid='{{.ASID}}' href="{{.Path}}">{{.Message}}</a></div>{{else}}
|
||||||
<div class='alertItem'><a href="{{.Path}}" class='text'>{{.Message}}</a></div>{{end}}
|
<div class='alertItem'><a href="{{.Path}}" class='text'>{{.Message}}</a></div>{{end}}
|
|
@ -38,5 +38,5 @@
|
||||||
<div class="right_of_nav">{{dock "rightOfNav" .Header }}</div>
|
<div class="right_of_nav">{{dock "rightOfNav" .Header }}</div>
|
||||||
<div id="back"><div id="main" {{if .Header.Widgets.RightSidebar}}class="shrink_main"{{end}}>
|
<div id="back"><div id="main" {{if .Header.Widgets.RightSidebar}}class="shrink_main"{{end}}>
|
||||||
<div class="alertbox">{{range .Header.NoticeList}}
|
<div class="alertbox">{{range .Header.NoticeList}}
|
||||||
<div class="alert">{{.}}</div>{{end}}
|
{{template "notice.html" . }}{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<div class="alert">{{.}}</div>
|
|
@ -1,35 +0,0 @@
|
||||||
// +build !no_templategen
|
|
||||||
|
|
||||||
// Code generated by Gosora. More below:
|
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
|
||||||
package tmpl
|
|
||||||
import "../../common"
|
|
||||||
import "io"
|
|
||||||
import "strconv"
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func init() {
|
|
||||||
common.TmplPtrMap["o_alert"] = Template_alert
|
|
||||||
}
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func Template_alert(tmpl_alert_vars common.AlertItem, w io.Writer) error {
|
|
||||||
if tmpl_alert_vars.Avatar != "" {
|
|
||||||
w.Write(alert_frags[0])
|
|
||||||
w.Write([]byte(tmpl_alert_vars.Avatar))
|
|
||||||
w.Write(alert_frags[1])
|
|
||||||
w.Write([]byte(strconv.Itoa(tmpl_alert_vars.ASID)))
|
|
||||||
w.Write(alert_frags[2])
|
|
||||||
w.Write([]byte(tmpl_alert_vars.Path))
|
|
||||||
w.Write(alert_frags[3])
|
|
||||||
w.Write([]byte(tmpl_alert_vars.Message))
|
|
||||||
w.Write(alert_frags[4])
|
|
||||||
} else {
|
|
||||||
w.Write(alert_frags[5])
|
|
||||||
w.Write([]byte(tmpl_alert_vars.Path))
|
|
||||||
w.Write(alert_frags[6])
|
|
||||||
w.Write([]byte(tmpl_alert_vars.Message))
|
|
||||||
w.Write(alert_frags[7])
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package tmpl
|
|
||||||
|
|
||||||
var alert_frags = make([][]byte,9)
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func init() {
|
|
||||||
alert_frags[0] = []byte(`<div class='alertItem withAvatar' style='background-image:url("`)
|
|
||||||
alert_frags[1] = []byte(`");'><a class='text' data-asid='`)
|
|
||||||
alert_frags[2] = []byte(`' href="`)
|
|
||||||
alert_frags[3] = []byte(`">`)
|
|
||||||
alert_frags[4] = []byte(`</a></div>`)
|
|
||||||
alert_frags[5] = []byte(`
|
|
||||||
<div class='alertItem'><a href="`)
|
|
||||||
alert_frags[6] = []byte(`" class='text'>`)
|
|
||||||
alert_frags[7] = []byte(`</a></div>`)
|
|
||||||
}
|
|
Loading…
Reference in New Issue