From e2c48c58ba4dceb9b1b279f42eb9b7df53e98849 Mon Sep 17 00:00:00 2001 From: Azareal Date: Tue, 7 Nov 2017 22:38:15 +0000 Subject: [PATCH] Moved the create statement into the TopicStore. Refactored the template generator. Began improving Cosora again. --- gen_mssql.go | 8 - gen_mysql.go | 7 - main.go | 12 + misc_test.go | 2 +- mod_routes.go | 1 - query_gen/lib/accumulator.go | 8 +- query_gen/lib/builder.go | 3 - query_gen/main.go | 2 - rev_templates.go | 113 +++++---- router_gen/routes.go | 1 + templates.go | 423 ++++++++++++++-------------------- themes/cosora/public/main.css | 21 ++ topic_store.go | 8 +- 13 files changed, 282 insertions(+), 327 deletions(-) diff --git a/gen_mssql.go b/gen_mssql.go index becff983..90f081ba 100644 --- a/gen_mssql.go +++ b/gen_mssql.go @@ -45,7 +45,6 @@ type Stmts struct { getForumTopics *sql.Stmt getProfileReplies *sql.Stmt getWatchers *sql.Stmt - createTopic *sql.Stmt createReport *sql.Stmt createActionReply *sql.Stmt createLike *sql.Stmt @@ -388,13 +387,6 @@ func _gen_mssql() (err error) { return err } - log.Print("Preparing createTopic statement.") - stmts.createTopic, err = db.Prepare("INSERT INTO [topics] ([parentID],[title],[content],[parsed_content],[createdAt],[lastReplyAt],[lastReplyBy],[ipaddress],[words],[createdBy]) VALUES (?,?,?,?,GETUTCDATE(),GETUTCDATE(),?,?,?,?)") - if err != nil { - log.Print("Bad Query: ","INSERT INTO [topics] ([parentID],[title],[content],[parsed_content],[createdAt],[lastReplyAt],[lastReplyBy],[ipaddress],[words],[createdBy]) VALUES (?,?,?,?,GETUTCDATE(),GETUTCDATE(),?,?,?,?)") - return err - } - log.Print("Preparing createReport statement.") stmts.createReport, err = db.Prepare("INSERT INTO [topics] ([title],[content],[parsed_content],[createdAt],[lastReplyAt],[createdBy],[lastReplyBy],[data],[parentID],[css_class]) VALUES (?,?,?,GETUTCDATE(),GETUTCDATE(),?,?,?,1,'report')") if err != nil { diff --git a/gen_mysql.go b/gen_mysql.go index 8475633b..0d4fc67a 100644 --- a/gen_mysql.go +++ b/gen_mysql.go @@ -47,7 +47,6 @@ type Stmts struct { getForumTopics *sql.Stmt getProfileReplies *sql.Stmt getWatchers *sql.Stmt - createTopic *sql.Stmt createReport *sql.Stmt createActionReply *sql.Stmt createLike *sql.Stmt @@ -353,12 +352,6 @@ func _gen_mysql() (err error) { return err } - log.Print("Preparing createTopic statement.") - stmts.createTopic, err = db.Prepare("INSERT INTO `topics`(`parentID`,`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`lastReplyBy`,`ipaddress`,`words`,`createdBy`) VALUES (?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,?)") - if err != nil { - return err - } - log.Print("Preparing createReport statement.") stmts.createReport, err = db.Prepare("INSERT INTO `topics`(`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`createdBy`,`lastReplyBy`,`data`,`parentID`,`css_class`) VALUES (?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,1,'report')") if err != nil { diff --git a/main.go b/main.go index f0b835b8..4453a2ec 100644 --- a/main.go +++ b/main.go @@ -94,6 +94,18 @@ func main() { } }()*/ + // WIP: Mango Test + /*res, err := ioutil.ReadFile("./templates/topic.html") + if err != nil { + log.Fatal(err) + } + tagIndices, err := mangoParse(string(res)) + if err != nil { + log.Fatal(err) + } + log.Printf("tagIndices: %+v\n", tagIndices) + log.Fatal("")*/ + // TODO: Have a file for each run with the time/date the server started as the file name? // TODO: Log panics with recover() f, err := os.OpenFile("./operations.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755) diff --git a/misc_test.go b/misc_test.go index 28d49ccb..2182994e 100644 --- a/misc_test.go +++ b/misc_test.go @@ -778,7 +778,7 @@ func TestProfileReplyStore(t *testing.T) { recordMustNotExist(t, err, "PRID #0 shouldn't exist") _, err = prstore.Get(1) - recordMustNotExist(t, err, "PRID #0 shouldn't exist") + recordMustNotExist(t, err, "PRID #1 shouldn't exist") var profileID = 1 prid, err := prstore.Create(profileID, "Haha", 1, "::1") diff --git a/mod_routes.go b/mod_routes.go index a53b90a3..033bdafe 100644 --- a/mod_routes.go +++ b/mod_routes.go @@ -657,7 +657,6 @@ func routeBanSubmit(w http.ResponseWriter, r *http.Request, user User) RouteErro if uid == user.ID { return LocalError("Why are you trying to ban yourself? Stop that.", w, r, user) } - if targetUser.IsBanned { return LocalError("The user you're trying to unban is already banned.", w, r, user) } diff --git a/query_gen/lib/accumulator.go b/query_gen/lib/accumulator.go index 7e3022b0..cddf5ccb 100644 --- a/query_gen/lib/accumulator.go +++ b/query_gen/lib/accumulator.go @@ -163,13 +163,7 @@ func (build *accBuilder) SimpleInsertSelectTx(tx *sql.Tx, ins DB_Insert, sel DB_ func (build *accBuilder) SimpleInsertLeftJoinTx(tx *sql.Tx, ins DB_Insert, sel DB_Join) (stmt *sql.Stmt) { res, err := build.adapter.SimpleInsertLeftJoin("_builder", ins, sel) - if err != nil { - build.recordError(err) - return nil - } - stmt, err = tx.Prepare(res) - build.recordError(err) - return stmt + return build.prepareTx(tx, res, err) } func (build *accBuilder) SimpleInsertInnerJoinTx(tx *sql.Tx, ins DB_Insert, sel DB_Join) (stmt *sql.Stmt) { diff --git a/query_gen/lib/builder.go b/query_gen/lib/builder.go index 842cc107..e6ddfa76 100644 --- a/query_gen/lib/builder.go +++ b/query_gen/lib/builder.go @@ -63,7 +63,6 @@ func (build *builder) SimpleCount(table string, where string, limit string) (stm if err != nil { return stmt, err } - //log.Print("res",res) return build.conn.Prepare(res) } @@ -72,7 +71,6 @@ func (build *builder) SimpleLeftJoin(table1 string, table2 string, columns strin if err != nil { return stmt, err } - //log.Print("res",res) return build.conn.Prepare(res) } @@ -81,7 +79,6 @@ func (build *builder) SimpleInnerJoin(table1 string, table2 string, columns stri if err != nil { return stmt, err } - //log.Print("res",res) return build.conn.Prepare(res) } diff --git a/query_gen/main.go b/query_gen/main.go index 4487d378..9ab5d943 100644 --- a/query_gen/main.go +++ b/query_gen/main.go @@ -314,8 +314,6 @@ func writeInnerJoins(adapter qgen.DB_Adapter) (err error) { } func writeInserts(adapter qgen.DB_Adapter) error { - adapter.SimpleInsert("createTopic", "topics", "parentID, title, content, parsed_content, createdAt, lastReplyAt, lastReplyBy, ipaddress, words, createdBy", "?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,?") - adapter.SimpleInsert("createReport", "topics", "title, content, parsed_content, createdAt, lastReplyAt, createdBy, lastReplyBy, data, parentID, css_class", "?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,1,'report'") adapter.SimpleInsert("createActionReply", "replies", "tid, actionType, ipaddress, createdBy, createdAt, lastUpdated, content, parsed_content", "?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'',''") diff --git a/rev_templates.go b/rev_templates.go index 1a46a83b..8b94c6f0 100644 --- a/rev_templates.go +++ b/rev_templates.go @@ -1,69 +1,48 @@ -//+build experiment +//+lbuild experiment // ! EXPERIMENTAL package main import ( "errors" - "log" "regexp" - "text/template/parse" ) -var tagFinder *regexp.Regexp -var limeFuncMap = map[string]interface{}{ - "and": "&&", - "not": "!", - "or": "||", - "eq": true, - "ge": true, - "gt": true, - "le": true, - "lt": true, - "ne": true, - "add": true, - "subtract": true, - "multiply": true, - "divide": true, +type Mango struct { + tagFinder *regexp.Regexp } -func init() { - tagFinder = regexp.MustCompile(`(?s)\{\{(.*)\}\}`) +func (m *Mango) Init() { + m.tagFinder = regexp.MustCompile(`(?s)\{\{(.*)\}\}`) } -func mangoParse(tmpl string) error { - tree := parse.New(name, funcMap) - var treeSet = make(map[string]*parse.Tree) - tree, err = tree.Parse(content, "{{", "}}", treeSet, limeFuncMap) - if err != nil { - return err - } - treeLength := len(tree.Root.Nodes) - log.Print("treeLength", treeLength) - return nil -} - -func icecreamSoup(tmpl string) error { - if config.MinifyTemplates { - tmpl = minify(tmpl) - } - tagIndices := tagFinder.FindAllStringIndex(tmpl, -1) - if tagIndices != nil && len(tagIndices) > 0 { - +func (m *Mango) Parse(tmpl string) (out string, err error) { + tagIndices := m.tagFinder.FindAllStringIndex(tmpl, -1) + if len(tagIndices) > 0 { if tagIndices[0][0] == 0 { - return errors.New("We don't support tags in the outermost layer yet") + return "", errors.New("We don't support tags in the outermost layer yet") } + var lastTag = 0 + var lastID = 0 for _, tagIndex := range tagIndices { var nestingLayer = 0 for i := tagIndex[0]; i > 0; i-- { switch tmpl[i] { case '>': - i, closeTag, err := tasteTagToLeft(tmpl, i) + ii, closeTag, err := m.tasteTagToLeft(tmpl, i) if err != nil { - return err + return "", err } if closeTag { nestingLayer++ + } else { + _, tagID := m.parseTag(tmpl, ii, i) + if tagID == "" { + out += tmpl[lastTag:ii] + m.injectID(ii, i) + lastID++ + } else { + out += tmpl[lastTag:i] + } } case '<': @@ -71,9 +50,55 @@ func icecreamSoup(tmpl string) error { } } } + return "", nil } -func tasteTagToLeft(tmpl string, index int) (indexOut int, closeTag bool, err error) { +func (m *Mango) injectID(start int, end int) string { + return "" +} + +func (m *Mango) parseTag(tmpl string, start int, end int) (tagType string, tagID string) { + var i = start + for ; i < end; i++ { + if tmpl[i] == ' ' { + break + } + } + tagType = tmpl[start:i] + i = start + for ; i < (end - 4); i++ { + if tmpl[i] == ' ' && tmpl[i+1] == 'i' && tmpl[i+2] == 'd' && tmpl[i+3] == '=' { + tagID = m.extractAttributeContents(tmpl, i+4, end) + } + } + return tagType, tagID +} + +func (m *Mango) extractAttributeContents(tmpl string, i int, end int) (contents string) { + var start = i + var quoteChar byte = 0 // nolint + if m.isHTMLQuoteChar(tmpl[i]) { + i++ + quoteChar = tmpl[i] + } + i += 3 + for ; i < end; i++ { + if quoteChar != 0 { + if tmpl[i] == quoteChar { + break + } + } else if tmpl[i] == ' ' { + break + } + } + return tmpl[start:i] +} + +func (m *Mango) isHTMLQuoteChar(char byte) bool { + return char == '\'' || char == '"' +} + +func (m *Mango) tasteTagToLeft(tmpl string, index int) (indexOut int, closeTag bool, err error) { var foundLeftBrace = false for ; index > 0; index-- { // What if the / isn't adjacent to the < but has a space instead? Is that even valid? @@ -85,7 +110,7 @@ func tasteTagToLeft(tmpl string, index int) (indexOut int, closeTag bool, err er } } if !foundLeftBrace { - return errors.New("The left portion of the tag is missing") + return index, closeTag, errors.New("The left portion of the tag is missing") } return index, closeTag, nil } diff --git a/router_gen/routes.go b/router_gen/routes.go index ec37365f..45c80b5a 100644 --- a/router_gen/routes.go +++ b/router_gen/routes.go @@ -60,6 +60,7 @@ func Route(fname string, path string, args ...string) *RouteImpl { return &RouteImpl{fname, path, args, []Runnable{}} } +// TODO: How should we handle headerLite and headerVar? func routes() { //addRoute("default_route","","") addRoute(Route("routeAPI", "/api/")) diff --git a/templates.go b/templates.go index 7a9395ff..d8a6f467 100644 --- a/templates.go +++ b/templates.go @@ -144,12 +144,12 @@ func (c *CTemplateSet) compileTemplate(name string, dir string, expects string, w.Write([]byte(`, " + ", -1) fout = strings.Replace(fout, "` + `", "", -1) //spstr := "`([:space:]*)`" - //whitespace_writes := regexp.MustCompile(`(?s)w.Write\(\[\]byte\(`+spstr+`\)\)`) - //fout = whitespace_writes.ReplaceAllString(fout,"") + //whitespaceWrites := regexp.MustCompile(`(?s)w.Write\(\[\]byte\(`+spstr+`\)\)`) + //fout = whitespaceWrites.ReplaceAllString(fout,"") if dev.DebugMode { for index, count := range c.stats { - fmt.Println(index + ": " + strconv.Itoa(count)) + fmt.Println(index+": ", strconv.Itoa(count)) } fmt.Println(" ") } @@ -158,6 +158,7 @@ w.Write([]byte(`, " + ", -1) fmt.Println("Output!") fmt.Println(fout) } + //log.Fatal("remove the log.Fatal line") return fout, nil } @@ -168,9 +169,8 @@ func (c *CTemplateSet) rootIterate(tree *parse.Tree, varholder string, holdrefle treeLength := len(tree.Root.Nodes) for index, node := range tree.Root.Nodes { if dev.TemplateDebug { - fmt.Println("Node: ", node.String()) + fmt.Println("Node:", node.String()) } - c.previousNode = c.currentNode c.currentNode = node.Type() if treeLength != (index + 1) { @@ -181,7 +181,7 @@ func (c *CTemplateSet) rootIterate(tree *parse.Tree, varholder string, holdrefle return out } -func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value, templateName string, node interface{}) (out string) { +func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value, templateName string, node parse.Node) (out string) { if dev.TemplateDebug { fmt.Println("in compileSwitch") } @@ -196,7 +196,6 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value for _, cmd := range node.Pipe.Cmds { out += c.compileSubswitch(varholder, holdreflect, templateName, cmd) } - return out case *parse.IfNode: if dev.TemplateDebug { fmt.Println("If Node:") @@ -218,7 +217,6 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value if dev.TemplateDebug { fmt.Println("If Node Expression:", expr) } - c.previousNode = c.currentNode c.currentNode = parse.NodeList c.nextNode = -1 @@ -240,60 +238,8 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value for _, subnode := range node.Nodes { out += c.compileSwitch(varholder, holdreflect, templateName, subnode) } - return out case *parse.RangeNode: - if dev.TemplateDebug { - fmt.Println("Range Node!") - fmt.Println(node.Pipe) - } - - var outVal reflect.Value - for _, cmd := range node.Pipe.Cmds { - if dev.TemplateDebug { - fmt.Println("Range Bit:", cmd) - } - out, outVal = c.compileReflectswitch(varholder, holdreflect, templateName, cmd) - } - - if dev.TemplateDebug { - fmt.Println("Returned:", out) - fmt.Println("Range Kind Switch!") - } - - switch outVal.Kind() { - case reflect.Map: - var item reflect.Value - for _, key := range outVal.MapKeys() { - item = outVal.MapIndex(key) - } - if dev.DebugMode { - fmt.Println("Range item:", item) - } - if !item.IsValid() { - panic("item" + "^\n" + "Invalid map. Maybe, it doesn't have any entries for the template engine to analyse?") - } - - if node.ElseList != nil { - out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compileSwitch("item", item, templateName, node.List) + "}\n} else {\n" + c.compileSwitch("item", item, templateName, node.ElseList) + "}\n" - } else { - out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compileSwitch("item", item, templateName, node.List) + "}\n}" - } - case reflect.Slice: - if outVal.Len() == 0 { - panic("The sample data needs at-least one or more elements for the slices. We're looking into removing this requirement at some point!") - } - item := outVal.Index(0) - out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compileSwitch("item", item, templateName, node.List) + "}\n}" - case reflect.Invalid: - return "" - } - - if node.ElseList != nil { - out += " else {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.ElseList) + "}\n" - } else { - out += "\n" - } - return out + return c.compileRangeNode(varholder, holdreflect, templateName, node) case *parse.TemplateNode: return c.compileSubtemplate(varholder, holdreflect, node) case *parse.TextNode: @@ -305,7 +251,6 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value return "" } - //return "w.Write([]byte(`" + string(node.Text) + "`))\n" fragmentName := templateName + "_" + strconv.Itoa(c.FragmentCursor[templateName]) _, ok := c.Fragments[fragmentName] if !ok { @@ -315,9 +260,61 @@ func (c *CTemplateSet) compileSwitch(varholder string, holdreflect reflect.Value c.FragmentCursor[templateName] = c.FragmentCursor[templateName] + 1 return "w.Write(" + fragmentName + ")\n" default: - panic("Unknown Node in main switch") + return c.unknownNode(node) } - return "" + return out +} + +func (c *CTemplateSet) compileRangeNode(varholder string, holdreflect reflect.Value, templateName string, node *parse.RangeNode) (out string) { + if dev.TemplateDebug { + fmt.Println("Range Node!") + fmt.Println(node.Pipe) + } + + var outVal reflect.Value + for _, cmd := range node.Pipe.Cmds { + if dev.TemplateDebug { + fmt.Println("Range Bit:", cmd) + } + out, outVal = c.compileReflectswitch(varholder, holdreflect, templateName, cmd) + } + if dev.TemplateDebug { + fmt.Println("Returned:", out) + fmt.Println("Range Kind Switch!") + } + + switch outVal.Kind() { + case reflect.Map: + var item reflect.Value + for _, key := range outVal.MapKeys() { + item = outVal.MapIndex(key) + } + if dev.DebugMode { + fmt.Println("Range item:", item) + } + if !item.IsValid() { + panic("item" + "^\n" + "Invalid map. Maybe, it doesn't have any entries for the template engine to analyse?") + } + + if node.ElseList != nil { + out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compileSwitch("item", item, templateName, node.List) + "}\n} else {\n" + c.compileSwitch("item", item, templateName, node.ElseList) + "}\n" + } else { + out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compileSwitch("item", item, templateName, node.List) + "}\n}" + } + case reflect.Slice: + if outVal.Len() == 0 { + panic("The sample data needs at-least one or more elements for the slices. We're looking into removing this requirement at some point!") + } + item := outVal.Index(0) + out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compileSwitch("item", item, templateName, node.List) + "}\n}" + case reflect.Invalid: + return "" + } + + if node.ElseList != nil { + out += " else {\n" + c.compileSwitch(varholder, holdreflect, templateName, node.ElseList) + "}" + } + return out + "\n" } func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) { @@ -353,7 +350,6 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va for cur.Kind() == reflect.Ptr { cur = cur.Elem() } - if dev.TemplateDebug { fmt.Println("Data Kind:", cur.Kind().String()) fmt.Println("Field Bit:", id) @@ -364,7 +360,7 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va if dev.DebugMode { fmt.Println("Debug Data:") fmt.Println("Holdreflect:", holdreflect) - fmt.Println("Holdreflect.Kind()", holdreflect.Kind()) + fmt.Println("Holdreflect.Kind():", holdreflect.Kind()) if !dev.TemplateDebug { fmt.Println("cur.Kind():", cur.Kind().String()) } @@ -425,15 +421,13 @@ func (c *CTemplateSet) compileSubswitch(varholder string, holdreflect reflect.Va } return c.compileVarsub(c.compileIdentswitch(varholder, holdreflect, templateName, node)) default: - fmt.Println("Unknown Kind:", reflect.ValueOf(firstWord).Elem().Kind()) - fmt.Println("Unknown Type:", reflect.ValueOf(firstWord).Elem().Type().Name()) - panic("I don't know what node this is") + return c.unknownNode(node) } } func (c *CTemplateSet) compileVarswitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string) { if dev.TemplateDebug { - fmt.Println("in compile_varswitch") + fmt.Println("in compileVarswitch") } firstWord := node.Args[0] switch n := firstWord.(type) { @@ -466,7 +460,6 @@ func (c *CTemplateSet) compileVarswitch(varholder string, holdreflect reflect.Va fmt.Println("Variable Node Identifier:", n.Ident) } out, _ = c.compileIfVarsub(n.String(), varholder, templateName, holdreflect) - return out case *parse.NilNode: panic("Nil is not a command x.x") case *parse.PipeNode: @@ -480,12 +473,16 @@ func (c *CTemplateSet) compileVarswitch(varholder string, holdreflect reflect.Va if dev.TemplateDebug { fmt.Println("Out:", out) } - return out default: - fmt.Println("Unknown Kind:", reflect.ValueOf(firstWord).Elem().Kind()) - fmt.Println("Unknown Type:", reflect.ValueOf(firstWord).Elem().Type().Name()) - panic("I don't know what node this is! Grr...") + return c.unknownNode(firstWord) } + return out +} + +func (c *CTemplateSet) unknownNode(node parse.Node) (out string) { + fmt.Println("Unknown Kind:", reflect.ValueOf(node).Elem().Kind()) + fmt.Println("Unknown Type:", reflect.ValueOf(node).Elem().Type().Name()) + panic("I don't know what node this is! Grr...") return "" } @@ -497,6 +494,78 @@ func (c *CTemplateSet) compileIdentswitchN(varholder string, holdreflect reflect return out } +func (c *CTemplateSet) compareFunc(varholder string, holdreflect reflect.Value, templateName string, pos int, node *parse.CommandNode, compare string) (out string) { + if dev.TemplateDebug { + fmt.Println("symbol: ", compare) + fmt.Println("node.Args[pos + 1]", node.Args[pos+1]) + fmt.Println("node.Args[pos + 2]", node.Args[pos+2]) + } + return c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " " + compare + " " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect) +} + +func (c *CTemplateSet) simpleMath(varholder string, holdreflect reflect.Value, templateName string, pos int, node *parse.CommandNode, symbol string) (out string, val reflect.Value) { + leftParam, val2 := c.compileIfVarsub(node.Args[pos+1].String(), varholder, templateName, holdreflect) + rightParam, val3 := c.compileIfVarsub(node.Args[pos+2].String(), varholder, templateName, holdreflect) + + if val2.IsValid() { + val = val2 + } else if val3.IsValid() { + val = val3 + } else { + // TODO: What does this do? + numSample := 1 + val = reflect.ValueOf(numSample) + } + + if dev.TemplateDebug { + fmt.Println("symbol: " + symbol) + fmt.Println("node.Args[pos + 1]", node.Args[pos+1]) + fmt.Println("node.Args[pos + 2]", node.Args[pos+2]) + } + + return leftParam + " " + symbol + " " + rightParam, val +} + +func (c *CTemplateSet) compareJoin(varholder string, holdreflect reflect.Value, templateName string, pos int, node *parse.CommandNode, symbol string) (pos2 int, out string) { + if dev.TemplateDebug { + fmt.Println("Building " + symbol + " function") + } + if pos == 0 { + fmt.Println("pos:", pos) + panic(symbol + " is missing a left operand") + } + if len(node.Args) <= pos { + fmt.Println("post pos:", pos) + fmt.Println("len(node.Args):", len(node.Args)) + panic(symbol + " is missing a right operand") + } + + left := c.compileBoolsub(node.Args[pos-1].String(), varholder, templateName, holdreflect) + _, funcExists := c.funcMap[node.Args[pos+1].String()] + + var right string + if !funcExists { + right = c.compileBoolsub(node.Args[pos+1].String(), varholder, templateName, holdreflect) + } + out = left + " " + symbol + " " + right + //log.Print("left: ", left) + //log.Print("right: ", right) + + if dev.TemplateDebug { + fmt.Println("Left operand:", node.Args[pos-1]) + fmt.Println("Right operand:", node.Args[pos+1]) + } + if !funcExists { + pos++ + } + if dev.TemplateDebug { + fmt.Println("pos:", pos) + fmt.Println("len(node.Args):", len(node.Args)) + } + + return pos, out +} + func (c *CTemplateSet) compileIdentswitch(varholder string, holdreflect reflect.Value, templateName string, node *parse.CommandNode) (out string, val reflect.Value) { if dev.TemplateDebug { fmt.Println("in compileIdentswitch") @@ -514,200 +583,50 @@ ArgLoop: case "not": out += "!" case "or": - if dev.TemplateDebug { - fmt.Println("Building or function") - } - if pos == 0 { - fmt.Println("pos:", pos) - panic("or is missing a left operand") - } - if len(node.Args) <= pos { - fmt.Println("post pos:", pos) - fmt.Println("len(node.Args):", len(node.Args)) - panic("or is missing a right operand") - } - - left := c.compileBoolsub(node.Args[pos-1].String(), varholder, templateName, holdreflect) - _, funcExists := c.funcMap[node.Args[pos+1].String()] - - var right string - if !funcExists { - right = c.compileBoolsub(node.Args[pos+1].String(), varholder, templateName, holdreflect) - } - - out += left + " || " + right - - if dev.TemplateDebug { - fmt.Println("Left operand:", node.Args[pos-1]) - fmt.Println("Right operand:", node.Args[pos+1]) - } - - if !funcExists { - pos++ - } - - if dev.TemplateDebug { - fmt.Println("pos:", pos) - fmt.Println("len(node.Args):", len(node.Args)) - } + var rout string + pos, rout = c.compareJoin(varholder, holdreflect, templateName, pos, node, "||") // TODO: Test this + out += rout case "and": - if dev.TemplateDebug { - fmt.Println("Building and function") - } - if pos == 0 { - fmt.Println("pos:", pos) - panic("and is missing a left operand") - } - if len(node.Args) <= pos { - fmt.Println("post pos:", pos) - fmt.Println("len(node.Args):", len(node.Args)) - panic("and is missing a right operand") - } - - left := c.compileBoolsub(node.Args[pos-1].String(), varholder, templateName, holdreflect) - _, funcExists := c.funcMap[node.Args[pos+1].String()] - - var right string - if !funcExists { - right = c.compileBoolsub(node.Args[pos+1].String(), varholder, templateName, holdreflect) - } - - out += left + " && " + right - - if dev.TemplateDebug { - fmt.Println("Left operand:", node.Args[pos-1]) - fmt.Println("Right operand:", node.Args[pos+1]) - } - - if !funcExists { - pos++ - } - - if dev.TemplateDebug { - fmt.Println("pos:", pos) - fmt.Println("len(node.Args):", len(node.Args)) - } - case "le": - out += c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " <= " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect) - if dev.TemplateDebug { - fmt.Println("node.Args[pos + 1]", node.Args[pos+1]) - fmt.Println("node.Args[pos + 2]", node.Args[pos+2]) - } + var rout string + pos, rout = c.compareJoin(varholder, holdreflect, templateName, pos, node, "&&") // TODO: Test this + out += rout + case "le": // TODO: Can we condense these comparison cases down into one? + out += c.compareFunc(varholder, holdreflect, templateName, pos, node, "<=") break ArgLoop case "lt": - out += c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " < " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect) - if dev.TemplateDebug { - fmt.Println("node.Args[pos + 1]", node.Args[pos+1]) - fmt.Println("node.Args[pos + 2]", node.Args[pos+2]) - } + out += c.compareFunc(varholder, holdreflect, templateName, pos, node, "<") break ArgLoop case "gt": - out += c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " > " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect) - if dev.TemplateDebug { - fmt.Println("node.Args[pos + 1]", node.Args[pos+1]) - fmt.Println("node.Args[pos + 2]", node.Args[pos+2]) - } + out += c.compareFunc(varholder, holdreflect, templateName, pos, node, ">") break ArgLoop case "ge": - out += c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " >= " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect) - if dev.TemplateDebug { - fmt.Println("node.Args[pos + 1]", node.Args[pos+1]) - fmt.Println("node.Args[pos + 2]", node.Args[pos+2]) - } + out += c.compareFunc(varholder, holdreflect, templateName, pos, node, ">=") break ArgLoop case "eq": - out += c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " == " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect) - if dev.TemplateDebug { - fmt.Println("node.Args[pos + 1]", node.Args[pos+1]) - fmt.Println("node.Args[pos + 2]", node.Args[pos+2]) - } + out += c.compareFunc(varholder, holdreflect, templateName, pos, node, "==") break ArgLoop case "ne": - out += c.compileIfVarsubN(node.Args[pos+1].String(), varholder, templateName, holdreflect) + " != " + c.compileIfVarsubN(node.Args[pos+2].String(), varholder, templateName, holdreflect) - if dev.TemplateDebug { - fmt.Println("node.Args[pos + 1]", node.Args[pos+1]) - fmt.Println("node.Args[pos + 2]", node.Args[pos+2]) - } + out += c.compareFunc(varholder, holdreflect, templateName, pos, node, "!=") break ArgLoop case "add": - param1, val2 := c.compileIfVarsub(node.Args[pos+1].String(), varholder, templateName, holdreflect) - param2, val3 := c.compileIfVarsub(node.Args[pos+2].String(), varholder, templateName, holdreflect) - - if val2.IsValid() { - val = val2 - } else if val3.IsValid() { - val = val3 - } else { - numSample := 1 - val = reflect.ValueOf(numSample) - } - - out += param1 + " + " + param2 - if dev.TemplateDebug { - fmt.Println("add") - fmt.Println("node.Args[pos + 1]", node.Args[pos+1]) - fmt.Println("node.Args[pos + 2]", node.Args[pos+2]) - } + rout, rval := c.simpleMath(varholder, holdreflect, templateName, pos, node, "+") + out += rout + val = rval break ArgLoop case "subtract": - param1, val2 := c.compileIfVarsub(node.Args[pos+1].String(), varholder, templateName, holdreflect) - param2, val3 := c.compileIfVarsub(node.Args[pos+2].String(), varholder, templateName, holdreflect) - - if val2.IsValid() { - val = val2 - } else if val3.IsValid() { - val = val3 - } else { - numSample := 1 - val = reflect.ValueOf(numSample) - } - - out += param1 + " - " + param2 - if dev.TemplateDebug { - fmt.Println("subtract") - fmt.Println("node.Args[pos + 1]", node.Args[pos+1]) - fmt.Println("node.Args[pos + 2]", node.Args[pos+2]) - } + rout, rval := c.simpleMath(varholder, holdreflect, templateName, pos, node, "-") + out += rout + val = rval break ArgLoop case "divide": - param1, val2 := c.compileIfVarsub(node.Args[pos+1].String(), varholder, templateName, holdreflect) - param2, val3 := c.compileIfVarsub(node.Args[pos+2].String(), varholder, templateName, holdreflect) - - if val2.IsValid() { - val = val2 - } else if val3.IsValid() { - val = val3 - } else { - numSample := 1 - val = reflect.ValueOf(numSample) - } - - out += param1 + " / " + param2 - if dev.TemplateDebug { - fmt.Println("divide") - fmt.Println("node.Args[pos + 1]", node.Args[pos+1]) - fmt.Println("node.Args[pos + 2]", node.Args[pos+2]) - } + rout, rval := c.simpleMath(varholder, holdreflect, templateName, pos, node, "/") + out += rout + val = rval break ArgLoop case "multiply": - param1, val2 := c.compileIfVarsub(node.Args[pos+1].String(), varholder, templateName, holdreflect) - param2, val3 := c.compileIfVarsub(node.Args[pos+2].String(), varholder, templateName, holdreflect) - - if val2.IsValid() { - val = val2 - } else if val3.IsValid() { - val = val3 - } else { - numSample := 1 - val = reflect.ValueOf(numSample) - } - - out += param1 + " * " + param2 - if dev.TemplateDebug { - fmt.Println("multiply") - fmt.Println("node.Args[pos + 1]", node.Args[pos+1]) - fmt.Println("node.Args[pos + 2]", node.Args[pos+2]) - } + rout, rval := c.simpleMath(varholder, holdreflect, templateName, pos, node, "*") + out += rout + val = rval break ArgLoop default: if dev.TemplateDebug { @@ -726,6 +645,7 @@ ArgLoop: //for _, outval := range outbuf { // out += outval //} + //log.Print("outbit: ", out) return out, val } @@ -747,7 +667,7 @@ func (c *CTemplateSet) compileReflectswitch(varholder string, holdreflect reflec case *parse.ChainNode: if dev.TemplateDebug { fmt.Println("Chain Node:", n.Node) - fmt.Println("node.Args", node.Args) + fmt.Println("node.Args:", node.Args) } return "", outVal case *parse.DotNode: @@ -835,7 +755,6 @@ func (c *CTemplateSet) compileIfVarsub(varname string, varholder string, templat } else { out += "." + bit } - if !cur.IsValid() { panic(out + "^\n" + "Invalid value. Maybe, it doesn't exist?") } diff --git a/themes/cosora/public/main.css b/themes/cosora/public/main.css index a05d235a..559096e0 100644 --- a/themes/cosora/public/main.css +++ b/themes/cosora/public/main.css @@ -699,6 +699,27 @@ select, input, textarea { margin-right: 10px; } +#profile_container, #profile_left_pane { + display: flex; +} +#profile_left_lane { + border: 1px solid var(--element-border-color); + border-bottom: 2px solid var(--element-border-color); +} +#profile_left_pane { + flex-direction: column; +} +#profile_left_pane .avatarRow { + padding: 24px; +} +#profile_left_pane .avatar { + border-radius: 80px; +} +#profile_right_lane .colstack_item { + border: 1px solid var(--element-border-color); + border-bottom: 2px solid var(--element-border-color); +} + @media(max-width: 670px) { .topic_inner_right { display: none; diff --git a/topic_store.go b/topic_store.go index 8d7c685b..5022a8b2 100644 --- a/topic_store.go +++ b/topic_store.go @@ -58,6 +58,7 @@ type MemoryTopicStore struct { get *sql.Stmt exists *sql.Stmt topicCount *sql.Stmt + create *sql.Stmt sync.RWMutex } @@ -70,6 +71,7 @@ func NewMemoryTopicStore(capacity int) (*MemoryTopicStore, error) { get: acc.SimpleSelect("topics", "title, content, createdBy, createdAt, lastReplyAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data", "tid = ?", "", ""), exists: acc.SimpleSelect("topics", "tid", "tid = ?", "", ""), topicCount: acc.SimpleCount("topics", "", ""), + create: acc.SimpleInsert("topics", "parentID, title, content, parsed_content, createdAt, lastReplyAt, lastReplyBy, ipaddress, words, createdBy", "?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,?"), }, acc.FirstError() } @@ -146,7 +148,7 @@ func (mts *MemoryTopicStore) Create(fid int, topicName string, content string, u wcount := wordCount(content) // TODO: Move this statement into the topic store - res, err := stmts.createTopic.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid) + res, err := mts.create.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid) if err != nil { return 0, err } @@ -253,6 +255,7 @@ type SQLTopicStore struct { get *sql.Stmt exists *sql.Stmt topicCount *sql.Stmt + create *sql.Stmt } func NewSQLTopicStore() (*SQLTopicStore, error) { @@ -261,6 +264,7 @@ func NewSQLTopicStore() (*SQLTopicStore, error) { get: acc.SimpleSelect("topics", "title, content, createdBy, createdAt, lastReplyAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, data", "tid = ?", "", ""), exists: acc.SimpleSelect("topics", "tid", "tid = ?", "", ""), topicCount: acc.SimpleCount("topics", "", ""), + create: acc.SimpleInsert("topics", "parentID, title, content, parsed_content, createdAt, lastReplyAt, lastReplyBy, ipaddress, words, createdBy", "?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,?"), }, acc.FirstError() } @@ -297,7 +301,7 @@ func (sts *SQLTopicStore) Create(fid int, topicName string, content string, uid wcount := wordCount(content) // TODO: Move this statement into the topic store - res, err := stmts.createTopic.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid) + res, err := sts.create.Exec(fid, topicName, content, parsedContent, uid, ipaddress, wcount, uid) if err != nil { return 0, err }