Use json marshal for the group permissions in querygen.

Add an omitempty json tag to the Perms struct.
Take the opportunity to shorten some things.
This commit is contained in:
Azareal 2019-10-06 15:32:08 +10:00
parent 8d40139ae5
commit 45a3065db1
9 changed files with 174 additions and 151 deletions

View File

@ -2,12 +2,14 @@
package main // import "github.com/Azareal/Gosora/query_gen" package main // import "github.com/Azareal/Gosora/query_gen"
import ( import (
"encoding/json"
"fmt" "fmt"
"log" "log"
"os" "os"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
c "github.com/Azareal/Gosora/common"
qgen "github.com/Azareal/Gosora/query_gen" qgen "github.com/Azareal/Gosora/query_gen"
) )
@ -175,18 +177,42 @@ func seedTables(adapter qgen.Adapter) error {
MoveTopic MoveTopic
*/ */
// TODO: Set the permissions on a struct and then serialize the struct and insert that instead of writing raw JSON p := func(perms c.Perms) string {
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, is_admin, tag", `'Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,"Admin"`) jBytes, err := json.Marshal(perms)
if err != nil {
panic(err)
}
return string(jBytes)
}
addGroup := func(name string, perms c.Perms, mod bool, admin bool, banned bool, tag string) {
mi, ai, bi := "0", "0", "0"
if mod {
mi = "1"
}
if admin {
ai = "1"
}
if banned {
bi = "1"
}
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, is_admin, is_banned, tag", `'`+name+`','`+p(perms)+`','{}',`+mi+`,`+ai+`,`+bi+`,"`+tag+`"`)
}
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, tag", `'Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,"Mod"`) perms := c.AllPerms
perms.EditUserGroupAdmin = false
perms.EditGroupAdmin = false
addGroup("Administrator", perms, true, true, false, "Admin")
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms", `'Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}'`) perms = c.Perms{BanUsers: true, ActivateUsers: true, EditUser: true, EditUserEmail: false, EditUserGroup: true, ViewIPs: true, UploadFiles: true, UploadAvatars: true, UseConvos: true, ViewTopic: true, LikeItem: true, CreateTopic: true, EditTopic: true, DeleteTopic: true, CreateReply: true, EditReply: true, DeleteReply: true, PinTopic: true, CloseTopic: true, MoveTopic: true}
addGroup("Moderator", perms, true, false, false, "Mod")
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_banned", `'Banned','{"ViewTopic":true}','{}',1`) perms = c.Perms{UploadFiles: true, UploadAvatars: true, UseConvos: true, ViewTopic: true, LikeItem: true, CreateTopic: true, CreateReply: true}
addGroup("Member", perms, false, false, false, "")
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms", `'Awaiting Activation','{"ViewTopic":true}','{}'`) perms = c.Perms{ViewTopic: true}
addGroup("Banned", perms, false, false, true, "")
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, tag", `'Not Loggedin','{"ViewTopic":true}','{}','Guest'`) addGroup("Awaiting Activation", perms, false, false, false, "")
addGroup("Not Loggedin", perms, false, false, false, "Guest")
// //
// TODO: Stop processFields() from stripping the spaces in the descriptions in the next commit // TODO: Stop processFields() from stripping the spaces in the descriptions in the next commit

View File

