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"
|
||||
|
||||
"../common"
|
||||
"../tmpl_gen/client"
|
||||
"../common/alerts"
|
||||
"../tmpl_gen"
|
||||
"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 {
|
||||
var buf bytes.Buffer
|
||||
alertItem := common.AlertItem{asid, path, msg, avatar}
|
||||
alertItem := alerts.AlertItem{asid, path, msg, avatar}
|
||||
err := tmpl.Template_alert(alertItem, &buf)
|
||||
if err != nil {
|
||||
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
|
||||
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)
|
||||
cookie = http.Cookie{Name: "session", Value: "", Path: "/", MaxAge: Year}
|
||||
cookie = http.Cookie{Name: "session", Value: "", Path: "/", MaxAge: int(Year)}
|
||||
http.SetCookie(w, &cookie)
|
||||
}
|
||||
|
||||
// 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
|
||||
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)
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -8,16 +8,16 @@ import (
|
|||
)
|
||||
|
||||
// nolint I don't want to write comments for each of these o.o
|
||||
const Hour int = 60 * 60
|
||||
const Day int = Hour * 24
|
||||
const Week int = Day * 7
|
||||
const Month int = Day * 30
|
||||
const Year int = Day * 365
|
||||
const Kilobyte int = 1024
|
||||
const Megabyte int = Kilobyte * 1024
|
||||
const Gigabyte int = Megabyte * 1024
|
||||
const Terabyte int = Gigabyte * 1024
|
||||
const Petabyte int = Terabyte * 1024
|
||||
const Hour int64 = 60 * 60
|
||||
const Day int64 = Hour * 24
|
||||
const Week int64 = Day * 7
|
||||
const Month int64 = Day * 30
|
||||
const Year int64 = Day * 365
|
||||
const Kilobyte int64 = 1024
|
||||
const Megabyte int64 = Kilobyte * 1024
|
||||
const Gigabyte int64 = Megabyte * 1024
|
||||
const Terabyte int64 = Gigabyte * 1024
|
||||
const Petabyte int64 = Terabyte * 1024
|
||||
|
||||
const SaltLength int = 32
|
||||
const SessionLength int = 80
|
||||
|
|
151
common/files.go
151
common/files.go
|
@ -2,6 +2,8 @@ package common
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"mime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -11,6 +13,8 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"../tmpl_gen"
|
||||
)
|
||||
|
||||
type SFileList map[string]SFile
|
||||
|
@ -33,6 +37,153 @@ type CSSData struct {
|
|||
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 {
|
||||
return filepath.Walk("./public", func(path string, f os.FileInfo, err error) error {
|
||||
if f.IsDir() {
|
||||
|
|
|
@ -168,6 +168,13 @@ func nextCharIs(tmplData []byte, i int, expects byte) bool {
|
|||
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) {
|
||||
j := i
|
||||
for ; j < len(tmplData); j++ {
|
||||
|
@ -182,14 +189,47 @@ func skipUntilCharsExist(tmplData []byte, i int, expects []byte) (newI int, hasI
|
|||
j := i
|
||||
expectIndex := 0
|
||||
for ; j < len(tmplData) && expectIndex < len(expects); j++ {
|
||||
//fmt.Println("tmplData[j]: ", string(tmplData[j]))
|
||||
if tmplData[j] != expects[expectIndex] {
|
||||
return j, false
|
||||
}
|
||||
//fmt.Printf("found %+v at %d\n", string(expects[expectIndex]), expectIndex)
|
||||
expectIndex++
|
||||
}
|
||||
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 int // 0: text, 1: variable
|
||||
Index int
|
||||
|
|
|
@ -59,13 +59,6 @@ type ExtData struct {
|
|||
sync.RWMutex
|
||||
}
|
||||
|
||||
type AlertItem struct {
|
||||
ASID int
|
||||
Path string
|
||||
Message string
|
||||
Avatar string
|
||||
}
|
||||
|
||||
type Page struct {
|
||||
Title string
|
||||
CurrentUser User
|
||||
|
|
|
@ -100,7 +100,6 @@ func InitPhrases() error {
|
|||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -20,8 +20,7 @@ type SQLProfileReplyStore struct {
|
|||
create *sql.Stmt
|
||||
}
|
||||
|
||||
func NewSQLProfileReplyStore() (*SQLProfileReplyStore, error) {
|
||||
acc := qgen.Builder.Accumulator()
|
||||
func NewSQLProfileReplyStore(acc *qgen.Accumulator) (*SQLProfileReplyStore, error) {
|
||||
return &SQLProfileReplyStore{
|
||||
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(),
|
||||
|
|
|
@ -15,8 +15,7 @@ type SQLReplyStore struct {
|
|||
create *sql.Stmt
|
||||
}
|
||||
|
||||
func NewSQLReplyStore() (*SQLReplyStore, error) {
|
||||
acc := qgen.Builder.Accumulator()
|
||||
func NewSQLReplyStore(acc *qgen.Accumulator) (*SQLReplyStore, error) {
|
||||
return &SQLReplyStore{
|
||||
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(),
|
||||
|
|
|
@ -52,7 +52,7 @@ type config struct {
|
|||
SslPrivkey string
|
||||
SslFullchain string
|
||||
|
||||
MaxRequestSize int
|
||||
MaxRequestSize int64
|
||||
CacheTopicUser int
|
||||
UserCacheCapacity int
|
||||
TopicCacheCapacity int
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"./alerts"
|
||||
"./templates"
|
||||
)
|
||||
|
||||
|
@ -297,24 +298,25 @@ func CompileJSTemplates() error {
|
|||
config.Minify = Config.MinifyTemplates
|
||||
config.SuperDebug = Dev.TemplateDebug
|
||||
config.SkipHandles = true
|
||||
config.SkipInitBlock = true
|
||||
config.PackageName = "tmpl"
|
||||
|
||||
c := tmpl.NewCTemplateSet()
|
||||
c.SetConfig(config)
|
||||
c.SetBaseImportMap(map[string]string{
|
||||
"io": "io",
|
||||
"../../common": "../../common",
|
||||
"../common/alerts": "../common/alerts",
|
||||
})
|
||||
var varList = make(map[string]tmpl.VarItem)
|
||||
|
||||
// TODO: Check what sort of path is sent exactly and use it here
|
||||
alertItem := AlertItem{Avatar: "", ASID: 1, Path: "/", Message: "uh oh, something happened"}
|
||||
alertTmpl, err := c.Compile("alert.html", "templates/", "common.AlertItem", alertItem, varList)
|
||||
alertItem := alerts.AlertItem{Avatar: "", ASID: 1, Path: "/", Message: "uh oh, something happened"}
|
||||
alertTmpl, err := c.Compile("alert.html", "templates/", "alerts.AlertItem", alertItem, varList)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var dirPrefix = "./tmpl_gen/client/"
|
||||
var dirPrefix = "./tmpl_gen/"
|
||||
var wg sync.WaitGroup
|
||||
var writeTemplate = func(name string, content string) {
|
||||
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"
|
||||
for templateName, count := range c.TemplateFragmentCount {
|
||||
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"
|
||||
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 {
|
||||
fmt.Println("Compiling template '" + name + "'")
|
||||
}
|
||||
|
||||
c.importMap = map[string]string{}
|
||||
for index, item := range c.baseImportMap {
|
||||
c.importMap[index] = item
|
||||
|
@ -135,7 +134,6 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe
|
|||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
content := string(res)
|
||||
if c.config.Minify {
|
||||
content = minify(content)
|
||||
|
@ -149,7 +147,6 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe
|
|||
}
|
||||
c.detail(name)
|
||||
|
||||
out = ""
|
||||
fname := strings.TrimSuffix(name, filepath.Ext(name))
|
||||
c.templateList = map[string]*parse.Tree{fname: tree}
|
||||
varholder := "tmpl_" + fname + "_vars"
|
||||
|
@ -212,7 +209,7 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe
|
|||
if len(c.langIndexToName) > 0 {
|
||||
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, `))
|
||||
w.Write([]byte(`, " + ", -1)
|
||||
|
@ -278,7 +275,6 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value
|
|||
c.detail("Selected Branch 1")
|
||||
return out + "\n"
|
||||
}
|
||||
|
||||
c.detail("Selected Branch 2")
|
||||
return out + " else {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.ElseList) + "}\n"
|
||||
case *parse.ListNode:
|
||||
|
@ -947,7 +943,6 @@ func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflec
|
|||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
content := string(res)
|
||||
if c.config.Minify {
|
||||
content = minify(content)
|
||||
|
|
|
@ -148,10 +148,11 @@ func ConvertByteInUnit(bytes float64, unit string) (count float64) {
|
|||
}
|
||||
|
||||
// TODO: Write a test for this
|
||||
// TODO: Re-add T as int64
|
||||
func ConvertUnit(num int) (int, string) {
|
||||
switch {
|
||||
case num >= 1000000000000:
|
||||
return num / 1000000000000, "T"
|
||||
//case num >= 1000000000000:
|
||||
// return num / 1000000000000, "T"
|
||||
case num >= 1000000000:
|
||||
return num / 1000000000, "B"
|
||||
case num >= 1000000:
|
||||
|
@ -164,12 +165,14 @@ func ConvertUnit(num int) (int, string) {
|
|||
}
|
||||
|
||||
// TODO: Write a test for this
|
||||
// TODO: Re-add quadrillion as int64
|
||||
// TODO: Re-add trillion as int64
|
||||
func ConvertFriendlyUnit(num int) (int, string) {
|
||||
switch {
|
||||
case num >= 1000000000000000:
|
||||
return 0, " quadrillion"
|
||||
case num >= 1000000000000:
|
||||
return 0, " trillion"
|
||||
//case num >= 1000000000000000:
|
||||
// return 0, " quadrillion"
|
||||
//case num >= 1000000000000:
|
||||
// return 0, " trillion"
|
||||
case num >= 1000000000:
|
||||
return num / 1000000000, " billion"
|
||||
case num >= 1000000:
|
||||
|
|
|
@ -9,7 +9,6 @@ import "./common"
|
|||
|
||||
// nolint
|
||||
type Stmts struct {
|
||||
getPassword *sql.Stmt
|
||||
isPluginActive *sql.Stmt
|
||||
getUsersOffset *sql.Stmt
|
||||
isThemeDefault *sql.Stmt
|
||||
|
@ -59,14 +58,6 @@ type Stmts struct {
|
|||
func _gen_mssql() (err error) {
|
||||
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.")
|
||||
stmts.isPluginActive, err = db.Prepare("SELECT [active] FROM [plugins] WHERE [uname] = ?1")
|
||||
if err != nil {
|
||||
|
|
|
@ -11,7 +11,6 @@ import "./common"
|
|||
|
||||
// nolint
|
||||
type Stmts struct {
|
||||
getPassword *sql.Stmt
|
||||
isPluginActive *sql.Stmt
|
||||
getUsersOffset *sql.Stmt
|
||||
isThemeDefault *sql.Stmt
|
||||
|
@ -61,13 +60,6 @@ type Stmts struct {
|
|||
func _gen_mysql() (err error) {
|
||||
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.")
|
||||
stmts.isPluginActive, err = db.Prepare("SELECT `active` FROM `plugins` WHERE `uname` = ?")
|
||||
if err != nil {
|
||||
|
|
|
@ -89,11 +89,11 @@ var RouteMap = map[string]interface{}{
|
|||
"routePanelDebug": routePanelDebug,
|
||||
"routePanelDashboard": routePanelDashboard,
|
||||
"routes.AccountEditCritical": routes.AccountEditCritical,
|
||||
"routeAccountEditCriticalSubmit": routeAccountEditCriticalSubmit,
|
||||
"routeAccountEditAvatar": routeAccountEditAvatar,
|
||||
"routeAccountEditAvatarSubmit": routeAccountEditAvatarSubmit,
|
||||
"routeAccountEditUsername": routeAccountEditUsername,
|
||||
"routeAccountEditUsernameSubmit": routeAccountEditUsernameSubmit,
|
||||
"routes.AccountEditCriticalSubmit": routes.AccountEditCriticalSubmit,
|
||||
"routes.AccountEditAvatar": routes.AccountEditAvatar,
|
||||
"routes.AccountEditAvatarSubmit": routes.AccountEditAvatarSubmit,
|
||||
"routes.AccountEditUsername": routes.AccountEditUsername,
|
||||
"routes.AccountEditUsernameSubmit": routes.AccountEditUsernameSubmit,
|
||||
"routeAccountEditEmail": routeAccountEditEmail,
|
||||
"routeAccountEditEmailTokenSubmit": routeAccountEditEmailTokenSubmit,
|
||||
"routes.ViewProfile": routes.ViewProfile,
|
||||
|
@ -205,11 +205,11 @@ var routeMapEnum = map[string]int{
|
|||
"routePanelDebug": 67,
|
||||
"routePanelDashboard": 68,
|
||||
"routes.AccountEditCritical": 69,
|
||||
"routeAccountEditCriticalSubmit": 70,
|
||||
"routeAccountEditAvatar": 71,
|
||||
"routeAccountEditAvatarSubmit": 72,
|
||||
"routeAccountEditUsername": 73,
|
||||
"routeAccountEditUsernameSubmit": 74,
|
||||
"routes.AccountEditCriticalSubmit": 70,
|
||||
"routes.AccountEditAvatar": 71,
|
||||
"routes.AccountEditAvatarSubmit": 72,
|
||||
"routes.AccountEditUsername": 73,
|
||||
"routes.AccountEditUsernameSubmit": 74,
|
||||
"routeAccountEditEmail": 75,
|
||||
"routeAccountEditEmailTokenSubmit": 76,
|
||||
"routes.ViewProfile": 77,
|
||||
|
@ -319,11 +319,11 @@ var reverseRouteMapEnum = map[int]string{
|
|||
67: "routePanelDebug",
|
||||
68: "routePanelDashboard",
|
||||
69: "routes.AccountEditCritical",
|
||||
70: "routeAccountEditCriticalSubmit",
|
||||
71: "routeAccountEditAvatar",
|
||||
72: "routeAccountEditAvatarSubmit",
|
||||
73: "routeAccountEditUsername",
|
||||
74: "routeAccountEditUsernameSubmit",
|
||||
70: "routes.AccountEditCriticalSubmit",
|
||||
71: "routes.AccountEditAvatar",
|
||||
72: "routes.AccountEditAvatarSubmit",
|
||||
73: "routes.AccountEditUsername",
|
||||
74: "routes.AccountEditUsernameSubmit",
|
||||
75: "routeAccountEditEmail",
|
||||
76: "routeAccountEditEmailTokenSubmit",
|
||||
77: "routes.ViewProfile",
|
||||
|
@ -529,7 +529,7 @@ func NewGenRouter(uploads http.Handler) (*GenRouter, error) {
|
|||
writ := NewWriterIntercept(w)
|
||||
http.StripPrefix("/uploads/",uploads).ServeHTTP(writ,req)
|
||||
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")
|
||||
}
|
||||
},
|
||||
|
@ -1337,7 +1337,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
counters.RouteViewCounter.Bump(70)
|
||||
err = routeAccountEditCriticalSubmit(w,req,user)
|
||||
err = routes.AccountEditCriticalSubmit(w,req,user)
|
||||
case "/user/edit/avatar/":
|
||||
err = common.MemberOnly(w,req,user)
|
||||
if err != nil {
|
||||
|
@ -1346,7 +1346,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
counters.RouteViewCounter.Bump(71)
|
||||
err = routeAccountEditAvatar(w,req,user)
|
||||
err = routes.AccountEditAvatar(w,req,user)
|
||||
case "/user/edit/avatar/submit/":
|
||||
err = common.MemberOnly(w,req,user)
|
||||
if err != nil {
|
||||
|
@ -1354,7 +1354,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
err = common.HandleUploadRoute(w,req,user,common.Config.MaxRequestSize)
|
||||
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
|
||||
if err != nil {
|
||||
router.handleError(err,w,req,user)
|
||||
return
|
||||
|
@ -1366,7 +1366,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
counters.RouteViewCounter.Bump(72)
|
||||
err = routeAccountEditAvatarSubmit(w,req,user)
|
||||
err = routes.AccountEditAvatarSubmit(w,req,user)
|
||||
case "/user/edit/username/":
|
||||
err = common.MemberOnly(w,req,user)
|
||||
if err != nil {
|
||||
|
@ -1375,7 +1375,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
counters.RouteViewCounter.Bump(73)
|
||||
err = routeAccountEditUsername(w,req,user)
|
||||
err = routes.AccountEditUsername(w,req,user)
|
||||
case "/user/edit/username/submit/":
|
||||
err = common.NoSessionMismatch(w,req,user)
|
||||
if err != nil {
|
||||
|
@ -1390,7 +1390,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
counters.RouteViewCounter.Bump(74)
|
||||
err = routeAccountEditUsernameSubmit(w,req,user)
|
||||
err = routes.AccountEditUsernameSubmit(w,req,user)
|
||||
case "/user/edit/email/":
|
||||
err = common.MemberOnly(w,req,user)
|
||||
if err != nil {
|
||||
|
@ -1492,7 +1492,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
err = common.HandleUploadRoute(w,req,user,common.Config.MaxRequestSize)
|
||||
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
|
||||
if err != nil {
|
||||
router.handleError(err,w,req,user)
|
||||
return
|
||||
|
@ -1649,7 +1649,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
err = common.HandleUploadRoute(w,req,user,common.Config.MaxRequestSize)
|
||||
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
|
||||
if err != nil {
|
||||
router.handleError(err,w,req,user)
|
||||
return
|
||||
|
|
10
main.go
10
main.go
|
@ -22,6 +22,7 @@ import (
|
|||
"./common"
|
||||
"./common/counters"
|
||||
"./config"
|
||||
"./query_gen/lib"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
)
|
||||
|
||||
|
@ -38,11 +39,12 @@ type Globs struct {
|
|||
}
|
||||
|
||||
func afterDBInit() (err error) {
|
||||
common.Rstore, err = common.NewSQLReplyStore()
|
||||
acc := qgen.Builder.Accumulator()
|
||||
common.Rstore, err = common.NewSQLReplyStore(acc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
common.Prstore, err = common.NewSQLProfileReplyStore()
|
||||
common.Prstore, err = common.NewSQLProfileReplyStore(acc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -65,6 +67,10 @@ func afterDBInit() (err error) {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = common.StaticFiles.JSTmplInit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Initialising the widgets")
|
||||
err = common.InitWidgets()
|
||||
|
|
177
member_routes.go
177
member_routes.go
|
@ -1,12 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"html"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -258,179 +254,6 @@ func routeReportSubmit(w http.ResponseWriter, r *http.Request, user common.User,
|
|||
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 {
|
||||
headerVars, ferr := common.UserCheck(w, r, &user)
|
||||
if ferr != nil {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
|
||||
"../common"
|
||||
"../config"
|
||||
|
@ -85,10 +86,19 @@ func patcher(scanner *bufio.Scanner) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = schemaFile
|
||||
dbVersion, err := strconv.Atoi(schemaFile.DBVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -120,5 +120,35 @@ func patch0(scanner *bufio.Scanner) (err 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
|
||||
}
|
||||
|
|
|
@ -49,9 +49,12 @@ function bindToAlerts() {
|
|||
});
|
||||
}
|
||||
|
||||
var alertsInitted = false;
|
||||
// TODO: Add the ability for users to dismiss alerts
|
||||
function loadAlerts(menuAlerts)
|
||||
{
|
||||
if(!alertsInitted) return;
|
||||
|
||||
var alertListNode = menuAlerts.getElementsByClassName("alertList")[0];
|
||||
var alertCounterNode = menuAlerts.getElementsByClassName("alert_counter")[0];
|
||||
alertCounterNode.textContent = "0";
|
||||
|
@ -59,7 +62,7 @@ function loadAlerts(menuAlerts)
|
|||
type: 'get',
|
||||
dataType: 'json',
|
||||
url:'/api/?action=get&module=alerts',
|
||||
success: function(data) {
|
||||
success: (data) => {
|
||||
if("errmsg" in data) {
|
||||
alertListNode.innerHTML = "<div class='alertItem'>"+data.errmsg+"</div>";
|
||||
return;
|
||||
|
@ -76,14 +79,12 @@ function loadAlerts(menuAlerts)
|
|||
//console.log("Sub #" + i + ":",msg.sub[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if("avatar" in msg) {
|
||||
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>";
|
||||
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>");
|
||||
} else {
|
||||
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>");
|
||||
}
|
||||
alist += Template_alert({
|
||||
ASID: msg.asid || 0,
|
||||
Path: msg.path,
|
||||
Avatar: msg.avatar || "",
|
||||
Message: mmsg
|
||||
})
|
||||
//console.log(msg);
|
||||
//console.log(mmsg);
|
||||
}
|
||||
|
@ -101,7 +102,7 @@ function loadAlerts(menuAlerts)
|
|||
|
||||
bindToAlerts();
|
||||
},
|
||||
error: function(magic,theStatus,error) {
|
||||
error: (magic,theStatus,error) => {
|
||||
let errtxt
|
||||
try {
|
||||
var data = JSON.parse(magic.responseText);
|
||||
|
@ -218,6 +219,14 @@ function runWebSockets() {
|
|||
|
||||
$(document).ready(function(){
|
||||
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();
|
||||
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) {
|
||||
event.stopPropagation();
|
||||
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()
|
||||
}
|
||||
|
||||
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
|
||||
func (selectItem *AccSelectBuilder) Each(handle func(*sql.Rows) error) error {
|
||||
rows, err := selectItem.Query()
|
||||
|
|
|
@ -257,8 +257,6 @@ func writeSelects(adapter qgen.Adapter) error {
|
|||
|
||||
// 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("isPluginInstalled").Table("plugins").Columns("installed").Where("uname = ?").Parse()
|
||||
|
|
|
@ -348,7 +348,7 @@ func NewGenRouter(uploads http.Handler) (*GenRouter, error) {
|
|||
writ := NewWriterIntercept(w)
|
||||
http.StripPrefix("/uploads/",uploads).ServeHTTP(writ,req)
|
||||
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")
|
||||
}
|
||||
},
|
||||
|
|
|
@ -41,11 +41,11 @@ func buildUserRoutes() {
|
|||
userGroup.Routes(
|
||||
View("routes.ViewProfile", "/user/").LitBefore("req.URL.Path += extraData"),
|
||||
MemberView("routes.AccountEditCritical", "/user/edit/critical/"),
|
||||
Action("routeAccountEditCriticalSubmit", "/user/edit/critical/submit/"), // TODO: Full test this
|
||||
MemberView("routeAccountEditAvatar", "/user/edit/avatar/"),
|
||||
UploadAction("routeAccountEditAvatarSubmit", "/user/edit/avatar/submit/").MaxSizeVar("common.Config.MaxRequestSize"),
|
||||
MemberView("routeAccountEditUsername", "/user/edit/username/"),
|
||||
Action("routeAccountEditUsernameSubmit", "/user/edit/username/submit/"), // TODO: Full test this
|
||||
Action("routes.AccountEditCriticalSubmit", "/user/edit/critical/submit/"), // TODO: Full test this
|
||||
MemberView("routes.AccountEditAvatar", "/user/edit/avatar/"),
|
||||
UploadAction("routes.AccountEditAvatarSubmit", "/user/edit/avatar/submit/").MaxSizeVar("int(common.Config.MaxRequestSize)"),
|
||||
MemberView("routes.AccountEditUsername", "/user/edit/username/"),
|
||||
Action("routes.AccountEditUsernameSubmit", "/user/edit/username/submit/"), // TODO: Full test this
|
||||
MemberView("routeAccountEditEmail", "/user/edit/email/"),
|
||||
Action("routeAccountEditEmailTokenSubmit", "/user/edit/token/", "extraData"),
|
||||
)
|
||||
|
@ -66,7 +66,7 @@ func buildTopicRoutes() {
|
|||
topicGroup := newRouteGroup("/topic/")
|
||||
topicGroup.Routes(
|
||||
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.DeleteTopicSubmit", "/topic/delete/submit/").LitBefore("req.URL.Path += extraData"),
|
||||
Action("routes.StickTopicSubmit", "/topic/stick/submit/", "extraData"),
|
||||
|
@ -85,7 +85,7 @@ func buildReplyRoutes() {
|
|||
replyGroup := newRouteGroup("/reply/")
|
||||
replyGroup.Routes(
|
||||
// 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.ReplyDeleteSubmit", "/reply/delete/submit/", "extraData"),
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
if !isJs {
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package routes
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"html"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -184,3 +188,172 @@ func AccountEditCritical(w http.ResponseWriter, r *http.Request, user common.Use
|
|||
}
|
||||
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"
|
||||
)
|
||||
|
||||
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
|
||||
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")
|
||||
} else {
|
||||
var seconds int
|
||||
seconds += durationDays * common.Day
|
||||
seconds += durationWeeks * common.Week
|
||||
seconds += durationMonths * common.Month
|
||||
seconds += durationDays * int(common.Day)
|
||||
seconds += durationWeeks * int(common.Week)
|
||||
seconds += durationMonths * int(common.Month)
|
||||
duration, _ = time.ParseDuration(strconv.Itoa(seconds) + "s")
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"DBVersion":"1",
|
||||
"DBVersion":"2",
|
||||
"DynamicFileVersion":"0",
|
||||
"MinGoVersion":"1.10",
|
||||
"MinVersion":""
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
// 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 main
|
||||
import "./common"
|
||||
import "io"
|
||||
import "./common"
|
||||
|
||||
var error_tmpl_phrase_id int
|
||||
|
||||
|
@ -79,12 +79,12 @@ w.Write(header_frags[22])
|
|||
w.Write(header_frags[23])
|
||||
if len(tmpl_error_vars.Header.NoticeList) != 0 {
|
||||
for _, item := range tmpl_error_vars.Header.NoticeList {
|
||||
w.Write(header_frags[24])
|
||||
w.Write(notice_frags[0])
|
||||
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(phrases[1])
|
||||
w.Write(error_frags[1])
|
||||
|
@ -117,5 +117,5 @@ w.Write(footer_frags[9])
|
|||
w.Write(footer_frags[10])
|
||||
w.Write([]byte(common.BuildWidget("rightSidebar",tmpl_error_vars.Header)))
|
||||
w.Write(footer_frags[11])
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
// 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 main
|
||||
import "./common"
|
||||
import "io"
|
||||
import "strconv"
|
||||
import "io"
|
||||
import "./common"
|
||||
|
||||
var forum_tmpl_phrase_id int
|
||||
|
||||
|
@ -112,12 +112,12 @@ w.Write(header_frags[22])
|
|||
w.Write(header_frags[23])
|
||||
if len(tmpl_forum_vars.Header.NoticeList) != 0 {
|
||||
for _, item := range tmpl_forum_vars.Header.NoticeList {
|
||||
w.Write(header_frags[24])
|
||||
w.Write(notice_frags[0])
|
||||
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 {
|
||||
w.Write(forum_frags[0])
|
||||
w.Write(phrases[1])
|
||||
|
@ -366,5 +366,5 @@ w.Write(footer_frags[9])
|
|||
w.Write(footer_frags[10])
|
||||
w.Write([]byte(common.BuildWidget("rightSidebar",tmpl_forum_vars.Header)))
|
||||
w.Write(footer_frags[11])
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -82,12 +82,12 @@ w.Write(header_frags[22])
|
|||
w.Write(header_frags[23])
|
||||
if len(tmpl_forums_vars.Header.NoticeList) != 0 {
|
||||
for _, item := range tmpl_forums_vars.Header.NoticeList {
|
||||
w.Write(header_frags[24])
|
||||
w.Write(notice_frags[0])
|
||||
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(phrases[1])
|
||||
w.Write(forums_frags[1])
|
||||
|
@ -170,5 +170,5 @@ w.Write(footer_frags[9])
|
|||
w.Write(footer_frags[10])
|
||||
w.Write([]byte(common.BuildWidget("rightSidebar",tmpl_forums_vars.Header)))
|
||||
w.Write(footer_frags[11])
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -77,12 +77,12 @@ w.Write(header_frags[22])
|
|||
w.Write(header_frags[23])
|
||||
if len(tmpl_guilds_guild_list_vars.Header.NoticeList) != 0 {
|
||||
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(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])
|
||||
if len(tmpl_guilds_guild_list_vars.GuildList) != 0 {
|
||||
for _, item := range tmpl_guilds_guild_list_vars.GuildList {
|
||||
|
@ -129,5 +129,5 @@ w.Write(footer_frags[9])
|
|||
w.Write(footer_frags[10])
|
||||
w.Write([]byte(common.BuildWidget("rightSidebar",tmpl_guilds_guild_list_vars.Header)))
|
||||
w.Write(footer_frags[11])
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
// 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 main
|
||||
import "./common"
|
||||
import "io"
|
||||
import "./common"
|
||||
|
||||
var ip_search_tmpl_phrase_id int
|
||||
|
||||
|
@ -81,12 +81,12 @@ w.Write(header_frags[22])
|
|||
w.Write(header_frags[23])
|
||||
if len(tmpl_ip_search_vars.Header.NoticeList) != 0 {
|
||||
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(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(phrases[1])
|
||||
w.Write(ip_search_frags[1])
|
||||
|
@ -150,5 +150,5 @@ w.Write(footer_frags[9])
|
|||
w.Write(footer_frags[10])
|
||||
w.Write([]byte(common.BuildWidget("rightSidebar",tmpl_ip_search_vars.Header)))
|
||||
w.Write(footer_frags[11])
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
108
template_list.go
108
template_list.go
|
@ -1,21 +1,102 @@
|
|||
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 footer_frags = make([][]byte,13)
|
||||
|
||||
// nolint
|
||||
func Get_error_frags() [][]byte {
|
||||
return error_frags
|
||||
}
|
||||
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 forum_frags = make([][]byte,90)
|
||||
|
||||
// nolint
|
||||
func Get_profile_frags() [][]byte {
|
||||
return profile_frags
|
||||
}
|
||||
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
|
||||
func init() {
|
||||
header_frags[0] = []byte(`<!doctype html>
|
||||
|
@ -81,10 +162,9 @@ header_frags[21] = []byte(`</div>
|
|||
header_frags[22] = []byte(`class="shrink_main"`)
|
||||
header_frags[23] = []byte(`>
|
||||
<div class="alertbox">`)
|
||||
notice_frags[0] = []byte(`<div class="alert">`)
|
||||
notice_frags[1] = []byte(`</div>`)
|
||||
header_frags[24] = []byte(`
|
||||
<div class="alert">`)
|
||||
header_frags[25] = []byte(`</div>`)
|
||||
header_frags[26] = []byte(`
|
||||
</div>
|
||||
`)
|
||||
topic_frags[0] = []byte(`
|
||||
|
|
|
@ -84,12 +84,12 @@ w.Write(header_frags[22])
|
|||
w.Write(header_frags[23])
|
||||
if len(tmpl_login_vars.Header.NoticeList) != 0 {
|
||||
for _, item := range tmpl_login_vars.Header.NoticeList {
|
||||
w.Write(header_frags[24])
|
||||
w.Write(notice_frags[0])
|
||||
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(phrases[1])
|
||||
w.Write(login_frags[1])
|
||||
|
@ -130,5 +130,5 @@ w.Write(footer_frags[9])
|
|||
w.Write(footer_frags[10])
|
||||
w.Write([]byte(common.BuildWidget("rightSidebar",tmpl_login_vars.Header)))
|
||||
w.Write(footer_frags[11])
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
// 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 main
|
||||
import "strconv"
|
||||
import "io"
|
||||
import "./common"
|
||||
import "strconv"
|
||||
|
||||
var profile_tmpl_phrase_id int
|
||||
|
||||
|
@ -107,12 +107,12 @@ w.Write(header_frags[22])
|
|||
w.Write(header_frags[23])
|
||||
if len(tmpl_profile_vars.Header.NoticeList) != 0 {
|
||||
for _, item := range tmpl_profile_vars.Header.NoticeList {
|
||||
w.Write(header_frags[24])
|
||||
w.Write(notice_frags[0])
|
||||
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([]byte(tmpl_profile_vars.ProfileOwner.Avatar))
|
||||
w.Write(profile_frags[1])
|
||||
|
@ -343,5 +343,5 @@ w.Write(footer_frags[9])
|
|||
w.Write(footer_frags[10])
|
||||
w.Write([]byte(common.BuildWidget("rightSidebar",tmpl_profile_vars.Header)))
|
||||
w.Write(footer_frags[11])
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -85,12 +85,12 @@ w.Write(header_frags[22])
|
|||
w.Write(header_frags[23])
|
||||
if len(tmpl_register_vars.Header.NoticeList) != 0 {
|
||||
for _, item := range tmpl_register_vars.Header.NoticeList {
|
||||
w.Write(header_frags[24])
|
||||
w.Write(notice_frags[0])
|
||||
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(phrases[1])
|
||||
w.Write(register_frags[1])
|
||||
|
@ -133,5 +133,5 @@ w.Write(footer_frags[9])
|
|||
w.Write(footer_frags[10])
|
||||
w.Write([]byte(common.BuildWidget("rightSidebar",tmpl_register_vars.Header)))
|
||||
w.Write(footer_frags[11])
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
// 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 main
|
||||
import "./common"
|
||||
import "io"
|
||||
import "strconv"
|
||||
import "io"
|
||||
import "./common"
|
||||
|
||||
var topic_tmpl_phrase_id int
|
||||
|
||||
|
@ -138,12 +138,12 @@ w.Write(header_frags[22])
|
|||
w.Write(header_frags[23])
|
||||
if len(tmpl_topic_vars.Header.NoticeList) != 0 {
|
||||
for _, item := range tmpl_topic_vars.Header.NoticeList {
|
||||
w.Write(header_frags[24])
|
||||
w.Write(notice_frags[0])
|
||||
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([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
|
||||
w.Write(topic_frags[1])
|
||||
|
@ -586,5 +586,5 @@ w.Write(footer_frags[9])
|
|||
w.Write(footer_frags[10])
|
||||
w.Write([]byte(common.BuildWidget("rightSidebar",tmpl_topic_vars.Header)))
|
||||
w.Write(footer_frags[11])
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
// 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 main
|
||||
import "./common"
|
||||
import "strconv"
|
||||
import "io"
|
||||
import "./common"
|
||||
|
||||
var topic_alt_tmpl_phrase_id int
|
||||
|
||||
|
@ -125,12 +125,12 @@ w.Write(header_frags[22])
|
|||
w.Write(header_frags[23])
|
||||
if len(tmpl_topic_alt_vars.Header.NoticeList) != 0 {
|
||||
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(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 {
|
||||
w.Write(topic_alt_frags[0])
|
||||
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
|
||||
|
@ -579,5 +579,5 @@ w.Write(footer_frags[9])
|
|||
w.Write(footer_frags[10])
|
||||
w.Write([]byte(common.BuildWidget("rightSidebar",tmpl_topic_alt_vars.Header)))
|
||||
w.Write(footer_frags[11])
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
// 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 main
|
||||
import "./common"
|
||||
import "io"
|
||||
import "./common"
|
||||
import "strconv"
|
||||
|
||||
var topics_tmpl_phrase_id int
|
||||
|
@ -112,12 +112,12 @@ w.Write(header_frags[22])
|
|||
w.Write(header_frags[23])
|
||||
if len(tmpl_topics_vars.Header.NoticeList) != 0 {
|
||||
for _, item := range tmpl_topics_vars.Header.NoticeList {
|
||||
w.Write(header_frags[24])
|
||||
w.Write(notice_frags[0])
|
||||
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])
|
||||
if tmpl_topics_vars.CurrentUser.ID != 0 {
|
||||
w.Write(topics_frags[1])
|
||||
|
@ -384,5 +384,5 @@ w.Write(footer_frags[9])
|
|||
w.Write(footer_frags[10])
|
||||
w.Write([]byte(common.BuildWidget("rightSidebar",tmpl_topics_vars.Header)))
|
||||
w.Write(footer_frags[11])
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -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}}
|
|
@ -38,5 +38,5 @@
|
|||
<div class="right_of_nav">{{dock "rightOfNav" .Header }}</div>
|
||||
<div id="back"><div id="main" {{if .Header.Widgets.RightSidebar}}class="shrink_main"{{end}}>
|
||||
<div class="alertbox">{{range .Header.NoticeList}}
|
||||
<div class="alert">{{.}}</div>{{end}}
|
||||
{{template "notice.html" . }}{{end}}
|
||||
</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