Added more phrases for the notices.

Theme resources can now be restricted to logged in users to avoid wasting bandwidth.
The template building step is now a flag to gosora.exe / Gosora.

Added build_templates.bat for test and development purposes.
Added some extra error checks to the batch files.
Fixed a compile error in the installer.
Fixed a big data race in the template transpiler and cleaned up a few loose ends.
Renamed CTemplateSet.log() to CTemplateSet.detail() to bring it in line with the /common/ logging
Renamed CTemplateSet.logf() to CTemplateSet.detailf() to bring it in line with the /common/ logging
You can now override templates in /templates/ without overwriting them by adding a modified version of a template with the same name in /templates/overrides/
Added Go Git as a dependency.
Removed config.go from the repository, you need to rely on the installer to generate this now, or make one yourself based on the implementation of it in the installer.
Travis now does tests for Go 1.10

Began work on the upgrader.
This commit is contained in:
Azareal 2018-03-21 05:56:33 +00:00
parent b20e295375
commit 2b86a17478
36 changed files with 549 additions and 158 deletions

View File

@ -1,11 +1,13 @@
language: go language: go
go: go:
- 1.9 - 1.9
- 1.10
- master - master
before_install: before_install:
- cd $HOME - cd $HOME
- git clone https://github.com/Azareal/Gosora - git clone https://github.com/Azareal/Gosora
- cd Gosora - cd Gosora
- mv config_default.noparse config.go
- chmod 755 ./update-deps-linux - chmod 755 ./update-deps-linux
- chmod 755 ./run-linux-tests - chmod 755 ./run-linux-tests
- ./update-deps-linux - ./update-deps-linux

View File