@ -45,50 +45,50 @@ var GlobalPermList = []string{
// Permission Structure: ActionComponent[Subcomponent]Flag // Permission Structure: ActionComponent[Subcomponent]Flag
type Perms struct { type Perms struct {
// Global Permissions // Global Permissions
BanUsers bool BanUsers bool `json:",omitempty"`
ActivateUsers bool ActivateUsers bool `json:",omitempty"`
EditUser bool EditUser bool `json:",omitempty"`
EditUserEmail bool EditUserEmail bool `json:",omitempty"`
EditUserPassword bool EditUserPassword bool `json:",omitempty"`
EditUserGroup bool EditUserGroup bool `json:",omitempty"`
EditUserGroupSuperMod bool EditUserGroupSuperMod bool `json:",omitempty"`
EditUserGroupAdmin bool EditUserGroupAdmin bool `json:",omitempty"`
EditGroup bool EditGroup bool `json:",omitempty"`
EditGroupLocalPerms bool EditGroupLocalPerms bool `json:",omitempty"`
EditGroupGlobalPerms bool EditGroupGlobalPerms bool `json:",omitempty"`
EditGroupSuperMod bool EditGroupSuperMod bool `json:",omitempty"`
EditGroupAdmin bool EditGroupAdmin bool `json:",omitempty"`
ManageForums bool // This could be local, albeit limited for per-forum managers? ManageForums bool `json:",omitempty"` // This could be local, albeit limited for per-forum managers?
EditSettings bool EditSettings bool `json:",omitempty"`
ManageThemes bool ManageThemes bool `json:",omitempty"`
ManagePlugins bool ManagePlugins bool `json:",omitempty"`
ViewAdminLogs bool ViewAdminLogs bool `json:",omitempty"`
ViewIPs bool ViewIPs bool `json:",omitempty"`
// Global non-staff permissions // Global non-staff permissions
UploadFiles bool UploadFiles bool `json:",omitempty"`
UploadAvatars bool UploadAvatars bool `json:",omitempty"`
UseConvos bool UseConvos bool `json:",omitempty"`
// Forum permissions // Forum permissions
ViewTopic bool ViewTopic bool `json:",omitempty"`
//ViewOwnTopic bool //ViewOwnTopic bool `json:",omitempty"`
LikeItem bool LikeItem bool `json:",omitempty"`
CreateTopic bool CreateTopic bool `json:",omitempty"`
EditTopic bool EditTopic bool `json:",omitempty"`
DeleteTopic bool DeleteTopic bool `json:",omitempty"`
CreateReply bool CreateReply bool `json:",omitempty"`
//CreateReplyToOwn bool //CreateReplyToOwn bool `json:",omitempty"`
EditReply bool EditReply bool `json:",omitempty"`
//EditOwnReply bool //EditOwnReply bool `json:",omitempty"`
DeleteReply bool DeleteReply bool `json:",omitempty"`
//DeleteOwnReply bool //DeleteOwnReply bool `json:",omitempty"`
PinTopic bool PinTopic bool `json:",omitempty"`
CloseTopic bool CloseTopic bool `json:",omitempty"`
//CloseOwnTopic bool //CloseOwnTopic bool `json:",omitempty"`
MoveTopic bool MoveTopic bool `json:",omitempty"`
//ExtData map[string]bool //ExtData map[string]bool `json:",omitempty"`
} }
func init() { func init() {

View File

@ -11,9 +11,9 @@ import (
"runtime/debug" "runtime/debug"
"strconv" "strconv"
"strings" "strings"
"unicode"
"text/template/parse" "text/template/parse"
"time" "time"
"unicode"
) )
// TODO: Turn this file into a library // TODO: Turn this file into a library
@ -107,15 +107,15 @@ func NewCTemplateSet(in string) *CTemplateSet {
"hasWidgets": true, "hasWidgets": true,
"elapsed": true, "elapsed": true,
"lang": true, "lang": true,
"langf":true, "langf": true,
"level": true, "level": true,
"bunit": true, "bunit": true,
"abstime": true, "abstime": true,
"reltime": true, "reltime": true,
"scope": true, "scope": true,
"dyntmpl": true, "dyntmpl": true,
"index": true, "index": true,
"flush": true, "flush": true,
}, },
logger: log.New(f, "", log.LstdFlags), logger: log.New(f, "", log.LstdFlags),
loggerf: f, loggerf: f,
@ -193,9 +193,9 @@ func (c *CTemplateSet) CompileByLoggedin(name string, fileDir string, expects st
} }
var importList string var importList string
for _, item := range c.importMap { for _, item := range c.importMap {
ispl := strings.Split(item," ") ispl := strings.Split(item, " ")
if len(ispl) > 1 { if len(ispl) > 1 {
importList += "import "+ispl[0]+" \"" + ispl[1] + "\"\n" importList += "import " + ispl[0] + " \"" + ispl[1] + "\"\n"
} else { } else {
importList += "import \"" + item + "\"\n" importList += "import \"" + item + "\"\n"
} }
@ -284,8 +284,7 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe
func (c *CTemplateSet) compile(name string, content string, expects string, expectsInt interface{}, varList map[string]VarItem, imports ...string) (out string, err error) { func (c *CTemplateSet) compile(name string, content string, expects string, expectsInt interface{}, varList map[string]VarItem, imports ...string) (out string, err error) {
defer func() { defer func() {
r := recover() if r := recover(); r != nil {
if r != nil {
fmt.Println(r) fmt.Println(r)
debug.PrintStack() debug.PrintStack()
err := c.loggerf.Sync() err := c.loggerf.Sync()
@ -313,7 +312,7 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
c.stats = make(map[string]int) c.stats = make(map[string]int)
tree := parse.New(name, c.funcMap) tree := parse.New(name, c.funcMap)
var treeSet = make(map[string]*parse.Tree) treeSet := make(map[string]*parse.Tree)
tree, err = tree.Parse(content, "{{", "}}", treeSet, c.funcMap) tree, err = tree.Parse(content, "{{", "}}", treeSet, c.funcMap)
if err != nil { if err != nil {
return "", err return "", err
@ -413,9 +412,9 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
} }
var importList string var importList string
for _, item := range c.importMap { for _, item := range c.importMap {
ispl := strings.Split(item," ") ispl := strings.Split(item, " ")
if len(ispl) > 1 { if len(ispl) > 1 {
importList += "import "+ispl[0]+" \"" + ispl[1] + "\"\n" importList += "import " + ispl[0] + " \"" + ispl[1] + "\"\n"
} else { } else {
importList += "import \"" + item + "\"\n" importList += "import \"" + item + "\"\n"
} }
@ -481,9 +480,9 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
} }
fout += varString fout += varString
var skipped = make(map[string]*SkipBlock) // map[templateName]*SkipBlock{map[atIndexAndAfter]skipThisMuch,lastCount} skipped := make(map[string]*SkipBlock) // map[templateName]*SkipBlock{map[atIndexAndAfter]skipThisMuch,lastCount}
var writeTextFrame = func(tmplName string, index int) { writeTextFrame := func(tmplName string, index int) {
out := "w.Write(" + tmplName + "_frags[" + strconv.Itoa(index) + "]" + ")\n" out := "w.Write(" + tmplName + "_frags[" + strconv.Itoa(index) + "]" + ")\n"
c.detail("writing ", out) c.detail("writing ", out)
fout += out fout += out
@ -531,7 +530,7 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
} }
fout += "return nil\n}\n" fout += "return nil\n}\n"
var writeFrag = func(tmplName string, index int, body string) { writeFrag := func(tmplName string, index int, body string) {
//c.detail("writing ", fragmentPrefix) //c.detail("writing ", fragmentPrefix)
c.FragOut = append(c.FragOut, OutFrag{tmplName, index, body}) c.FragOut = append(c.FragOut, OutFrag{tmplName, index, body})
} }
@ -704,7 +703,7 @@ func (c *CTemplateSet) compileRangeNode(con CContext, node *parse.RangeNode) {
c.detail("Expr:", expr) c.detail("Expr:", expr)
c.detail("Range Kind Switch!") c.detail("Range Kind Switch!")
var startIf = func(item reflect.Value, useCopy bool) { startIf := func(item reflect.Value, useCopy bool) {
con.Push("startif", "if len("+expr+") != 0 {\n") con.Push("startif", "if len("+expr+") != 0 {\n")
startIndex := con.StartLoop("for _, item := range " + expr + " {\n") startIndex := con.StartLoop("for _, item := range " + expr + " {\n")
ccon := con ccon := con
@ -812,7 +811,7 @@ func (c *CTemplateSet) compileSubSwitch(con CContext, node *parse.CommandNode) {
} }
var assLines string var assLines string
var multiline = false multiline := false
for _, id := range n.Ident { for _, id := range n.Ident {
c.detail("Data Kind:", cur.Kind().String()) c.detail("Data Kind:", cur.Kind().String())
c.detail("Field Bit:", id) c.detail("Field Bit:", id)
@ -1023,7 +1022,7 @@ func (c *CTemplateSet) compareJoin(con CContext, pos int, node *parse.CommandNod
func (c *CTemplateSet) compileIdentSwitch(con CContext, node *parse.CommandNode) (out string, val reflect.Value, literal bool, notident bool) { func (c *CTemplateSet) compileIdentSwitch(con CContext, node *parse.CommandNode) (out string, val reflect.Value, literal bool, notident bool) {
c.dumpCall("compileIdentSwitch", con, node) c.dumpCall("compileIdentSwitch", con, node)
var litString = func(inner string, bytes bool) { litString := func(inner string, bytes bool) {
if !bytes { if !bytes {
inner = "StringToBytes(" + inner + ")" inner = "StringToBytes(" + inner + ")"
} }
@ -1129,9 +1128,9 @@ ArgLoop:
if leftOperand[0] != '"' { if leftOperand[0] != '"' {
panic("Phrase names cannot be dynamic") panic("Phrase names cannot be dynamic")
} }
var olist []string var olist []string
for i := pos+2; i < len(node.Args); i++ { for i := pos + 2; i < len(node.Args); i++ {
op := node.Args[i].String() op := node.Args[i].String()
if op != "" { if op != "" {
if op[0] == '.' || op[0] == '$' { if op[0] == '.' || op[0] == '$' {
@ -1140,14 +1139,14 @@ ArgLoop:
if op[0] != '"' && !unicode.IsDigit(rune(op[0])) { if op[0] != '"' && !unicode.IsDigit(rune(op[0])) {
break break
} }
olist = append(olist,op) olist = append(olist, op)
} }
} }
if len(olist) == 0 { if len(olist) == 0 {
panic("You must provide parameters for langf") panic("You must provide parameters for langf")
} }
var ob = "," ob := ","
for _, op := range olist { for _, op := range olist {
allNum := true allNum := true
for _, o := range op { for _, o := range op {
@ -1156,7 +1155,7 @@ ArgLoop:
} }
} }
if allNum { if allNum {
ob += strings.Replace(op,"\"","\\\"",-1) + "," ob += strings.Replace(op, "\"", "\\\"", -1) + ","
} else { } else {
ob += ob + "," ob += ob + ","
} }
@ -1316,8 +1315,8 @@ func (c *CTemplateSet) compileIfVarSub(con CContext, varname string) (out string
return varname, cur return varname, cur
} }
var stepInterface = func() { stepInterface := func() {
var nobreak = (cur.Type().Name() == "nobreak") nobreak := (cur.Type().Name() == "nobreak")
c.detailf("cur.Type().Name(): %+v\n", cur.Type().Name()) c.detailf("cur.Type().Name(): %+v\n", cur.Type().Name())
if cur.Kind() == reflect.Interface && !nobreak { if cur.Kind() == reflect.Interface && !nobreak {
cur = cur.Elem() cur = cur.Elem()
@ -1345,7 +1344,7 @@ func (c *CTemplateSet) compileIfVarSub(con CContext, varname string) (out string
} }
bits[0] = strings.TrimPrefix(bits[0], "$") bits[0] = strings.TrimPrefix(bits[0], "$")
var dumpKind = func(pre string) { dumpKind := func(pre string) {
c.detail(pre+" Kind:", cur.Kind()) c.detail(pre+" Kind:", cur.Kind())
c.detail(pre+" Type:", cur.Type().Name()) c.detail(pre+" Type:", cur.Type().Name())
} }
@ -1484,12 +1483,12 @@ func (c *CTemplateSet) retCall(name string, params ...interface{}) {
} }
func buildUserExprs(holder string) ([]string, []string) { func buildUserExprs(holder string) ([]string, []string) {
var userExprs = []string{ userExprs := []string{
holder + ".CurrentUser.Loggedin", holder + ".CurrentUser.Loggedin",
holder + ".CurrentUser.IsSuperMod", holder + ".CurrentUser.IsSuperMod",
holder + ".CurrentUser.IsAdmin", holder + ".CurrentUser.IsAdmin",
} }
var negUserExprs = []string{ negUserExprs := []string{
"!" + holder + ".CurrentUser.Loggedin", "!" + holder + ".CurrentUser.Loggedin",
"!" + holder + ".CurrentUser.IsSuperMod", "!" + holder + ".CurrentUser.IsSuperMod",
"!" + holder + ".CurrentUser.IsAdmin", "!" + holder + ".CurrentUser.IsAdmin",

View File

@ -20,7 +20,7 @@ import (
"strconv" "strconv"
"text/template" "text/template"
"github.com/Azareal/Gosora/common/phrases" p "github.com/Azareal/Gosora/common/phrases"
) )
var ErrNoDefaultTheme = errors.New("The default theme isn't registered in the system") var ErrNoDefaultTheme = errors.New("The default theme isn't registered in the system")
@ -88,8 +88,8 @@ type ThemeMapTmplToDock struct {
} }
// TODO: It might be unsafe to call the template parsing functions with fsnotify, do something more concurrent // TODO: It might be unsafe to call the template parsing functions with fsnotify, do something more concurrent
func (theme *Theme) LoadStaticFiles() error { func (t *Theme) LoadStaticFiles() error {
theme.ResourceTemplates = template.New("") t.ResourceTemplates = template.New("")
fmap := make(map[string]interface{}) fmap := make(map[string]interface{})
fmap["lang"] = func(phraseNameInt interface{}, tmplInt interface{}) interface{} { fmap["lang"] = func(phraseNameInt interface{}, tmplInt interface{}) interface{} {
phraseName, ok := phraseNameInt.(string) phraseName, ok := phraseNameInt.(string)
@ -117,18 +117,18 @@ func (theme *Theme) LoadStaticFiles() error {
} }
return out return out
} }
theme.ResourceTemplates.Funcs(fmap) t.ResourceTemplates.Funcs(fmap)
template.Must(theme.ResourceTemplates.ParseGlob("./themes/" + theme.Name + "/public/*.css")) template.Must(t.ResourceTemplates.ParseGlob("./themes/" + t.Name + "/public/*.css"))
// It should be safe for us to load the files for all the themes in memory, as-long as the admin hasn't setup a ridiculous number of themes // It should be safe for us to load the files for all the themes in memory, as-long as the admin hasn't setup a ridiculous number of themes
return theme.AddThemeStaticFiles() return t.AddThemeStaticFiles()
} }
func (theme *Theme) AddThemeStaticFiles() error { func (t *Theme) AddThemeStaticFiles() error {
phraseMap := phrases.GetTmplPhrases() phraseMap := p.GetTmplPhrases()
// TODO: Use a function instead of a closure to make this more testable? What about a function call inside the closure to take the theme variable into account? // TODO: Use a function instead of a closure to make this more testable? What about a function call inside the closure to take the theme variable into account?
return filepath.Walk("./themes/"+theme.Name+"/public", func(path string, f os.FileInfo, err error) error { return filepath.Walk("./themes/"+t.Name+"/public", func(path string, f os.FileInfo, err error) error {
DebugLog("Attempting to add static file '" + path + "' for default theme '" + theme.Name + "'") DebugLog("Attempting to add static file '" + path + "' for default theme '" + t.Name + "'")
if err != nil { if err != nil {
return err return err
} }
@ -142,21 +142,21 @@ func (theme *Theme) AddThemeStaticFiles() error {
return err return err
} }
var ext = filepath.Ext(path) ext := filepath.Ext(path)
if ext == ".css" && len(data) != 0 { if ext == ".css" && len(data) != 0 {
var b bytes.Buffer var b bytes.Buffer
pieces := strings.Split(path, "/") pieces := strings.Split(path, "/")
filename := pieces[len(pieces)-1] filename := pieces[len(pieces)-1]
// TODO: Prepare resource templates for each loaded langpack? // TODO: Prepare resource templates for each loaded langpack?
err = theme.ResourceTemplates.ExecuteTemplate(&b, filename, CSSData{Phrases: phraseMap}) err = t.ResourceTemplates.ExecuteTemplate(&b, filename, CSSData{Phrases: phraseMap})
if err != nil { if err != nil {
log.Print("Failed in adding static file '" + path + "' for default theme '" + theme.Name + "'") log.Print("Failed in adding static file '" + path + "' for default theme '" + t.Name + "'")
return err return err
} }
data = b.Bytes() data = b.Bytes()
} }
path = strings.TrimPrefix(path, "themes/"+theme.Name+"/public") path = strings.TrimPrefix(path, "themes/"+t.Name+"/public")
gzipData, err := CompressBytesGzip(data) gzipData, err := CompressBytesGzip(data)
if err != nil { if err != nil {
return err return err
@ -167,16 +167,16 @@ func (theme *Theme) AddThemeStaticFiles() error {
hasher.Write(data) hasher.Write(data)
checksum := hex.EncodeToString(hasher.Sum(nil)) checksum := hex.EncodeToString(hasher.Sum(nil))
StaticFiles.Set("/s/"+theme.Name+path, SFile{data, gzipData, checksum,theme.Name+path + "?h=" + checksum, 0, int64(len(data)), int64(len(gzipData)),strconv.Itoa(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}) StaticFiles.Set("/s/"+t.Name+path, SFile{data, gzipData, checksum,t.Name+path + "?h=" + checksum, 0, int64(len(data)), int64(len(gzipData)),strconv.Itoa(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)})
DebugLog("Added the '/" + theme.Name + path + "' static file for theme " + theme.Name + ".") DebugLog("Added the '/" + t.Name + path + "' static file for theme " + t.Name + ".")
return nil return nil
}) })
} }
func (theme *Theme) MapTemplates() { func (t *Theme) MapTemplates() {
if theme.Templates != nil { if t.Templates != nil {
for _, themeTmpl := range theme.Templates { for _, themeTmpl := range t.Templates {
if themeTmpl.Name == "" { if themeTmpl.Name == "" {
LogError(errors.New("Invalid destination template name")) LogError(errors.New("Invalid destination template name"))
} }
@ -215,34 +215,34 @@ func (theme *Theme) MapTemplates() {
} }
} }
func (theme *Theme) setActive(active bool) error { func (t *Theme) setActive(active bool) error {
var sink bool var sink bool
err := themeStmts.isDefault.QueryRow(theme.Name).Scan(&sink) err := themeStmts.isDefault.QueryRow(t.Name).Scan(&sink)
if err != nil && err != sql.ErrNoRows { if err != nil && err != sql.ErrNoRows {
return err return err
} }
hasTheme := err != sql.ErrNoRows hasTheme := err != sql.ErrNoRows
if hasTheme { if hasTheme {
_, err = themeStmts.update.Exec(active, theme.Name) _, err = themeStmts.update.Exec(active, t.Name)
} else { } else {
_, err = themeStmts.add.Exec(theme.Name, active) _, err = themeStmts.add.Exec(t.Name, active)
} }
if err != nil { if err != nil {
return err return err
} }
// TODO: Think about what we want to do for multi-server configurations // TODO: Think about what we want to do for multi-server configurations
log.Printf("Setting theme '%s' as the default theme", theme.Name) log.Printf("Setting theme '%s' as the default theme", t.Name)
theme.Active = active t.Active = active
return nil return nil
} }
func UpdateDefaultTheme(theme *Theme) error { func UpdateDefaultTheme(t *Theme) error {
ChangeDefaultThemeMutex.Lock() ChangeDefaultThemeMutex.Lock()
defer ChangeDefaultThemeMutex.Unlock() defer ChangeDefaultThemeMutex.Unlock()
err := theme.setActive(true) err := t.setActive(true)
if err != nil { if err != nil {
return err return err
} }
@ -258,15 +258,15 @@ func UpdateDefaultTheme(theme *Theme) error {
return err return err
} }
DefaultThemeBox.Store(theme.Name) DefaultThemeBox.Store(t.Name)
ResetTemplateOverrides() ResetTemplateOverrides()
theme.MapTemplates() t.MapTemplates()
return nil return nil
} }
func (theme Theme) HasDock(name string) bool { func (t Theme) HasDock(name string) bool {
for _, dock := range theme.Docks { for _, dock := range t.Docks {
if dock == name { if dock == name {
return true return true
} }
@ -274,8 +274,8 @@ func (theme Theme) HasDock(name string) bool {
return false return false
} }
func (theme Theme) BuildDock(dock string) (sbody string) { func (t Theme) BuildDock(dock string) (sbody string) {
runOnDock := theme.RunOnDock runOnDock := t.RunOnDock
if runOnDock != nil { if runOnDock != nil {
return runOnDock(dock) return runOnDock(dock)
} }
@ -294,14 +294,14 @@ func (w GzipResponseWriter) Write(b []byte) (int, error) {
// NEW method of doing theme templates to allow one user to have a different theme to another. Under construction. // NEW method of doing theme templates to allow one user to have a different theme to another. Under construction.
// TODO: Generate the type switch instead of writing it by hand // TODO: Generate the type switch instead of writing it by hand
// TODO: Cut the number of types in half // TODO: Cut the number of types in half
func (theme *Theme) RunTmpl(template string, pi interface{}, w io.Writer) error { func (t *Theme) RunTmpl(template string, pi interface{}, w io.Writer) error {
// Unpack this to avoid an indirect call // Unpack this to avoid an indirect call
gzw, ok := w.(GzipResponseWriter) gzw, ok := w.(GzipResponseWriter)
if ok { if ok {
w = gzw.Writer w = gzw.Writer
} }
var getTmpl = theme.GetTmpl(template) getTmpl := t.GetTmpl(template)
switch tmplO := getTmpl.(type) { switch tmplO := getTmpl.(type) {
case *func(interface{}, io.Writer) error: case *func(interface{}, io.Writer) error:
var tmpl = *tmplO var tmpl = *tmplO
@ -310,16 +310,16 @@ func (theme *Theme) RunTmpl(template string, pi interface{}, w io.Writer) error
return tmplO(pi, w) return tmplO(pi, w)
case nil, string: case nil, string:
//fmt.Println("falling back to interpreted for " + template) //fmt.Println("falling back to interpreted for " + template)
mapping, ok := theme.TemplatesMap[template] mapping, ok := t.TemplatesMap[template]
if !ok { if !ok {
mapping = template mapping = template
} }
if theme.IntTmplHandle.Lookup(mapping+".html") == nil { if t.IntTmplHandle.Lookup(mapping+".html") == nil {
return ErrBadDefaultTemplate return ErrBadDefaultTemplate
} }
return theme.IntTmplHandle.ExecuteTemplate(w, mapping+".html", pi) return t.IntTmplHandle.ExecuteTemplate(w, mapping+".html", pi)
default: default:
log.Print("theme ", theme) log.Print("theme ", t)
log.Print("template ", template) log.Print("template ", template)
log.Print("pi ", pi) log.Print("pi ", pi)
log.Print("tmplO ", tmplO) log.Print("tmplO ", tmplO)
@ -339,14 +339,14 @@ func (theme *Theme) RunTmpl(template string, pi interface{}, w io.Writer) error
} }
// GetTmpl attempts to get the template for a specific theme, otherwise it falls back on the default template pointer, which if absent will fallback onto the template interpreter // GetTmpl attempts to get the template for a specific theme, otherwise it falls back on the default template pointer, which if absent will fallback onto the template interpreter
func (theme *Theme) GetTmpl(template string) interface{} { func (t *Theme) GetTmpl(template string) interface{} {
// TODO: Figure out why we're getting a nil pointer here when transpiled templates are disabled, I would have assumed that we would just fall back to !ok on this // TODO: Figure out why we're getting a nil pointer here when transpiled templates are disabled, I would have assumed that we would just fall back to !ok on this
// Might have something to do with it being the theme's TmplPtr map, investigate. // Might have something to do with it being the theme's TmplPtr map, investigate.
tmpl, ok := theme.TmplPtr[template] tmpl, ok := t.TmplPtr[template]
if ok { if ok {
return tmpl return tmpl
} }
tmpl, ok = TmplPtrMap[template+"_"+theme.Name] tmpl, ok = TmplPtrMap[template+"_"+t.Name]
if ok { if ok {
return tmpl return tmpl
} }

View File

@ -54,7 +54,7 @@ func NewDefaultWordFilterStore(acc *qgen.Accumulator) (*DefaultWordFilterStore,
// ReloadAll drops all the items in the memory cache and replaces them with fresh copies from the database // ReloadAll drops all the items in the memory cache and replaces them with fresh copies from the database
func (s *DefaultWordFilterStore) ReloadAll() error { func (s *DefaultWordFilterStore) ReloadAll() error {
var wordFilters = make(map[int]*WordFilter) wordFilters := make(map[int]*WordFilter)
filters, err := s.bypassGetAll() filters, err := s.bypassGetAll()
if err != nil { if err != nil {
return err return err
@ -77,12 +77,12 @@ func (s *DefaultWordFilterStore) bypassGetAll() (filters []*WordFilter, err erro
defer rows.Close() defer rows.Close()
for rows.Next() { for rows.Next() {
filter := &WordFilter{ID: 0} f := &WordFilter{ID: 0}
err := rows.Scan(&filter.ID, &filter.Find, &filter.Replacement) err := rows.Scan(&f.ID, &f.Find, &f.Replacement)
if err != nil { if err != nil {
return filters, err return filters, err
} }
filters = append(filters, filter) filters = append(filters, f)
} }
return filters, rows.Err() return filters, rows.Err()
} }
@ -93,8 +93,8 @@ func (s *DefaultWordFilterStore) GetAll() (filters map[int]*WordFilter, err erro
} }
// Create adds a new word filter to the database and refreshes the memory cache // Create adds a new word filter to the database and refreshes the memory cache
func (s *DefaultWordFilterStore) Create(find string, replacement string) error { func (s *DefaultWordFilterStore) Create(find string, replace string) error {
_, err := s.create.Exec(find, replacement) _, err := s.create.Exec(find, replace)
if err != nil { if err != nil {
return err return err
} }
@ -110,8 +110,8 @@ func (s *DefaultWordFilterStore) Delete(id int) error {
return s.ReloadAll() return s.ReloadAll()
} }
func (s *DefaultWordFilterStore) Update(id int, find string, replacement string) error { func (s *DefaultWordFilterStore) Update(id int, find string, replace string) error {
_, err := s.update.Exec(find, replacement, id) _, err := s.update.Exec(find, replace, id)
if err != nil { if err != nil {
return err return err
} }

View File

@ -7,12 +7,12 @@ INSERT INTO [settings] ([name],[content],[type]) VALUES ('rapid_loading','1','bo
INSERT INTO [settings] ([name],[content],[type]) VALUES ('google_site_verify','','html-attribute'); INSERT INTO [settings] ([name],[content],[type]) VALUES ('google_site_verify','','html-attribute');
INSERT INTO [themes] ([uname],[default]) VALUES ('cosora',1); INSERT INTO [themes] ([uname],[default]) VALUES ('cosora',1);
INSERT INTO [emails] ([email],[uid],[validated]) VALUES ('admin@localhost',1,1); INSERT INTO [emails] ([email],[uid],[validated]) VALUES ('admin@localhost',1,1);
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[tag]) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin'); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[is_banned],[tag]) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,0,'Admin');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[tag]) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod'); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[is_banned],[tag]) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,0,0,'Mod');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms]) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}'); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[is_banned],[tag]) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}',0,0,0,"");
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_banned]) VALUES ('Banned','{"ViewTopic":true}','{}',1); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[is_banned],[tag]) VALUES ('Banned','{"ViewTopic":true}','{}',0,0,1,"");
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms]) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}'); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[is_banned],[tag]) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}',0,0,0,"");
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[tag]) VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest'); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[is_banned],[tag]) VALUES ('Not Loggedin','{"ViewTopic":true}','{}',0,0,0,'Guest');
INSERT INTO [forums] ([name],[active],[desc],[tmpl]) VALUES ('Reports',0,'All the reports go here',''); INSERT INTO [forums] ([name],[active],[desc],[tmpl]) VALUES ('Reports',0,'All the reports go here','');
INSERT INTO [forums] ([name],[lastTopicID],[lastReplyerID],[desc],[tmpl]) VALUES ('General',1,1,'A place for general discussions which don''t fit elsewhere',''); INSERT INTO [forums] ([name],[lastTopicID],[lastReplyerID],[desc],[tmpl]) VALUES ('General',1,1,'A place for general discussions which don''t fit elsewhere','');
INSERT INTO [forums_permissions] ([gid],[fid],[permissions]) VALUES (1,1,'{"ViewTopic":true,"CreateReply":true,"CreateTopic":true,"PinTopic":true,"CloseTopic":true}'); INSERT INTO [forums_permissions] ([gid],[fid],[permissions]) VALUES (1,1,'{"ViewTopic":true,"CreateReply":true,"CreateTopic":true,"PinTopic":true,"CloseTopic":true}');

View File

@ -15,12 +15,12 @@ INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('rapid_loading','1','boo
INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('google_site_verify','','html-attribute'); INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('google_site_verify','','html-attribute');
INSERT INTO `themes`(`uname`,`default`) VALUES ('cosora',1); INSERT INTO `themes`(`uname`,`default`) VALUES ('cosora',1);
INSERT INTO `emails`(`email`,`uid`,`validated`) VALUES ('admin@localhost',1,1); INSERT INTO `emails`(`email`,`uid`,`validated`) VALUES ('admin@localhost',1,1);
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin'); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`is_banned`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,0,'Admin');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod'); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`is_banned`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,0,0,'Mod');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}'); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`is_banned`,`tag`) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}',0,0,0,"");
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_banned`) VALUES ('Banned','{"ViewTopic":true}','{}',1); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`is_banned`,`tag`) VALUES ('Banned','{"ViewTopic":true}','{}',0,0,1,"");
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}'); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`is_banned`,`tag`) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}',0,0,0,"");
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`tag`) VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest'); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`is_banned`,`tag`) VALUES ('Not Loggedin','{"ViewTopic":true}','{}',0,0,0,'Guest');
INSERT INTO `forums`(`name`,`active`,`desc`,`tmpl`) VALUES ('Reports',0,'All the reports go here',''); INSERT INTO `forums`(`name`,`active`,`desc`,`tmpl`) VALUES ('Reports',0,'All the reports go here','');
INSERT INTO `forums`(`name`,`lastTopicID`,`lastReplyerID`,`desc`,`tmpl`) VALUES ('General',1,1,'A place for general discussions which don''t fit elsewhere',''); INSERT INTO `forums`(`name`,`lastTopicID`,`lastReplyerID`,`desc`,`tmpl`) VALUES ('General',1,1,'A place for general discussions which don''t fit elsewhere','');
INSERT INTO `forums_permissions`(`gid`,`fid`,`permissions`) VALUES (1,1,'{"ViewTopic":true,"CreateReply":true,"CreateTopic":true,"PinTopic":true,"CloseTopic":true}'); INSERT INTO `forums_permissions`(`gid`,`fid`,`permissions`) VALUES (1,1,'{"ViewTopic":true,"CreateReply":true,"CreateTopic":true,"PinTopic":true,"CloseTopic":true}');

View File

@ -7,12 +7,12 @@ INSERT INTO "settings"("name","content","type") VALUES ('rapid_loading','1','boo
INSERT INTO "settings"("name","content","type") VALUES ('google_site_verify','','html-attribute'); INSERT INTO "settings"("name","content","type") VALUES ('google_site_verify','','html-attribute');
INSERT INTO "themes"("uname","default") VALUES ('cosora',1); INSERT INTO "themes"("uname","default") VALUES ('cosora',1);
INSERT INTO "emails"("email","uid","validated") VALUES ('admin@localhost',1,1); INSERT INTO "emails"("email","uid","validated") VALUES ('admin@localhost',1,1);
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","tag") VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin'); INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","is_banned","tag") VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,0,'Admin');
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","tag") VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod'); INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","is_banned","tag") VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,0,0,'Mod');
INSERT INTO "users_groups"("name","permissions","plugin_perms") VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}'); INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","is_banned","tag") VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}',0,0,0,"");
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_banned") VALUES ('Banned','{"ViewTopic":true}','{}',1); INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","is_banned","tag") VALUES ('Banned','{"ViewTopic":true}','{}',0,0,1,"");
INSERT INTO "users_groups"("name","permissions","plugin_perms") VALUES ('Awaiting Activation','{"ViewTopic":true}','{}'); INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","is_banned","tag") VALUES ('Awaiting Activation','{"ViewTopic":true}','{}',0,0,0,"");
INSERT INTO "users_groups"("name","permissions","plugin_perms","tag") VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest'); INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","is_banned","tag") VALUES ('Not Loggedin','{"ViewTopic":true}','{}',0,0,0,'Guest');
INSERT INTO "forums"("name","active","desc","tmpl") VALUES ('Reports',0,'All the reports go here',''); INSERT INTO "forums"("name","active","desc","tmpl") VALUES ('Reports',0,'All the reports go here','');
INSERT INTO "forums"("name","lastTopicID","lastReplyerID","desc","tmpl") VALUES ('General',1,1,'A place for general discussions which don''t fit elsewhere',''); INSERT INTO "forums"("name","lastTopicID","lastReplyerID","desc","tmpl") VALUES ('General',1,1,'A place for general discussions which don''t fit elsewhere','');
INSERT INTO "forums_permissions"("gid","fid","permissions") VALUES (1,1,'{"ViewTopic":true,"CreateReply":true,"CreateTopic":true,"PinTopic":true,"CloseTopic":true}'); INSERT INTO "forums_permissions"("gid","fid","permissions") VALUES (1,1,'{"ViewTopic":true,"CreateReply":true,"CreateTopic":true,"PinTopic":true,"CloseTopic":true}');

View File

@ -26,9 +26,7 @@
{{end}} {{end}}
</div> </div>
</div> </div>
{{if .Poll.ID}} {{if .Poll.ID}}{{template "topic_poll.html" . }}{{end}}
{{template "topic_poll.html" . }}
{{end}}
<article {{scope "opening_post"}} itemscope itemtype="http://schema.org/CreativeWork" class="rowblock post_container top_post" aria-label="{{lang "topic.opening_post_aria"}}"> <article {{scope "opening_post"}} itemscope itemtype="http://schema.org/CreativeWork" class="rowblock post_container top_post" aria-label="{{lang "topic.opening_post_aria"}}">
<div class="rowitem passive editable_parent post_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}), url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat,repeat-y;"> <div class="rowitem passive editable_parent post_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}), url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat,repeat-y;">