@ -50,7 +50,7 @@ It's entirely possible that your host might already have MySQL, so you might be
cd to the directory / folder the code is in. In other words, type cd followed by the location of the code and it should jump there. cd to the directory / folder the code is in. In other words, type cd followed by the location of the code and it should jump there.
Run ./install-gosora-linux Run ./install-linux
Follow the instructions shown on the screen. Follow the instructions shown on the screen.
@ -65,7 +65,7 @@ Follow the instructions shown on the screen.
*Linux* *Linux*
In the same directory you installed it, you simply have to type: ./run-gosora-linux In the same directory you installed it, you simply have to type: ./run-linux
*Windows* *Windows*
@ -73,13 +73,13 @@ Run run.bat
*Updating Dependencies* *Updating Dependencies*
You can update the dependencies which Gosora relies on by running update-deps.bat on Windows or ./update-deps-linux on Linux. These dependencies do not include Go or MySQL. You can update the dependencies which Gosora relies on by running update-deps.bat on Windows or ./update-deps-linux on Linux. These dependencies do not include Go or MySQL, those have to be updated separately.
We're also looking into ways to distribute ready made executables for Windows. While this is not a complicated endeavour, the configuration settings currently get built with the rest of the program for speed, and we will likely have to change this. We're also looking into ways to distribute ready made executables for Windows. While this is not a complicated endeavour, the configuration settings currently get built with the rest of the program for speed, and we will likely have to change this.
With the introduction of the new settings system, we will begin moving some of the less critical settings out of the configuration file, and will likely have a config.xml or config.ini in the future to store the critical settings in. With the introduction of the new settings system, we will begin moving some of the less critical settings out of the configuration file, and will likely have a config.xml or config.ini in the future to store the critical settings in.
You might have to run run.bat or ./run-gosora-linux twice after changing a template to make sure the templates are compiled properly. We'll be resolving this issue while rolling out the new compiled templates system to the rest of the routes. You'll need to restart the server every-time you change a template, e.g. with `run.bat` or `./run-linux`
Several important features for saving memory in the templates system may have to be implemented before the new compiled template system is rolled out to every route. These features are coming fairly soon, but not before the higher priority items. Several important features for saving memory in the templates system may have to be implemented before the new compiled template system is rolled out to every route. These features are coming fairly soon, but not before the higher priority items.
@ -90,6 +90,8 @@ An example of running the commands directly on Windows. We're looking into reduc
Linux is similar, however you might need to use cd and mv a bit more like in the shell files due to the differences in go build across platforms. Additionally, Linux doesn't require `StackExchange/wmi` or ``/x/sys/windows` Linux is similar, however you might need to use cd and mv a bit more like in the shell files due to the differences in go build across platforms. Additionally, Linux doesn't require `StackExchange/wmi` or ``/x/sys/windows`
You also need to substitute the `gosora.exe` bits for `./Gosora` on Linux. For more info, you might want to take a gander inside the `./run-linux` and `./install-linux` shell files to see how they're implemented.
```bash ```bash
git clone https://github.com/Azareal/Gosora git clone https://github.com/Azareal/Gosora
@ -113,6 +115,8 @@ go get -u github.com/denisenkom/go-mssqldb
go get -u github.com/fsnotify/fsnotify go get -u github.com/fsnotify/fsnotify
go get -u gopkg.in/src-d/go-git.v4/...
go generate go generate
@ -130,6 +134,8 @@ go build ./install
install.exe install.exe
gosora.exe -build-templates
gosora.exe gosora.exe
``` ```

2
build_templates.bat Normal file
View File

@ -0,0 +1,2 @@
gosora.exe -build-templates
pause

View File

@ -11,20 +11,13 @@ var EnableWebsockets = false // Put this in caps for consistency with the other
var wsHub WSHub var wsHub WSHub
var errWsNouser = errors.New("This user isn't connected via WebSockets") var errWsNouser = errors.New("This user isn't connected via WebSockets")
type WSHub struct { type WSHub struct{}
}
func (_ *WSHub) guestCount() int { func (_ *WSHub) guestCount() int { return 0 }
return 0
}
func (_ *WSHub) userCount() int { func (_ *WSHub) userCount() int { return 0 }
return 0
}
func (hub *WSHub) broadcastMessage(_ string) error { func (hub *WSHub) broadcastMessage(_ string) error { return nil }
return nil
}
func (hub *WSHub) pushMessage(_ int, _ string) error { func (hub *WSHub) pushMessage(_ int, _ string) error {
return errWsNouser return errWsNouser
@ -38,5 +31,4 @@ func (hub *WSHub) pushAlerts(_ []int, _ int, _ string, _ string, _ int, _ int, _
return errWsNouser return errWsNouser
} }
func RouteWebsockets(_ http.ResponseWriter, _ *http.Request, _ User) { func RouteWebsockets(_ http.ResponseWriter, _ *http.Request, _ User) {}
}

View File

@ -224,6 +224,9 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (headerVars *
if len(theme.Resources) > 0 { if len(theme.Resources) > 0 {
rlist := theme.Resources rlist := theme.Resources
for _, resource := range rlist { for _, resource := range rlist {
if resource.Loggedin && !user.Loggedin {
continue
}
if resource.Location == "global" || resource.Location == "frontend" { if resource.Location == "global" || resource.Location == "frontend" {
extarr := strings.Split(resource.Name, ".") extarr := strings.Split(resource.Name, ".")
ext := extarr[len(extarr)-1] ext := extarr[len(extarr)-1]

View File

@ -4,7 +4,10 @@ import (
"html/template" "html/template"
"log" "log"
"net/http" "net/http"
"path/filepath"
"strconv" "strconv"
"strings"
"sync"
"time" "time"
"./templates" "./templates"
@ -119,7 +122,7 @@ var Template_ip_search_handle = func(pi IPSearchPage, w http.ResponseWriter) err
} }
// ? - Add template hooks? // ? - Add template hooks?
func compileTemplates() error { func CompileTemplates() error {
var config tmpl.CTemplateConfig var config tmpl.CTemplateConfig
config.Minify = Config.MinifyTemplates config.Minify = Config.MinifyTemplates
config.SuperDebug = Dev.TemplateDebug config.SuperDebug = Dev.TemplateDebug
@ -235,6 +238,23 @@ func compileTemplates() error {
return err return err
} }
var wg sync.WaitGroup
var writeTemplate = func(name string, content string) {
log.Print("Writing template '" + name + "'")
if content == "" {
log.Fatal("No content body")
}
wg.Add(1)
go func() {
err := writeFile("./template_"+name+".go", content)
if err != nil {
log.Fatal(err)
}
wg.Done()
}()
}
// Let plugins register their own templates // Let plugins register their own templates
DebugLog("Registering the templates for the plugins") DebugLog("Registering the templates for the plugins")
config = c.GetConfig() config = c.GetConfig()
@ -247,20 +267,22 @@ func compileTemplates() error {
if err != nil { if err != nil {
return err return err
} }
go writeTemplate(tmplItem.Name, compiledTmpl) writeTemplate(tmplItem.Name, compiledTmpl)
} }
log.Print("Writing the templates") log.Print("Writing the templates")
go writeTemplate("topic", topicIDTmpl) writeTemplate("topic", topicIDTmpl)
go writeTemplate("topic_alt", topicIDAltTmpl) writeTemplate("topic_alt", topicIDAltTmpl)
go writeTemplate("profile", profileTmpl) writeTemplate("profile", profileTmpl)
go writeTemplate("forums", forumsTmpl) writeTemplate("forums", forumsTmpl)
go writeTemplate("topics", topicsTmpl) writeTemplate("topics", topicsTmpl)
go writeTemplate("forum", forumTmpl) writeTemplate("forum", forumTmpl)
go writeTemplate("login", loginTmpl) writeTemplate("login", loginTmpl)
go writeTemplate("register", registerTmpl) writeTemplate("register", registerTmpl)
go writeTemplate("ip_search", ipSearchTmpl) writeTemplate("ip_search", ipSearchTmpl)
go writeTemplate("error", errorTmpl) writeTemplate("error", errorTmpl)
wg.Add(1)
go func() { go func() {
out := "package main\n\n" out := "package main\n\n"
for templateName, count := range c.TemplateFragmentCount { for templateName, count := range c.TemplateFragmentCount {
@ -271,26 +293,15 @@ func compileTemplates() error {
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
wg.Done()
}() }()
wg.Wait()
return nil return nil
} }
func writeTemplate(name string, content string) {
err := writeFile("./template_"+name+".go", content)
if err != nil {
log.Fatal(err)
}
}
func InitTemplates() error { func InitTemplates() error {
if Dev.DebugMode { DebugLog("Initialising the template system")
log.Print("Initialising the template system")
}
err := compileTemplates()
if err != nil {
return err
}
// TODO: Add support for 64-bit integers // TODO: Add support for 64-bit integers
// TODO: Add support for floats // TODO: Add support for floats
@ -365,7 +376,34 @@ func InitTemplates() error {
// The interpreted templates... // The interpreted templates...
DebugLog("Loading the template files...") DebugLog("Loading the template files...")
Templates.Funcs(fmap) Templates.Funcs(fmap)
template.Must(Templates.ParseGlob("templates/*")) templateFiles, err := filepath.Glob("templates/*.html")
if err != nil {
return err
}
var templateFileMap = make(map[string]int)
for index, path := range templateFiles {
path = strings.Replace(path, "\\", "/", -1)
log.Print("templateFile: ", path)
templateFileMap[path] = index
}
overrideFiles, err := filepath.Glob("templates/overrides/*.html")
if err != nil {
return err
}
for _, path := range overrideFiles {
path = strings.Replace(path, "\\", "/", -1)
log.Print("overrideFile: ", path)
index, ok := templateFileMap["templates/"+strings.TrimPrefix(path, "templates/overrides/")]
if !ok {
log.Print("not ok: templates/" + strings.TrimPrefix(path, "templates/overrides/"))
templateFiles = append(templateFiles, path)
continue
}
templateFiles[index] = path
}
template.Must(Templates.ParseFiles(templateFiles...))
template.Must(Templates.ParseGlob("pages/*")) template.Must(Templates.ParseGlob("pages/*"))
return nil return nil

View File

@ -109,9 +109,14 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe
c.expectsInt = expectsInt c.expectsInt = expectsInt
holdreflect := reflect.ValueOf(expectsInt) holdreflect := reflect.ValueOf(expectsInt)
res, err := ioutil.ReadFile(fileDir + name) res, err := ioutil.ReadFile(fileDir + "overrides/" + name)
if err != nil { if err != nil {
return "", err c.detail("override path: ", fileDir+"overrides/"+name)
c.detail("override err: ", err)
res, err = ioutil.ReadFile(fileDir + name)
if err != nil {
return "", err
}
} }
content := string(res) content := string(res)
@ -125,14 +130,14 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe
if err != nil { if err != nil {
return "", err return "", err
} }
c.log(name) c.detail(name)
out = "" out = ""
fname := strings.TrimSuffix(name, filepath.Ext(name)) fname := strings.TrimSuffix(name, filepath.Ext(name))
c.templateList = map[string]*parse.Tree{fname: tree} c.templateList = map[string]*parse.Tree{fname: tree}
varholder := "tmpl_" + fname + "_vars" varholder := "tmpl_" + fname + "_vars"
c.log(c.templateList) c.detail(c.templateList)
c.localVars = make(map[string]map[string]VarItemReflect) c.localVars = make(map[string]map[string]VarItemReflect)
c.localVars[fname] = make(map[string]VarItemReflect) c.localVars[fname] = make(map[string]VarItemReflect)
c.localVars[fname]["."] = VarItemReflect{".", varholder, holdreflect} c.localVars[fname]["."] = VarItemReflect{".", varholder, holdreflect}
@ -203,16 +208,16 @@ w.Write([]byte(`, " + ", -1)
} }
fmt.Println(" ") fmt.Println(" ")
} }
c.log("Output!") c.detail("Output!")
c.log(fout) c.detail(fout)
return fout, nil return fout, nil
} }
func (c *CTemplateSet) rootIterate(tree *parse.Tree, varholder string, holdreflect reflect.Value, fname string) (out string) { func (c *CTemplateSet) rootIterate(tree *parse.Tree, varholder string, holdreflect reflect.Value, fname string) (out string) {
c.log(tree.Root) c.detail(tree.Root)
treeLength := len(tree.Root.Nodes) treeLength := len(tree.Root.Nodes)
for index, node := range tree.Root.Nodes { for index, node := range tree.Root.Nodes {
c.log("Node:", node.String()) c.detail("Node:", node.String())
c.previousNode = c.currentNode c.previousNode = c.currentNode
c.currentNode = node.Type() c.currentNode = node.Type()
if treeLength != (index + 1) { if treeLength != (index + 1) {
@ -224,10 +229,10 @@ func (c *CTemplateSet) rootIterate(tree *parse.Tree, varholder string, holdrefle
} }
func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value, templateName string, node parse.Node) (out string) { func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value, templateName string, node parse.Node) (out string) {
c.log("in compileSwitch") c.detail("in compileSwitch")
switch node := node.(type) { switch node := node.(type) {
case *parse.ActionNode: case *parse.ActionNode:
c.log("Action Node") c.detail("Action Node")
if node.Pipe == nil { if node.Pipe == nil {
break break
} }
@ -235,30 +240,30 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value
out += c.compileSubswitch(varholder, holdreflect, templateName, cmd) out += c.compileSubswitch(varholder, holdreflect, templateName, cmd)
} }
case *parse.IfNode: case *parse.IfNode:
c.log("If Node:") c.detail("If Node:")
c.log("node.Pipe", node.Pipe) c.detail("node.Pipe", node.Pipe)
var expr string var expr string
for _, cmd := range node.Pipe.Cmds { for _, cmd := range node.Pipe.Cmds {
c.log("If Node Bit:", cmd) c.detail("If Node Bit:", cmd)
c.log("Bit Type:", reflect.ValueOf(cmd).Type().Name()) c.detail("Bit Type:", reflect.ValueOf(cmd).Type().Name())
expr += c.compileVarswitch(varholder, holdreflect, templateName, cmd) expr += c.compileVarswitch(varholder, holdreflect, templateName, cmd)
c.log("Expression Step:", c.compileVarswitch(varholder, holdreflect, templateName, cmd)) c.detail("Expression Step:", c.compileVarswitch(varholder, holdreflect, templateName, cmd))
} }
c.log("Expression:", expr) c.detail("Expression:", expr)
c.previousNode = c.currentNode c.previousNode = c.currentNode
c.currentNode = parse.NodeList c.currentNode = parse.NodeList
c.nextNode = -1 c.nextNode = -1
out = "if " + expr + " {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.List) + "}" out = "if " + expr + " {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.List) + "}"
if node.ElseList == nil { if node.ElseList == nil {
c.log("Selected Branch 1") c.detail("Selected Branch 1")
return out + "\n" return out + "\n"
} }
c.log("Selected Branch 2") c.detail("Selected Branch 2")
return out + " else {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.ElseList) + "}\n" return out + " else {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.ElseList) + "}\n"
case *parse.ListNode: case *parse.ListNode:
c.log("List Node") c.detail("List Node")
for _, subnode := range node.Nodes { for _, subnode := range node.Nodes {
out += c.compileSwitch(varholder, holdreflect, templateName, subnode) out += c.compileSwitch(varholder, holdreflect, templateName, subnode)
} }
@ -291,15 +296,15 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value
} }
func (c *CTemplateSet) compileRangeNode(varholder string, holdreflect reflect.Value, templateName string, node *parse.RangeNode) (out string) { func (c *CTemplateSet) compileRangeNode(varholder string, holdreflect reflect.Value, templateName string, node *parse.RangeNode) (out string) {
c.log("Range Node!") c.detail("Range Node!")
c.log(node.Pipe) c.detail(node.Pipe)
var outVal reflect.Value var outVal reflect.Value
for _, cmd := range node.Pipe.Cmds { for _, cmd := range node.Pipe.Cmds {
c.log("Range Bit:", cmd) c.detail("Range Bit:", cmd)
out, outVal = c.compileReflectSwitch(varholder, holdreflect, templateName, cmd) out, outVal = c.compileReflectSwitch(varholder, holdreflect, templateName, cmd)
} }
c.log("Returned:", out) c.detail("Returned:", out)
c.log("Range Kind Switch!") c.detail("Range Kind Switch!")
switch outVal.Kind() { switch outVal.Kind() {
case reflect.Map: case reflect.Map:
@ -308,7 +313,7 @@ func (c *CTemplateSet) compileRangeNode(varholder string, holdreflect reflect.Va
item = outVal.MapIndex(key) item = outVal.MapIndex(key)
} }
c.log("Range item:", item) c.detail("Range item:", item)
if !item.IsValid() { if !item.IsValid() {
panic("item" + "^\n" + "Invalid map. Maybe, it doesn't have any entries for the template engine to analyse?") panic("item" + "^\n" + "Invalid map. Maybe, it doesn't have any entries for the template engine to analyse?")
} }
@ -334,11 +339,11 @@ func (c *CTemplateSet) compileRangeNode(varholder string, holdreflect reflect.Va
} }
func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) { func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) {
c.log("in compileSubswitch") c.detail("in compileSubswitch")
firstWord := node.Args[0] firstWord := node.Args[0]
switch n := firstWord.(type) { switch n := firstWord.(type) {
case *parse.FieldNode: case *parse.FieldNode:
c.log("Field Node:", n.Ident) c.detail("Field Node:", n.Ident)
/* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Variable declarations are coming soon! */ /* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Variable declarations are coming soon! */
cur := holdreflect cur := holdreflect
@ -351,12 +356,12 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va
// ! Might not work so well for non-struct pointers // ! Might not work so well for non-struct pointers
skipPointers := func(cur reflect.Value, id string) reflect.Value { skipPointers := func(cur reflect.Value, id string) reflect.Value {
if cur.Kind() == reflect.Ptr { if cur.Kind() == reflect.Ptr {
c.log("Looping over pointer") c.detail("Looping over pointer")
for cur.Kind() == reflect.Ptr { for cur.Kind() == reflect.Ptr {
cur = cur.Elem() cur = cur.Elem()
} }
c.log("Data Kind:", cur.Kind().String()) c.detail("Data Kind:", cur.Kind().String())
c.log("Field Bit:", id) c.detail("Field Bit:", id)
} }
return cur return cur
} }
@ -364,8 +369,8 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va
var assLines string var assLines string
var multiline = false var multiline = false
for _, id := range n.Ident { for _, id := range n.Ident {
c.log("Data Kind:", cur.Kind().String()) c.detail("Data Kind:", cur.Kind().String())
c.log("Field Bit:", id) c.detail("Field Bit:", id)
cur = skipPointers(cur, id) cur = skipPointers(cur, id)
if !cur.IsValid() { if !cur.IsValid() {
@ -382,7 +387,7 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va
panic(varbit + "^\n" + "Invalid value. Maybe, it doesn't exist?") panic(varbit + "^\n" + "Invalid value. Maybe, it doesn't exist?")
} }
c.log("in-loop varbit: " + varbit) c.detail("in-loop varbit: " + varbit)
if cur.Kind() == reflect.Map { if cur.Kind() == reflect.Map {
cur = cur.MapIndex(reflect.ValueOf(id)) cur = cur.MapIndex(reflect.ValueOf(id))
varbit += "[\"" + id + "\"]" varbit += "[\"" + id + "\"]"
@ -427,7 +432,7 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va
} }
varbit += cur.Type().Name() + ")" varbit += cur.Type().Name() + ")"
} }
c.log("End Cycle: ", varbit) c.detail("End Cycle: ", varbit)
} }
if multiline { if multiline {
@ -446,20 +451,20 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va
} }
return out return out
case *parse.DotNode: case *parse.DotNode:
c.log("Dot Node:", node.String()) c.detail("Dot Node:", node.String())
return c.compileVarsub(varholder, holdreflect, "") return c.compileVarsub(varholder, holdreflect, "")
case *parse.NilNode: case *parse.NilNode:
panic("Nil is not a command x.x") panic("Nil is not a command x.x")
case *parse.VariableNode: case *parse.VariableNode:
c.log("Variable Node:", n.String()) c.detail("Variable Node:", n.String())
c.log(n.Ident) c.detail(n.Ident)
varname, reflectVal := c.compileIfVarsub(n.String(), varholder, templateName, holdreflect) varname, reflectVal := c.compileIfVarsub(n.String(), varholder, templateName, holdreflect)
return c.compileVarsub(varname, reflectVal, "") return c.compileVarsub(varname, reflectVal, "")
case *parse.StringNode: case *parse.StringNode:
return n.Quoted return n.Quoted
case *parse.IdentifierNode: case *parse.IdentifierNode:
c.log("Identifier Node:", node) c.detail("Identifier Node:", node)
c.log("Identifier Node Args:", node.Args) c.detail("Identifier Node Args:", node.Args)
out, outval, lit := c.compileIdentSwitch(varholder, holdreflect, templateName, node) out, outval, lit := c.compileIdentSwitch(varholder, holdreflect, templateName, node)
if lit { if lit {
return out return out
@ -471,7 +476,7 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va
} }
func (c *CTemplateSet) compileVarswitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) { func (c *CTemplateSet) compileVarswitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) {
c.log("in compileVarswitch") c.detail("in compileVarswitch")
firstWord := node.Args[0] firstWord := node.Args[0]
switch n := firstWord.(type) { switch n := firstWord.(type) {
case *parse.FieldNode: case *parse.FieldNode:
@ -485,26 +490,26 @@ func (c *CTemplateSet) compileVarswitch(varholder string, holdreflect reflect.Va
/* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Coming Soon. */ /* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Coming Soon. */
return c.compileBoolsub(n.String(), varholder, templateName, holdreflect) return c.compileBoolsub(n.String(), varholder, templateName, holdreflect)
case *parse.ChainNode: case *parse.ChainNode:
c.log("Chain Node:", n.Node) c.detail("Chain Node:", n.Node)
c.log("Node Args:", node.Args) c.detail("Node Args:", node.Args)
case *parse.IdentifierNode: case *parse.IdentifierNode:
c.log("Identifier Node:", node) c.detail("Identifier Node:", node)
c.log("Node Args:", node.Args) c.detail("Node Args:", node.Args)
return c.compileIdentSwitchN(varholder, holdreflect, templateName, node) return c.compileIdentSwitchN(varholder, holdreflect, templateName, node)
case *parse.DotNode: case *parse.DotNode:
return varholder return varholder
case *parse.VariableNode: case *parse.VariableNode:
c.log("Variable Node:", n.String()) c.detail("Variable Node:", n.String())
c.log("Node Identifier:", n.Ident) c.detail("Node Identifier:", n.Ident)
out, _ = c.compileIfVarsub(n.String(), varholder, templateName, holdreflect) out, _ = c.compileIfVarsub(n.String(), varholder, templateName, holdreflect)
case *parse.NilNode: case *parse.NilNode:
panic("Nil is not a command x.x") panic("Nil is not a command x.x")
case *parse.PipeNode: case *parse.PipeNode:
c.log("Pipe Node!") c.detail("Pipe Node!")
c.log(n) c.detail(n)
c.log("Node Args:", node.Args) c.detail("Node Args:", node.Args)
out += c.compileIdentSwitchN(varholder, holdreflect, templateName, node) out += c.compileIdentSwitchN(varholder, holdreflect, templateName, node)
c.log("Out:", out) c.detail("Out:", out)
default: default:
return c.unknownNode(firstWord) return c.unknownNode(firstWord)
} }
@ -518,15 +523,15 @@ func (c *CTemplateSet) unknownNode(node parse.Node) (out string) {
} }
func (c *CTemplateSet) compileIdentSwitchN(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) { func (c *CTemplateSet) compileIdentSwitchN(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) {
c.log("in compileIdentSwitchN") c.detail("in compileIdentSwitchN")
out, _, _ = c.compileIdentSwitch(varholder, holdreflect, templateName, node) out, _, _ = c.compileIdentSwitch(varholder, holdreflect, templateName, node)
return out return out
} }
func (c *CTemplateSet) dumpSymbol(pos int, node *parse.CommandNode, symbol string) { func (c *CTemplateSet) dumpSymbol(pos int, node *parse.CommandNode, symbol string) {
c.log("symbol: ", symbol) c.detail("symbol: ", symbol)
c.log("node.Args[pos + 1]", node.Args[pos+1]) c.detail("node.Args[pos + 1]", node.Args[pos+1])
c.log("node.Args[pos + 2]", node.Args[pos+2]) c.detail("node.Args[pos + 2]", node.Args[pos+2])
} }
func (c *CTemplateSet) compareFunc(varholder string, holdreflect reflect.Value, templateName string, pos int, node *parse.CommandNode, compare string) (out string) { func (c *CTemplateSet) compareFunc(varholder string, holdreflect reflect.Value, templateName string, pos int, node *parse.CommandNode, compare string) (out string) {
@ -552,7 +557,7 @@ func (c *CTemplateSet) simpleMath(varholder string, holdreflect reflect.Value, t
} }
func (c *CTemplateSet) compareJoin(varholder string, holdreflect reflect.Value, templateName string, pos int, node *parse.CommandNode, symbol string) (pos2 int, out string) { func (c *CTemplateSet) compareJoin(varholder string, holdreflect reflect.Value, templateName string, pos int, node *parse.CommandNode, symbol string) (pos2 int, out string) {
c.logf("Building %s function", symbol) c.detailf("Building %s function", symbol)
if pos == 0 { if pos == 0 {
fmt.Println("pos:", pos) fmt.Println("pos:", pos)
panic(symbol + " is missing a left operand") panic(symbol + " is missing a left operand")
@ -572,24 +577,24 @@ func (c *CTemplateSet) compareJoin(varholder string, holdreflect reflect.Value,
} }
out = left + " " + symbol + " " + right out = left + " " + symbol + " " + right
c.log("Left operand:", node.Args[pos-1]) c.detail("Left operand:", node.Args[pos-1])
c.log("Right operand:", node.Args[pos+1]) c.detail("Right operand:", node.Args[pos+1])
if !funcExists { if !funcExists {
pos++ pos++
} }
c.log("pos:", pos) c.detail("pos:", pos)
c.log("len(node.Args):", len(node.Args)) c.detail("len(node.Args):", len(node.Args))
return pos, out return pos, out
} }
func (c *CTemplateSet) compileIdentSwitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string, val reflect.Value, literal bool) { func (c *CTemplateSet) compileIdentSwitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string, val reflect.Value, literal bool) {
c.log("in compileIdentSwitch") c.detail("in compileIdentSwitch")
ArgLoop: ArgLoop:
for pos := 0; pos < len(node.Args); pos++ { for pos := 0; pos < len(node.Args); pos++ {
id := node.Args[pos] id := node.Args[pos]
c.log("pos:", pos) c.detail("pos:", pos)
c.log("ID:", id) c.detail("ID:", id)
switch id.String() { switch id.String() {
case "not": case "not":
out += "!" out += "!"
@ -683,7 +688,7 @@ ArgLoop:
literal = true literal = true
break ArgLoop break ArgLoop
default: default:
c.log("Variable!") c.detail("Variable!")
if len(node.Args) > (pos + 1) { if len(node.Args) > (pos + 1) {
nextNode := node.Args[pos+1].String() nextNode := node.Args[pos+1].String()
if nextNode == "or" || nextNode == "and" { if nextNode == "or" || nextNode == "and" {
@ -697,7 +702,7 @@ ArgLoop:
} }
func (c *CTemplateSet) compileReflectSwitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string, outVal reflect.Value) { func (c *CTemplateSet) compileReflectSwitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string, outVal reflect.Value) {
c.log("in compileReflectSwitch") c.detail("in compileReflectSwitch")
firstWord := node.Args[0] firstWord := node.Args[0]
switch n := firstWord.(type) { switch n := firstWord.(type) {
case *parse.FieldNode: case *parse.FieldNode:
@ -710,8 +715,8 @@ func (c *CTemplateSet) compileReflectSwitch(varholder string, holdreflect reflec
/* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Coming Soon. */ /* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Coming Soon. */
return c.compileIfVarsub(n.String(), varholder, templateName, holdreflect) return c.compileIfVarsub(n.String(), varholder, templateName, holdreflect)
case *parse.ChainNode: case *parse.ChainNode:
c.log("Chain Node:", n.Node) c.detail("Chain Node:", n.Node)
c.log("node.Args:", node.Args) c.detail("node.Args:", node.Args)
case *parse.DotNode: case *parse.DotNode:
return varholder, holdreflect return varholder, holdreflect
case *parse.NilNode: case *parse.NilNode:
@ -723,13 +728,13 @@ func (c *CTemplateSet) compileReflectSwitch(varholder string, holdreflect reflec
} }
func (c *CTemplateSet) compileIfVarsubN(varname string, varholder string, templateName string, cur reflect.Value) (out string) { func (c *CTemplateSet) compileIfVarsubN(varname string, varholder string, templateName string, cur reflect.Value) (out string) {
c.log("in compileIfVarsubN") c.detail("in compileIfVarsubN")
out, _ = c.compileIfVarsub(varname, varholder, templateName, cur) out, _ = c.compileIfVarsub(varname, varholder, templateName, cur)
return out return out
} }
func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templateName string, cur reflect.Value) (out string, val reflect.Value) { func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templateName string, cur reflect.Value) (out string, val reflect.Value) {
c.log("in compileIfVarsub") c.detail("in compileIfVarsub")
if varname[0] != '.' && varname[0] != '$' { if varname[0] != '.' && varname[0] != '$' {
return varname, cur return varname, cur
} }
@ -757,22 +762,22 @@ func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templat
} }
bits[0] = strings.TrimPrefix(bits[0], "$") bits[0] = strings.TrimPrefix(bits[0], "$")
c.log("Cur Kind:", cur.Kind()) c.detail("Cur Kind:", cur.Kind())
c.log("Cur Type:", cur.Type().Name()) c.detail("Cur Type:", cur.Type().Name())
for _, bit := range bits { for _, bit := range bits {
c.log("Variable Field:", bit) c.detail("Variable Field:", bit)
if bit == "" { if bit == "" {
continue continue
} }
// TODO: Fix this up so that it works for regular pointers and not just struct pointers. Ditto for the other cur.Kind() == reflect.Ptr we have in this file // TODO: Fix this up so that it works for regular pointers and not just struct pointers. Ditto for the other cur.Kind() == reflect.Ptr we have in this file
if cur.Kind() == reflect.Ptr { if cur.Kind() == reflect.Ptr {
c.log("Looping over pointer") c.detail("Looping over pointer")
for cur.Kind() == reflect.Ptr { for cur.Kind() == reflect.Ptr {
cur = cur.Elem() cur = cur.Elem()
} }
c.log("Data Kind:", cur.Kind().String()) c.detail("Data Kind:", cur.Kind().String())
c.log("Field Bit:", bit) c.detail("Field Bit:", bit)
} }
cur = cur.FieldByName(bit) cur = cur.FieldByName(bit)
@ -784,13 +789,13 @@ func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templat
if !cur.IsValid() { if !cur.IsValid() {
panic(out + "^\n" + "Invalid value. Maybe, it doesn't exist?") panic(out + "^\n" + "Invalid value. Maybe, it doesn't exist?")
} }
c.log("Data Kind:", cur.Kind()) c.detail("Data Kind:", cur.Kind())
c.log("Data Type:", cur.Type().Name()) c.detail("Data Type:", cur.Type().Name())
} }
c.log("Out Value:", out) c.detail("Out Value:", out)
c.log("Out Kind:", cur.Kind()) c.detail("Out Kind:", cur.Kind())
c.log("Out Type:", cur.Type().Name()) c.detail("Out Type:", cur.Type().Name())
for _, varItem := range c.varList { for _, varItem := range c.varList {
if strings.HasPrefix(out, varItem.Destination) { if strings.HasPrefix(out, varItem.Destination) {
@ -798,9 +803,9 @@ func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templat
} }
} }
c.log("Out Value:", out) c.detail("Out Value:", out)
c.log("Out Kind:", cur.Kind()) c.detail("Out Kind:", cur.Kind())
c.log("Out Type:", cur.Type().Name()) c.detail("Out Type:", cur.Type().Name())
_, ok := c.stats[out] _, ok := c.stats[out]
if ok { if ok {
@ -813,7 +818,7 @@ func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templat
} }
func (c *CTemplateSet) compileBoolsub(varname string, varholder string, templateName string, val reflect.Value) string { func (c *CTemplateSet) compileBoolsub(varname string, varholder string, templateName string, val reflect.Value) string {
c.log("in compileBoolsub") c.detail("in compileBoolsub")
out, val := c.compileIfVarsub(varname, varholder, templateName, val) out, val := c.compileIfVarsub(varname, varholder, templateName, val)
// TODO: What if it's a pointer or an interface? I *think* we've got pointers handled somewhere, but not interfaces which we don't know the types of at compile time // TODO: What if it's a pointer or an interface? I *think* we've got pointers handled somewhere, but not interfaces which we don't know the types of at compile time
switch val.Kind() { switch val.Kind() {
@ -834,7 +839,7 @@ func (c *CTemplateSet) compileBoolsub(varname string, varholder string, template
} }
func (c *CTemplateSet) compileVarsub(varname string, val reflect.Value, assLines string) (out string) { func (c *CTemplateSet) compileVarsub(varname string, val reflect.Value, assLines string) (out string) {
c.log("in compileVarsub") c.detail("in compileVarsub")
// Is this a literal string? // Is this a literal string?
if len(varname) != 0 && varname[0] == '"' { if len(varname) != 0 && varname[0] == '"' {
@ -858,8 +863,8 @@ func (c *CTemplateSet) compileVarsub(varname string, val reflect.Value, assLines
val = val.Elem() val = val.Elem()
} }
c.log("varname: ", varname) c.detail("varname: ", varname)
c.log("assLines: ", assLines) c.detail("assLines: ", assLines)
switch val.Kind() { switch val.Kind() {
case reflect.Int: case reflect.Int:
c.importMap["strconv"] = "strconv" c.importMap["strconv"] = "strconv"
@ -883,13 +888,13 @@ func (c *CTemplateSet) compileVarsub(varname string, val reflect.Value, assLines
fmt.Println("Unknown Type:", val.Type().Name()) fmt.Println("Unknown Type:", val.Type().Name())
panic("-- I don't know what this variable's type is o.o\n") panic("-- I don't know what this variable's type is o.o\n")
} }
c.log("out: ", out) c.detail("out: ", out)
return assLines + out return assLines + out
} }
func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflect.Value, node *parse.TemplateNode) (out string) { func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflect.Value, node *parse.TemplateNode) (out string) {
c.log("in compileSubtemplate") c.detail("in compileSubtemplate")
c.log("Template Node: ", node.Name) c.detail("Template Node: ", node.Name)
fname := strings.TrimSuffix(node.Name, filepath.Ext(node.Name)) fname := strings.TrimSuffix(node.Name, filepath.Ext(node.Name))
varholder := "tmpl_" + fname + "_vars" varholder := "tmpl_" + fname + "_vars"
@ -904,16 +909,21 @@ func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflec
case *parse.NilNode: case *parse.NilNode:
panic("Nil is not a command x.x") panic("Nil is not a command x.x")
default: default:
c.log("Unknown Node: ", firstWord) c.detail("Unknown Node: ", firstWord)
panic("") panic("")
} }
} }
} }
// TODO: Cascade errors back up the tree to the caller? // TODO: Cascade errors back up the tree to the caller?
res, err := ioutil.ReadFile(c.fileDir + node.Name) res, err := ioutil.ReadFile(c.fileDir + "overrides/" + node.Name)
if err != nil { if err != nil {
log.Fatal(err) c.detail("override path: ", c.fileDir+"overrides/"+node.Name)
c.detail("override err: ", err)
res, err = ioutil.ReadFile(c.fileDir + node.Name)
if err != nil {
log.Fatal(err)
}
} }
content := string(res) content := string(res)
@ -930,7 +940,7 @@ func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflec
c.templateList[fname] = tree c.templateList[fname] = tree
subtree := c.templateList[fname] subtree := c.templateList[fname]
c.log("subtree.Root", subtree.Root) c.detail("subtree.Root", subtree.Root)
c.localVars[fname] = make(map[string]VarItemReflect) c.localVars[fname] = make(map[string]VarItemReflect)
c.localVars[fname]["."] = VarItemReflect{".", varholder, holdreflect} c.localVars[fname]["."] = VarItemReflect{".", varholder, holdreflect}
@ -943,13 +953,13 @@ func (c *CTemplateSet) compileSubtemplate(pvarholder string, pholdreflect reflec
// TODO: Should we rethink the way the log methods work or their names? // TODO: Should we rethink the way the log methods work or their names?
func (c *CTemplateSet) log(args ...interface{}) { func (c *CTemplateSet) detail(args ...interface{}) {
if c.config.SuperDebug { if c.config.SuperDebug {
fmt.Println(args...) fmt.Println(args...)
} }
} }
func (c *CTemplateSet) logf(left string, args ...interface{}) { func (c *CTemplateSet) detailf(left string, args ...interface{}) {
if c.config.SuperDebug { if c.config.SuperDebug {
fmt.Printf(left, args...) fmt.Printf(left, args...)
} }

View File

@ -71,6 +71,7 @@ type TemplateMapping struct {
type ThemeResource struct { type ThemeResource struct {
Name string Name string
Location string Location string
Loggedin bool // Only serve this resource to logged in users
} }
type ThemeStmts struct { type ThemeStmts struct {

View File

@ -0,0 +1,15 @@
package adventure
// We're experimenting with struct tags here atm
type Adventure struct {
ID int `schema:"name=aid;primary;auto"`
Name string `schema:"name=name;type=short_text"`
Desc string `schema:"name=desc;type=text"`
CreatedBy int `schema:"name=createdBy"`
//CreatedBy int `schema:"name=createdBy;relatesTo=users.uid"`
}
// TODO: Should we add a table interface?
func (adventure *Adventure) GetTable() string {
return "adventure"
}

View File

@ -0,0 +1,8 @@
package adventure
type AdventureStore interface {
Create() (int, error)
}
type DefaultAdventureStore struct {
}

View File

@ -0,0 +1,7 @@
{
"UName":"adventure",
"Name":"Adventure",
"Author":"Azareal",
"URL":"https://github.com/Azareal/Gosora",
"Skip":true
}

View File

@ -0,0 +1 @@
This file is here so that Git will include this folder in the repository.

View File

@ -0,0 +1 @@
This file is here so that Git will include this folder in the repository.

View File

@ -28,6 +28,9 @@ go get -u github.com/bamiaux/rez
echo "Installing fsnotify" echo "Installing fsnotify"
go get -u github.com/fsnotify/fsnotify go get -u github.com/fsnotify/fsnotify
echo "Installing Go Git"
go get -u gopkg.in/src-d/go-git.v4/...
echo "Building the installer" echo "Building the installer"
cd ./install cd ./install

View File

@ -85,6 +85,13 @@ if %errorlevel% neq 0 (
exit /b %errorlevel% exit /b %errorlevel%
) )
echo Installing Go Git
go get -u gopkg.in/src-d/go-git.v4/...
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the installer echo Building the installer
go generate go generate

View File

@ -198,7 +198,8 @@ func handleDatabaseDetails() (adap install.InstallAdapter, ok bool) {
var dbUsername string var dbUsername string
var dbPassword string var dbPassword string
var dbName string var dbName string
var dbPort string // TODO: Let the admin set the database port?
//var dbPort string
for { for {
fmt.Println("Which database adapter do you wish to use? mysql, mssql, or mysql? Default: mysql") fmt.Println("Which database adapter do you wish to use? mysql, mssql, or mysql? Default: mysql")

View File

@ -231,7 +231,18 @@
"NoticePhrases": { "NoticePhrases": {
"account_banned":"Your account has been suspended. Some of your permissions may have been revoked.", "account_banned":"Your account has been suspended. Some of your permissions may have been revoked.",
"account_inactive":"Your account hasn't been activated yet. Some features may remain unavailable until it is." "account_inactive":"Your account hasn't been activated yet. Some features may remain unavailable until it is.",
"account_password_updated":"Your password was successfully updated",
"account_avatar_updated":"Your avatar was successfully updated",
"account_username_updated":"Your username was successfully updated",
"account_mail_disabled":"The mail system is currently disabled.",
"account_mail_verify_success":"Your email was successfully verified",
"panel_forum_created":"The forum was successfully created",
"panel_forum_deleted":"The forum was successfully deleted",
"panel_forum_updated":"The forum was successfully updated",
"panel_forum_perms_updated":"The forum permissions were successfully updated",
"panel_user_updated":"The user was successfully updated"
}, },
"TmplPhrases": { "TmplPhrases": {

11
main.go
View File

@ -7,6 +7,7 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"io" "io"
"log" "log"
@ -217,6 +218,16 @@ func main() {
} }
defer db.Close() defer db.Close()
buildTemplates := flag.Bool("build-templates", false, "build the templates")
flag.Parse()
if *buildTemplates {
err = common.CompileTemplates()
if err != nil {
log.Fatal(err)
}
return
}
err = afterDBInit() err = afterDBInit()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)

View File

@ -129,12 +129,12 @@ func routeProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user
if err != nil { if err != nil {
return common.LocalError("Invalid UID", w, r, user) return common.LocalError("Invalid UID", w, r, user)
} }
profileOwner, err := common.Users.Get(uid) profileOwner, err := common.Users.Get(uid)
if err == ErrNoRows { if err == ErrNoRows {
return common.LocalError("The profile you're trying to post on doesn't exist.", w, r, user) return common.LocalError("The profile you're trying to post on doesn't exist.", w, r, user)
} else if err != nil { } else if err != nil {
return common.InternalError(err,w,r) return common.InternalError(err, w, r)
} }
content := common.PreparseMessage(r.PostFormValue("reply-content")) content := common.PreparseMessage(r.PostFormValue("reply-content"))
@ -278,7 +278,7 @@ func routeAccountEditCriticalSubmit(w http.ResponseWriter, r *http.Request, user
// Log the user out as a safety precaution // Log the user out as a safety precaution
common.Auth.ForceLogout(user.ID) common.Auth.ForceLogout(user.ID)
headerVars.NoticeList = append(headerVars.NoticeList, "Your password was successfully updated") headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_password_updated"))
pi := common.Page{"Edit Password", user, headerVars, tList, nil} pi := common.Page{"Edit Password", user, headerVars, tList, nil}
if common.RunPreRenderHook("pre_render_account_own_edit_critical", w, r, &user, &pi) { if common.RunPreRenderHook("pre_render_account_own_edit_critical", w, r, &user, &pi) {
return nil return nil
@ -367,7 +367,7 @@ func routeAccountEditAvatarSubmit(w http.ResponseWriter, r *http.Request, user c
return common.InternalError(err, w, r) return common.InternalError(err, w, r)
} }
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + "." + ext user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + "." + ext
headerVars.NoticeList = append(headerVars.NoticeList, "Your avatar was successfully updated") headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_avatar_updated"))
pi := common.Page{"Edit Avatar", user, headerVars, tList, nil} pi := common.Page{"Edit Avatar", user, headerVars, tList, nil}
if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) { if common.RunPreRenderHook("pre_render_account_own_edit_avatar", w, r, &user, &pi) {
@ -410,7 +410,7 @@ func routeAccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user
} }
user.Name = newUsername user.Name = newUsername
headerVars.NoticeList = append(headerVars.NoticeList, "Your username was successfully updated") headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_username_updated"))
pi := common.Page{"Edit Username", user, headerVars, tList, nil} pi := common.Page{"Edit Username", user, headerVars, tList, nil}
if common.RunPreRenderHook("pre_render_account_own_edit_username", w, r, &user, &pi) { if common.RunPreRenderHook("pre_render_account_own_edit_username", w, r, &user, &pi) {
return nil return nil
@ -461,7 +461,7 @@ func routeAccountEditEmail(w http.ResponseWriter, r *http.Request, user common.U
emailList = append(emailList, email) emailList = append(emailList, email)
} }
if !common.Site.EnableEmails { if !common.Site.EnableEmails {
headerVars.NoticeList = append(headerVars.NoticeList, "The mail system is currently disabled.") headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_mail_disabled"))
} }
pi := common.Page{"Email Manager", user, headerVars, emailList, nil} pi := common.Page{"Email Manager", user, headerVars, emailList, nil}
@ -531,9 +531,9 @@ func routeAccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, us
} }
if !common.Site.EnableEmails { if !common.Site.EnableEmails {
headerVars.NoticeList = append(headerVars.NoticeList, "The mail system is currently disabled.") headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_mail_disabled"))
} }
headerVars.NoticeList = append(headerVars.NoticeList, "Your email was successfully verified") headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("account_mail_verify_success"))
pi := common.Page{"Email Manager", user, headerVars, emailList, nil} pi := common.Page{"Email Manager", user, headerVars, emailList, nil}
if common.RunPreRenderHook("pre_render_account_own_edit_email", w, r, &user, &pi) { if common.RunPreRenderHook("pre_render_account_own_edit_email", w, r, &user, &pi) {
return nil return nil

View File

@ -198,11 +198,11 @@ func routePanelForums(w http.ResponseWriter, r *http.Request, user common.User)
} }
if r.FormValue("created") == "1" { if r.FormValue("created") == "1" {
headerVars.NoticeList = append(headerVars.NoticeList, "The forum was successfully created") headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("panel_forum_created"))
} else if r.FormValue("deleted") == "1" { } else if r.FormValue("deleted") == "1" {
headerVars.NoticeList = append(headerVars.NoticeList, "The forum was successfully deleted") headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("panel_forum_deleted"))
} else if r.FormValue("updated") == "1" { } else if r.FormValue("updated") == "1" {
headerVars.NoticeList = append(headerVars.NoticeList, "The forum was successfully updated") headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("panel_forum_updated"))
} }
pi := common.PanelPage{common.GetTitlePhrase("panel_forums"), user, headerVars, stats, "forums", forumList, nil} pi := common.PanelPage{common.GetTitlePhrase("panel_forums"), user, headerVars, stats, "forums", forumList, nil}
@ -335,7 +335,7 @@ func routePanelForumsEdit(w http.ResponseWriter, r *http.Request, user common.Us
} }
if r.FormValue("updated") == "1" { if r.FormValue("updated") == "1" {
headerVars.NoticeList = append(headerVars.NoticeList, "The forum was successfully updated") headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("panel_forum_updated"))
} }
pi := common.PanelEditForumPage{common.GetTitlePhrase("panel_edit_forum"), user, headerVars, stats, "forums", forum.ID, forum.Name, forum.Desc, forum.Active, forum.Preset, gplist} pi := common.PanelEditForumPage{common.GetTitlePhrase("panel_edit_forum"), user, headerVars, stats, "forums", forum.ID, forum.Name, forum.Desc, forum.Active, forum.Preset, gplist}
@ -501,7 +501,7 @@ func routePanelForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, us
addNameLangToggle("MoveTopic", forumPerms.MoveTopic) addNameLangToggle("MoveTopic", forumPerms.MoveTopic)
if r.FormValue("updated") == "1" { if r.FormValue("updated") == "1" {
headerVars.NoticeList = append(headerVars.NoticeList, "The forum permissions were successfully updated") headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("panel_forums_perms_updated"))
} }
pi := common.PanelEditForumGroupPage{common.GetTitlePhrase("panel_edit_forum"), user, headerVars, stats, "forums", forum.ID, gid, forum.Name, forum.Desc, forum.Active, forum.Preset, formattedPermList} pi := common.PanelEditForumGroupPage{common.GetTitlePhrase("panel_edit_forum"), user, headerVars, stats, "forums", forum.ID, gid, forum.Name, forum.Desc, forum.Active, forum.Preset, formattedPermList}
@ -1794,7 +1794,7 @@ func routePanelUsersEdit(w http.ResponseWriter, r *http.Request, user common.Use
} }
if r.FormValue("updated") == "1" { if r.FormValue("updated") == "1" {
headerVars.NoticeList = append(headerVars.NoticeList, "The user was successfully updated") headerVars.NoticeList = append(headerVars.NoticeList, common.GetNoticePhrase("panel_user_updated"))
} }
pi := common.PanelPage{common.GetTitlePhrase("panel_edit_user"), user, headerVars, stats, "users", groupList, targetUser} pi := common.PanelPage{common.GetTitlePhrase("panel_edit_user"), user, headerVars, stats, "users", groupList, targetUser}

20
plugin_adventure.go Normal file
View File

@ -0,0 +1,20 @@
// WIP - Experimental adventure plugin, this might find a new home soon, but it's here to stress test Gosora's extensibility for now
package main
import "./common"
func init() {
common.Plugins["adventure"] = common.NewPlugin("adventure", "WIP", "Azareal", "http://github.com/Azareal", "", "", "", initAdventure, nil, deactivateAdventure, installAdventure, nil)
}
func initAdventure() error {
return nil
}
// TODO: Change the signature to return an error?
func deactivateAdventure() {
}
func installAdventure() error {
return nil
}

View File

@ -2,5 +2,7 @@ echo "Generating the dynamic code"
go generate go generate
echo "Building Gosora" echo "Building Gosora"
go build -o Gosora go build -o Gosora
echo "Building the templates"
./Gosora -build-templates
echo "Running Gosora" echo "Running Gosora"
./Gosora ./Gosora

View File

@ -2,5 +2,7 @@ echo "Generating the dynamic code"
go generate go generate
echo "Building Gosora" echo "Building Gosora"
go build -o Gosora -tags no_ws go build -o Gosora -tags no_ws
echo "Building the templates"
./Gosora -build-templates
echo "Running Gosora" echo "Running Gosora"
./Gosora ./Gosora

View File

@ -14,6 +14,10 @@ if %errorlevel% neq 0 (
) )
echo Running the router generator echo Running the router generator
router_gen.exe router_gen.exe
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the query generator echo Building the query generator
go build ./query_gen go build ./query_gen
@ -23,6 +27,10 @@ if %errorlevel% neq 0 (
) )
echo Running the query generator echo Running the query generator
query_gen.exe query_gen.exe
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the executable echo Building the executable
go build -o gosora.exe -tags no_ws go build -o gosora.exe -tags no_ws
@ -31,6 +39,13 @@ if %errorlevel% neq 0 (
exit /b %errorlevel% exit /b %errorlevel%
) )
echo Building the templates
gosora.exe -build-templates
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Running Gosora echo Running Gosora
gosora.exe gosora.exe
pause pause

15
run.bat
View File

@ -14,6 +14,10 @@ if %errorlevel% neq 0 (
) )
echo Running the router generator echo Running the router generator
router_gen.exe router_gen.exe
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the query generator echo Building the query generator
go build ./query_gen go build ./query_gen
@ -23,6 +27,10 @@ if %errorlevel% neq 0 (
) )
echo Running the query generator echo Running the query generator
query_gen.exe query_gen.exe
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the executable echo Building the executable
go build -o gosora.exe go build -o gosora.exe
@ -31,6 +39,13 @@ if %errorlevel% neq 0 (
exit /b %errorlevel% exit /b %errorlevel%
) )
echo Building the templates
gosora.exe -build-templates
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Running Gosora echo Running Gosora
gosora.exe gosora.exe
rem Or you could redirect the output to a file rem Or you could redirect the output to a file

View File

@ -14,6 +14,10 @@ if %errorlevel% neq 0 (
) )
echo Running the router generator echo Running the router generator
router_gen.exe router_gen.exe
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the query generator echo Building the query generator
go build ./query_gen go build ./query_gen
@ -23,6 +27,10 @@ if %errorlevel% neq 0 (
) )
echo Running the query generator echo Running the query generator
query_gen.exe query_gen.exe
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the executable echo Building the executable
go build -o gosora.exe -tags mssql go build -o gosora.exe -tags mssql
@ -31,6 +39,13 @@ if %errorlevel% neq 0 (
exit /b %errorlevel% exit /b %errorlevel%
) )
echo Building the templates
gosora.exe -build-templates
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Running Gosora echo Running Gosora
gosora.exe gosora.exe
pause pause

View File

@ -14,6 +14,10 @@ if %errorlevel% neq 0 (
) )
echo Running the router generator echo Running the router generator
router_gen.exe router_gen.exe
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the query generator echo Building the query generator
go build ./query_gen go build ./query_gen
@ -23,6 +27,10 @@ if %errorlevel% neq 0 (
) )
echo Running the query generator echo Running the query generator
query_gen.exe query_gen.exe
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the executable echo Building the executable
go test go test

View File

@ -14,6 +14,10 @@ if %errorlevel% neq 0 (
) )
echo Running the router generator echo Running the router generator
router_gen.exe router_gen.exe
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the query generator echo Building the query generator
go build ./query_gen go build ./query_gen
@ -23,6 +27,10 @@ if %errorlevel% neq 0 (
) )
echo Running the query generator echo Running the query generator
query_gen.exe query_gen.exe
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the executable echo Building the executable
go test -tags mssql go test -tags mssql

3
schema/schema.json Normal file
View File

@ -0,0 +1,3 @@
{
"Version":"0"
}

View File

@ -0,0 +1 @@
This file is here so that Git will include this folder in the repository.

View File

@ -19,11 +19,13 @@
}, },
{ {
"Name":"trumbowyg/trumbowyg.min.js", "Name":"trumbowyg/trumbowyg.min.js",
"Location":"global" "Location":"global",
"Loggedin": true
}, },
{ {
"Name":"trumbowyg/ui/trumbowyg.custom.css", "Name":"trumbowyg/ui/trumbowyg.custom.css",
"Location":"global" "Location":"global",
"Loggedin":true
}, },
{ {
"Name":"cosora/misc.js", "Name":"cosora/misc.js",

View File

@ -26,4 +26,7 @@ echo "Updating the Rez Image Resizer"
go get -u github.com/bamiaux/rez go get -u github.com/bamiaux/rez
echo "Updating fsnotify" echo "Updating fsnotify"
go get -u github.com/fsnotify/fsnotify go get -u github.com/fsnotify/fsnotify
echo "Updating Go Git"
go get -u gopkg.in/src-d/go-git.v4/...

View File

@ -82,5 +82,12 @@ if %errorlevel% neq 0 (
exit /b %errorlevel% exit /b %errorlevel%
) )
echo Updating Go Git
go get -u gopkg.in/src-d/go-git.v4/...
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo The dependencies were successfully updated echo The dependencies were successfully updated
pause pause

103
update.bat Normal file
View File

@ -0,0 +1,103 @@
@echo off
echo Updating the dependencies
echo Updating the MySQL Driver
go get -u github.com/go-sql-driver/mysql
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating the PostgreSQL Driver
go get -u github.com/lib/pq
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating the MSSQL Driver
go get -u github.com/denisenkom/go-mssqldb
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating the bcrypt library
go get -u golang.org/x/crypto/bcrypt
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating /x/sys/windows (dependency for gopsutil)
go get -u golang.org/x/sys/windows
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating wmi (dependency for gopsutil)
go get -u github.com/StackExchange/wmi
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating the gopsutil library
go get -u github.com/Azareal/gopsutil
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating the WebSockets library
go get -u github.com/gorilla/websocket
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating Sourcemap (dependency for OttoJS)
go get -u gopkg.in/sourcemap.v1
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating OttoJS
go get -u github.com/robertkrimen/otto
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating the Rez Image Resizer
go get -u github.com/bamiaux/rez
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating fsnotify
go get -u github.com/fsnotify/fsnotify
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Updating Go Git
go get -u gopkg.in/src-d/go-git.v4/...
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the updater
go generate
go build ./updater
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
updater.exe

68
updater/main.go Normal file
View File

@ -0,0 +1,68 @@
package main
import (
"bufio"
"fmt"
"os"
"runtime/debug"
"gopkg.in/src-d/go-git.v4"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Capture panics instead of closing the window at a superhuman speed before the user can read the message on Windows
defer func() {
r := recover()
if r != nil {
fmt.Println(r)
debug.PrintStack()
pressAnyKey(scanner)
return
}
}()
err := updater(scanner)
if err != nil {
fmt.Println(err)
}
}
func pressAnyKey(scanner *bufio.Scanner) {
fmt.Println("Please press enter to exit...")
for scanner.Scan() {
_ = scanner.Text()
return
}
}
func updater(scanner *bufio.Scanner) error {
fmt.Println("Welcome to Gosora's Upgrader")
fmt.Print("We're going to check for new updates, please wait patiently")
repo, err := git.PlainOpen("./.git")
if err != nil {
return err
}
workTree, err := repo.Worktree()
if err != nil {
return err
}
err = workTree.Pull(&git.PullOptions{RemoteName: "origin"})
if err != nil {
return err
}
fmt.Println("Updated to the latest commit")
headRef, err := repo.Head()
if err != nil {
return err
}
fmt.Println("Commit details:")
commit, err := repo.CommitObject(headRef.Hash())
return err
}