Topic and user edits should now update the caches. Ditto for topic deletions.
The tests and benchmarks now run again. gloinit() is always called prior to the tests and benchmarks now. The tests and benchmarks no longer use hard-coded session strings for admin route tests. Added some new route tests. We now pull the database version into a variable. Fixed an issue with guest perms not applying properly. Tweaked the router to make it a little more efficient. Moved more topic / user parsing logic into CascadeGet Profiles now use the user cache. Added the Set method to the caches. Set is used when you don't know if an item exists in a cache or not. Added the Load method to the caches. Load is used to forcefully reload an item in a cache from the database.
2
cache.go
|
@ -11,9 +11,11 @@ var users UserStore
|
|||
var topics TopicStore
|
||||
|
||||
type DataStore interface {
|
||||
Load(id int) error
|
||||
Get(id int) (interface{}, error)
|
||||
GetUnsafe(id int) (interface{}, error)
|
||||
CascadeGet(id int) (interface{}, error)
|
||||
Set(item interface{}) error
|
||||
Add(item interface{}) error
|
||||
AddUnsafe(item interface{}) error
|
||||
Remove(id int) error
|
||||
|
|
8
files.go
|
@ -4,9 +4,9 @@ import "log"
|
|||
import "bytes"
|
||||
import "strings"
|
||||
import "mime"
|
||||
import "errors"
|
||||
//import "errors"
|
||||
import "os"
|
||||
import "io"
|
||||
//import "io"
|
||||
import "io/ioutil"
|
||||
import "path/filepath"
|
||||
import "net/http"
|
||||
|
@ -23,7 +23,7 @@ type SFile struct
|
|||
FormattedModTime string
|
||||
}
|
||||
|
||||
func (r SFile) Read(b []byte) (n int, err error) {
|
||||
/*func (r SFile) Read(b []byte) (n int, err error) {
|
||||
n = 0
|
||||
if r.Pos > r.Length {
|
||||
return n, io.EOF
|
||||
|
@ -58,7 +58,7 @@ func (r SFile) Seek(offset int64, whence int) (int64, error) {
|
|||
return 0, errors.New("invalid whence")
|
||||
}
|
||||
return r.Pos, nil
|
||||
}
|
||||
}*/
|
||||
|
||||
func add_static_file(path string, prefix string) error {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
|
|
528
general_test.go
|
@ -1,5 +1,6 @@
|
|||
package main
|
||||
import "os"
|
||||
import "fmt"
|
||||
import "log"
|
||||
import "bytes"
|
||||
import "strconv"
|
||||
|
@ -8,7 +9,6 @@ import "testing"
|
|||
import "net/http"
|
||||
import "net/http/httptest"
|
||||
import "io/ioutil"
|
||||
import "html/template"
|
||||
import "database/sql"
|
||||
import _ "github.com/go-sql-driver/mysql"
|
||||
//import "github.com/husobee/vestigo"
|
||||
|
@ -23,9 +23,25 @@ func gloinit() {
|
|||
//discard := ioutil.Discard
|
||||
//log.SetOutput(discard)
|
||||
|
||||
init_themes()
|
||||
var err error
|
||||
init_database(err)
|
||||
init_templates()
|
||||
db.SetMaxOpenConns(64)
|
||||
err = init_errors()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if cache_topicuser == CACHE_STATIC {
|
||||
users = NewStaticUserStore(user_cache_capacity)
|
||||
topics = NewStaticTopicStore(topic_cache_capacity)
|
||||
} else {
|
||||
users = NewSqlUserStore()
|
||||
topics = NewSqlTopicStore()
|
||||
}
|
||||
|
||||
init_static_files()
|
||||
external_sites["YT"] = "https://www.youtube.com/"
|
||||
hooks["trow_assign"] = nil
|
||||
hooks["rrow_assign"] = nil
|
||||
|
@ -33,26 +49,30 @@ func gloinit() {
|
|||
gloinited = true
|
||||
}
|
||||
|
||||
func BenchmarkTopicTemplate(b *testing.B) {
|
||||
func init() {
|
||||
gloinit()
|
||||
}
|
||||
|
||||
func BenchmarkTopicTemplateSerial(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"127.0.0.1"}
|
||||
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58,"127.0.0.1"}
|
||||
noticeList := []string{"test"}
|
||||
|
||||
topic := TopicUser{Title: "Lol",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}
|
||||
topic := TopicUser{Title: "Lol",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}
|
||||
|
||||
var replyList []Reply
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1})
|
||||
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1})
|
||||
|
||||
tpage := TopicPage{"Topic Blah",user,noticeList,replyList,topic,1,1,false}
|
||||
tpage2 := TopicPage{"Topic Blah",admin,noticeList,replyList,topic,1,1,false}
|
||||
|
@ -113,24 +133,24 @@ func BenchmarkTopicTemplate(b *testing.B) {
|
|||
defer pprof.StopCPUProfile()*/
|
||||
}
|
||||
|
||||
func BenchmarkTopicsTemplate(b *testing.B) {
|
||||
func BenchmarkTopicsTemplateSerial(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"127.0.0.1"}
|
||||
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58,"127.0.0.1"}
|
||||
noticeList := []string{"test"}
|
||||
|
||||
var topicList []TopicUser
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
var topicList []TopicsRow
|
||||
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
|
||||
|
||||
w := ioutil.Discard
|
||||
tpage := TopicsPage{"Topic Blah",user,noticeList,topicList,nil}
|
||||
|
@ -163,23 +183,6 @@ func BenchmarkStaticRouteParallel(b *testing.B) {
|
|||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
static_w := httptest.NewRecorder()
|
||||
static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil))
|
||||
static_handler := http.HandlerFunc(route_static)
|
||||
for pb.Next() {
|
||||
static_w.Body.Reset()
|
||||
static_handler.ServeHTTP(static_w,static_req)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/*func BenchmarkStaticRouteParallelWithPlugins(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
if !plugins_inited {
|
||||
init_plugins()
|
||||
}
|
||||
|
@ -189,11 +192,16 @@ func BenchmarkStaticRouteParallel(b *testing.B) {
|
|||
static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil))
|
||||
static_handler := http.HandlerFunc(route_static)
|
||||
for pb.Next() {
|
||||
//static_w.Code = 200
|
||||
static_w.Body.Reset()
|
||||
static_handler.ServeHTTP(static_w,static_req)
|
||||
//if static_w.Code != 200 {
|
||||
// fmt.Println(static_w.Body)
|
||||
// panic("HTTP Error!")
|
||||
//}
|
||||
}
|
||||
})
|
||||
}*/
|
||||
}
|
||||
|
||||
func BenchmarkTopicAdminRouteParallel(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
@ -202,9 +210,15 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) {
|
|||
}
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year}
|
||||
// TO-DO: Stop hard-coding this value. Seriously.
|
||||
admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year}
|
||||
admin, err := users.CascadeGet(1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !admin.Is_Admin {
|
||||
panic("UID1 is not an admin")
|
||||
}
|
||||
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
|
||||
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year}
|
||||
|
||||
topic_w := httptest.NewRecorder()
|
||||
topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil))
|
||||
|
@ -214,7 +228,7 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) {
|
|||
topic_handler := http.HandlerFunc(route_topic_id)
|
||||
|
||||
for pb.Next() {
|
||||
//topic_w.Body.Reset()
|
||||
topic_w.Body.Reset()
|
||||
topic_handler.ServeHTTP(topic_w,topic_req_admin)
|
||||
}
|
||||
})
|
||||
|
@ -245,9 +259,15 @@ func BenchmarkForumsAdminRouteParallel(b *testing.B) {
|
|||
}
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year}
|
||||
// TO-DO: Stop hard-coding this value. Seriously.
|
||||
admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year}
|
||||
admin, err := users.CascadeGet(1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !admin.Is_Admin {
|
||||
panic("UID1 is not an admin")
|
||||
}
|
||||
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
|
||||
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year}
|
||||
|
||||
forums_w := httptest.NewRecorder()
|
||||
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
|
||||
|
@ -270,9 +290,15 @@ func BenchmarkForumsAdminRouteParallelProf(b *testing.B) {
|
|||
}
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year}
|
||||
// TO-DO: Stop hard-coding this value. Seriously.
|
||||
admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year}
|
||||
admin, err := users.CascadeGet(1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !admin.Is_Admin {
|
||||
panic("UID1 is not an admin")
|
||||
}
|
||||
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
|
||||
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path: "/",MaxAge: year}
|
||||
|
||||
forums_w := httptest.NewRecorder()
|
||||
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
|
||||
|
@ -313,10 +339,16 @@ func BenchmarkForumsGuestRouteParallel(b *testing.B) {
|
|||
|
||||
func BenchmarkRoutesSerial(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
admin, err := users.CascadeGet(1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !admin.Is_Admin {
|
||||
panic("UID1 is not an admin")
|
||||
}
|
||||
|
||||
admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year}
|
||||
// TO-DO: Stop hard-coding this value. Seriously.
|
||||
admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year}
|
||||
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
|
||||
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path: "/",MaxAge: year}
|
||||
|
||||
if plugins_inited {
|
||||
b.Log("Plugins have already been initialised, they can't be deinitialised so these tests will run with plugins on")
|
||||
|
@ -367,8 +399,13 @@ func BenchmarkRoutesSerial(b *testing.B) {
|
|||
|
||||
b.Run("static_recorder", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
//static_w.Code = 200
|
||||
static_w.Body.Reset()
|
||||
static_handler.ServeHTTP(static_w,static_req)
|
||||
//if static_w.Code != 200 {
|
||||
// fmt.Println(static_w.Body)
|
||||
// panic("HTTP Error!")
|
||||
//}
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -542,12 +579,9 @@ func BenchmarkQueryTopicParallel(b *testing.B) {
|
|||
}
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
topic := TopicUser{Css: no_css_tmpl}
|
||||
var content string
|
||||
var is_super_admin bool
|
||||
var group int
|
||||
tu := TopicUser{Css: no_css_tmpl}
|
||||
for pb.Next() {
|
||||
err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, topics.ipaddress from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level, &topic.IpAddress)
|
||||
err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.Is_Closed, &tu.Sticky, &tu.ParentID, &tu.IpAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level)
|
||||
if err == sql.ErrNoRows {
|
||||
log.Fatal("No rows found!")
|
||||
return
|
||||
|
@ -566,12 +600,9 @@ func BenchmarkQueryPreparedTopicParallel(b *testing.B) {
|
|||
}
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
topic := TopicUser{Css: no_css_tmpl}
|
||||
var content string
|
||||
var is_super_admin bool
|
||||
var group int
|
||||
tu := TopicUser{Css: no_css_tmpl}
|
||||
for pb.Next() {
|
||||
err := get_topic_user_stmt.QueryRow(1).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level, &topic.IpAddress)
|
||||
err := get_topic_user_stmt.QueryRow(1).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.Is_Closed, &tu.Sticky, &tu.ParentID, &tu.IpAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level)
|
||||
if err == sql.ErrNoRows {
|
||||
log.Fatal("No rows found!")
|
||||
return
|
||||
|
@ -585,13 +616,10 @@ func BenchmarkQueryPreparedTopicParallel(b *testing.B) {
|
|||
|
||||
func BenchmarkQueriesSerial(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
topic := TopicUser{Css: no_css_tmpl}
|
||||
var content string
|
||||
var is_super_admin bool
|
||||
var group int
|
||||
tu := TopicUser{Css: no_css_tmpl}
|
||||
b.Run("topic", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, topics.ipaddress from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level, &topic.IpAddress)
|
||||
err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.Is_Closed, &tu.Sticky, &tu.ParentID, &tu.IpAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level)
|
||||
if err == sql.ErrNoRows {
|
||||
log.Fatal("No rows found!")
|
||||
return
|
||||
|
@ -617,7 +645,10 @@ func BenchmarkQueriesSerial(b *testing.B) {
|
|||
defer rows.Close()
|
||||
}
|
||||
})
|
||||
|
||||
replyItem := Reply{Css: no_css_tmpl}
|
||||
var is_super_admin bool
|
||||
var group int
|
||||
b.Run("topic_replies_scan", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
rows, err := db.Query("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress from replies left join users ON replies.createdBy = users.uid where tid = ?", 1)
|
||||
|
@ -648,7 +679,7 @@ func addEmptyRoutesToMux(routes []string, serveMux *http.ServeMux) {
|
|||
}
|
||||
}
|
||||
|
||||
func BenchmarkDefaultGoRouter(b *testing.B) {
|
||||
func BenchmarkDefaultGoRouterSerial(b *testing.B) {
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil))
|
||||
routes := make([]string, 0)
|
||||
|
@ -805,176 +836,13 @@ func BenchmarkDefaultGoRouter(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
/*func addEmptyRoutesToVestigo(routes []string, router *vestigo.Router) {
|
||||
for _, route := range routes {
|
||||
router.HandleFunc(route, func(_ http.ResponseWriter,_ *http.Request){})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkVestigoRouter(b *testing.B) {
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil))
|
||||
routes := make([]string, 0)
|
||||
|
||||
routes = append(routes,"/test/")
|
||||
router := vestigo.NewRouter()
|
||||
router.HandleFunc("/test/", func(_ http.ResponseWriter,_ *http.Request){})
|
||||
b.Run("one-route", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
|
||||
router.ServeHTTP(w,req)
|
||||
}
|
||||
})
|
||||
|
||||
routes = append(routes,"/topic/")
|
||||
routes = append(routes,"/forums/")
|
||||
routes = append(routes,"/forum/")
|
||||
routes = append(routes,"/panel/")
|
||||
router = vestigo.NewRouter()
|
||||
addEmptyRoutesToVestigo(routes, router)
|
||||
b.Run("five-routes", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
|
||||
router.ServeHTTP(w,req)
|
||||
}
|
||||
})
|
||||
|
||||
router = vestigo.NewRouter()
|
||||
routes = append(routes,"/panel/plugins/")
|
||||
routes = append(routes,"/panel/groups/")
|
||||
routes = append(routes,"/panel/settings/")
|
||||
routes = append(routes,"/panel/users/")
|
||||
routes = append(routes,"/panel/forums/")
|
||||
addEmptyRoutesToVestigo(routes, router)
|
||||
b.Run("ten-routes", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
|
||||
router.ServeHTTP(w,req)
|
||||
}
|
||||
})
|
||||
|
||||
router = vestigo.NewRouter()
|
||||
routes = append(routes,"/panel/forums/create/submit/")
|
||||
routes = append(routes,"/panel/forums/delete/")
|
||||
routes = append(routes,"/users/ban/")
|
||||
routes = append(routes,"/panel/users/edit/")
|
||||
routes = append(routes,"/panel/forums/create/")
|
||||
routes = append(routes,"/users/unban/")
|
||||
routes = append(routes,"/pages/")
|
||||
routes = append(routes,"/users/activate/")
|
||||
routes = append(routes,"/panel/forums/edit/submit/")
|
||||
routes = append(routes,"/panel/plugins/activate/")
|
||||
addEmptyRoutesToVestigo(routes, router)
|
||||
b.Run("twenty-routes", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
|
||||
router.ServeHTTP(w,req)
|
||||
}
|
||||
})
|
||||
|
||||
router = vestigo.NewRouter()
|
||||
routes = append(routes,"/panel/plugins/deactivate/")
|
||||
routes = append(routes,"/panel/plugins/install/")
|
||||
routes = append(routes,"/panel/plugins/uninstall/")
|
||||
routes = append(routes,"/panel/templates/")
|
||||
routes = append(routes,"/panel/templates/edit/")
|
||||
routes = append(routes,"/panel/templates/create/")
|
||||
routes = append(routes,"/panel/templates/delete/")
|
||||
routes = append(routes,"/panel/templates/edit/submit/")
|
||||
routes = append(routes,"/panel/themes/")
|
||||
routes = append(routes,"/panel/themes/edit/")
|
||||
addEmptyRoutesToVestigo(routes, router)
|
||||
b.Run("thirty-routes", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
|
||||
router.ServeHTTP(w,req)
|
||||
}
|
||||
})
|
||||
|
||||
router = vestigo.NewRouter()
|
||||
routes = append(routes,"/panel/themes/create/")
|
||||
routes = append(routes,"/panel/themes/delete/")
|
||||
routes = append(routes,"/panel/themes/delete/submit/")
|
||||
routes = append(routes,"/panel/templates/create/submit/")
|
||||
routes = append(routes,"/panel/templates/delete/submit/")
|
||||
routes = append(routes,"/panel/widgets/")
|
||||
routes = append(routes,"/panel/widgets/edit/")
|
||||
routes = append(routes,"/panel/widgets/activate/")
|
||||
routes = append(routes,"/panel/widgets/deactivate/")
|
||||
routes = append(routes,"/panel/magical/wombat/path")
|
||||
addEmptyRoutesToVestigo(routes, router)
|
||||
b.Run("forty-routes", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
|
||||
router.ServeHTTP(w,req)
|
||||
}
|
||||
})
|
||||
|
||||
router = vestigo.NewRouter()
|
||||
routes = append(routes,"/report/")
|
||||
routes = append(routes,"/report/submit/")
|
||||
routes = append(routes,"/topic/create/submit/")
|
||||
routes = append(routes,"/topics/create/")
|
||||
routes = append(routes,"/overview/")
|
||||
routes = append(routes,"/uploads/")
|
||||
routes = append(routes,"/static/")
|
||||
routes = append(routes,"/reply/edit/submit/")
|
||||
routes = append(routes,"/reply/delete/submit/")
|
||||
routes = append(routes,"/topic/edit/submit/")
|
||||
addEmptyRoutesToVestigo(routes, router)
|
||||
b.Run("fifty-routes", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
|
||||
router.ServeHTTP(w,req)
|
||||
}
|
||||
})
|
||||
|
||||
router = vestigo.NewRouter()
|
||||
routes = append(routes,"/topic/delete/submit/")
|
||||
routes = append(routes,"/topic/stick/submit/")
|
||||
routes = append(routes,"/topic/unstick/submit/")
|
||||
routes = append(routes,"/accounts/login/")
|
||||
routes = append(routes,"/accounts/create/")
|
||||
routes = append(routes,"/accounts/logout/")
|
||||
routes = append(routes,"/accounts/login/submit/")
|
||||
routes = append(routes,"/accounts/create/submit/")
|
||||
routes = append(routes,"/user/edit/critical/")
|
||||
routes = append(routes,"/user/edit/critical/submit/")
|
||||
addEmptyRoutesToVestigo(routes, router)
|
||||
b.Run("sixty-routes", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
|
||||
router.ServeHTTP(w,req)
|
||||
}
|
||||
})
|
||||
|
||||
router = vestigo.NewRouter()
|
||||
routes = append(routes,"/user/edit/avatar/")
|
||||
routes = append(routes,"/user/edit/avatar/submit/")
|
||||
routes = append(routes,"/user/edit/username/")
|
||||
routes = append(routes,"/user/edit/username/submit/")
|
||||
routes = append(routes,"/profile/reply/create/")
|
||||
routes = append(routes,"/profile/reply/edit/submit/")
|
||||
routes = append(routes,"/profile/reply/delete/submit/")
|
||||
routes = append(routes,"/arcane/tower/")
|
||||
routes = append(routes,"/magical/kingdom/")
|
||||
routes = append(routes,"/insert/name/here/")
|
||||
addEmptyRoutesToVestigo(routes, router)
|
||||
b.Run("seventy-routes", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
|
||||
router.ServeHTTP(w,req)
|
||||
}
|
||||
})
|
||||
}*/
|
||||
|
||||
func addEmptyRoutesToCustom(routes []string, router *Router) {
|
||||
for _, route := range routes {
|
||||
router.HandleFunc(route, func(_ http.ResponseWriter,_ *http.Request){})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCustomRouter(b *testing.B) {
|
||||
func BenchmarkCustomRouterSerial(b *testing.B) {
|
||||
w := httptest.NewRecorder()
|
||||
req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil))
|
||||
routes := make([]string, 0)
|
||||
|
@ -1131,7 +999,7 @@ func BenchmarkCustomRouter(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func BenchmarkParser(b *testing.B) {
|
||||
func BenchmarkParserSerial(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.Run("empty_post", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
@ -1165,7 +1033,7 @@ func BenchmarkParser(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func BenchmarkBBCodePluginWithRegexp(b *testing.B) {
|
||||
func BenchmarkBBCodePluginWithRegexpSerial(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.Run("empty_post", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
@ -1214,7 +1082,7 @@ func BenchmarkBBCodePluginWithRegexp(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func BenchmarkBBCodePluginWithoutCodeTag(b *testing.B) {
|
||||
func BenchmarkBBCodePluginWithoutCodeTagSerial(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.Run("empty_post", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
@ -1263,7 +1131,7 @@ func BenchmarkBBCodePluginWithoutCodeTag(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func BenchmarkBBCodePluginWithFullParser(b *testing.B) {
|
||||
func BenchmarkBBCodePluginWithFullParserSerial(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.Run("empty_post", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
@ -1320,6 +1188,186 @@ func TestLevels(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestStaticRoute(t *testing.T) {
|
||||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
if !plugins_inited {
|
||||
init_plugins()
|
||||
}
|
||||
|
||||
static_w := httptest.NewRecorder()
|
||||
static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil))
|
||||
static_handler := http.HandlerFunc(route_static)
|
||||
|
||||
static_handler.ServeHTTP(static_w,static_req)
|
||||
if static_w.Code != 200 {
|
||||
fmt.Println(static_w.Body)
|
||||
panic("HTTP Error!")
|
||||
}
|
||||
fmt.Println("No problems found in the static route!")
|
||||
}
|
||||
|
||||
func TestTopicAdminRoute(t *testing.T) {
|
||||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
if !plugins_inited {
|
||||
init_plugins()
|
||||
}
|
||||
|
||||
admin, err := users.CascadeGet(1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !admin.Is_Admin {
|
||||
panic("UID1 is not an admin")
|
||||
}
|
||||
|
||||
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
|
||||
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year}
|
||||
|
||||
topic_w := httptest.NewRecorder()
|
||||
topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil))
|
||||
topic_req_admin := topic_req
|
||||
topic_req_admin.AddCookie(&admin_uid_cookie)
|
||||
topic_req_admin.AddCookie(&admin_session_cookie)
|
||||
topic_handler := http.HandlerFunc(route_topic_id)
|
||||
|
||||
topic_handler.ServeHTTP(topic_w,topic_req_admin)
|
||||
if topic_w.Code != 200 {
|
||||
fmt.Println(topic_w.Body)
|
||||
panic("HTTP Error!")
|
||||
}
|
||||
fmt.Println("No problems found in the topic-admin route!")
|
||||
}
|
||||
|
||||
func TestTopicGuestRoute(t *testing.T) {
|
||||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
if !plugins_inited {
|
||||
init_plugins()
|
||||
}
|
||||
|
||||
topic_w := httptest.NewRecorder()
|
||||
topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil))
|
||||
topic_handler := http.HandlerFunc(route_topic_id)
|
||||
|
||||
topic_handler.ServeHTTP(topic_w,topic_req)
|
||||
if topic_w.Code != 200 {
|
||||
fmt.Println(topic_w.Body)
|
||||
panic("HTTP Error!")
|
||||
}
|
||||
fmt.Println("No problems found in the topic-guest route!")
|
||||
}
|
||||
|
||||
func TestForumsAdminRoute(t *testing.T) {
|
||||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
if !plugins_inited {
|
||||
init_plugins()
|
||||
}
|
||||
|
||||
admin, err := users.CascadeGet(1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !admin.Is_Admin {
|
||||
panic("UID1 is not an admin")
|
||||
}
|
||||
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
|
||||
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year}
|
||||
|
||||
forums_w := httptest.NewRecorder()
|
||||
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
|
||||
forums_req_admin := forums_req
|
||||
forums_req_admin.AddCookie(&admin_uid_cookie)
|
||||
forums_req_admin.AddCookie(&admin_session_cookie)
|
||||
forums_handler := http.HandlerFunc(route_forums)
|
||||
|
||||
forums_handler.ServeHTTP(forums_w,forums_req_admin)
|
||||
if forums_w.Code != 200 {
|
||||
fmt.Println(forums_w.Body)
|
||||
panic("HTTP Error!")
|
||||
}
|
||||
fmt.Println("No problems found in the forums-admin route!")
|
||||
}
|
||||
|
||||
func TestForumsGuestRoute(t *testing.T) {
|
||||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
if !plugins_inited {
|
||||
init_plugins()
|
||||
}
|
||||
|
||||
forums_w := httptest.NewRecorder()
|
||||
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
|
||||
forums_handler := http.HandlerFunc(route_forums)
|
||||
|
||||
forums_handler.ServeHTTP(forums_w,forums_req)
|
||||
if forums_w.Code != 200 {
|
||||
fmt.Println(forums_w.Body)
|
||||
panic("HTTP Error!")
|
||||
}
|
||||
fmt.Println("No problems found in the forums-guest route!")
|
||||
}
|
||||
|
||||
func TestForumAdminRoute(t *testing.T) {
|
||||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
if !plugins_inited {
|
||||
init_plugins()
|
||||
}
|
||||
|
||||
admin, err := users.CascadeGet(1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !admin.Is_Admin {
|
||||
panic("UID1 is not an admin")
|
||||
}
|
||||
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
|
||||
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year}
|
||||
|
||||
forum_w := httptest.NewRecorder()
|
||||
forum_req := httptest.NewRequest("get","/forum/2",bytes.NewReader(nil))
|
||||
forum_req_admin := forum_req
|
||||
forum_req_admin.AddCookie(&admin_uid_cookie)
|
||||
forum_req_admin.AddCookie(&admin_session_cookie)
|
||||
forum_handler := http.HandlerFunc(route_forum)
|
||||
|
||||
forum_handler.ServeHTTP(forum_w,forum_req_admin)
|
||||
if forum_w.Code != 200 {
|
||||
fmt.Println(forum_w.Body)
|
||||
panic("HTTP Error!")
|
||||
}
|
||||
fmt.Println("No problems found in the forum-admin route!")
|
||||
}
|
||||
|
||||
func TestForumGuestRoute(t *testing.T) {
|
||||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
if !plugins_inited {
|
||||
init_plugins()
|
||||
}
|
||||
|
||||
forum_w := httptest.NewRecorder()
|
||||
forum_req := httptest.NewRequest("get","/forum/2",bytes.NewReader(nil))
|
||||
forum_handler := http.HandlerFunc(route_forum)
|
||||
|
||||
forum_handler.ServeHTTP(forum_w,forum_req)
|
||||
if forum_w.Code != 200 {
|
||||
fmt.Println(forum_w.Body)
|
||||
panic("HTTP Error!")
|
||||
}
|
||||
fmt.Println("No problems found in the forum-guest route!")
|
||||
}
|
||||
|
||||
/*func TestRoute(t *testing.T) {
|
||||
|
||||
}*/
|
After Width: | Height: | Size: 31 KiB |
45
main.go
|
@ -123,6 +123,29 @@ func init_templates() {
|
|||
template.Must(templates.ParseGlob("pages/*"))
|
||||
}
|
||||
|
||||
func init_static_files() {
|
||||
log.Print("Loading the static files.")
|
||||
err := filepath.Walk("./public", func(path string, f os.FileInfo, err error) error {
|
||||
if f.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
path = strings.Replace(path,"\\","/",-1)
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path = strings.TrimPrefix(path,"public/")
|
||||
log.Print("Added the '" + path + "' static file.")
|
||||
static_files["/static/" + path] = SFile{data,compress_bytes_gzip(data),0,int64(len(data)),mime.TypeByExtension(filepath.Ext("/public/" + path)),f,f.ModTime().UTC().Format(http.TimeFormat)}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main(){
|
||||
//if profiling {
|
||||
// f, err := os.Create("startup_cpu.prof")
|
||||
|
@ -151,27 +174,7 @@ func main(){
|
|||
topics = NewSqlTopicStore()
|
||||
}
|
||||
|
||||
log.Print("Loading the static files.")
|
||||
err = filepath.Walk("./public", func(path string, f os.FileInfo, err error) error {
|
||||
if f.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
path = strings.Replace(path,"\\","/",-1)
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path = strings.TrimPrefix(path,"public/")
|
||||
log.Print("Added the '" + path + "' static file.")
|
||||
static_files["/static/" + path] = SFile{data,compress_bytes_gzip(data),0,int64(len(data)),mime.TypeByExtension(filepath.Ext("/public/" + path)),f,f.ModTime().UTC().Format(http.TimeFormat)}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
init_static_files()
|
||||
external_sites["YT"] = "https://www.youtube.com/"
|
||||
hooks["trow_assign"] = nil
|
||||
hooks["rrow_assign"] = nil
|
||||
|
|
|
@ -57,6 +57,12 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
err = topics.Load(tid)
|
||||
if err != nil {
|
||||
LocalError("This topic no longer exists!",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
if is_js == "0" {
|
||||
http.Redirect(w,r,"/topic/" + strconv.Itoa(tid),http.StatusSeeOther)
|
||||
} else {
|
||||
|
@ -114,6 +120,7 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
forums[fid].TopicCount -= 1
|
||||
topics.Remove(tid)
|
||||
}
|
||||
|
||||
func route_stick_topic(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -123,8 +130,7 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
var fid int
|
||||
err = db.QueryRow("select parentID from topics where tid = ?", tid).Scan(&fid)
|
||||
topic, err := topics.CascadeGet(tid)
|
||||
if err == sql.ErrNoRows {
|
||||
PreError("The topic you tried to pin doesn't exist.",w,r)
|
||||
return
|
||||
|
@ -133,7 +139,7 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
user, ok := SimpleForumSessionCheck(w,r,fid)
|
||||
user, ok := SimpleForumSessionCheck(w,r,topic.ParentID)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
@ -147,6 +153,8 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) {
|
|||
InternalError(err,w,r)
|
||||
return
|
||||
}
|
||||
|
||||
topic.Sticky = true
|
||||
http.Redirect(w,r,"/topic/" + strconv.Itoa(tid),http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
@ -157,8 +165,7 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
var fid int
|
||||
err = db.QueryRow("select parentID from topics where tid = ?", tid).Scan(&fid)
|
||||
topic, err := topics.CascadeGet(tid)
|
||||
if err == sql.ErrNoRows {
|
||||
PreError("The topic you tried to unpin doesn't exist.",w,r)
|
||||
return
|
||||
|
@ -167,7 +174,7 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
user, ok := SimpleForumSessionCheck(w,r,fid)
|
||||
user, ok := SimpleForumSessionCheck(w,r,topic.ParentID)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
@ -181,6 +188,8 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) {
|
|||
InternalError(err,w,r)
|
||||
return
|
||||
}
|
||||
|
||||
topic.Sticky = false
|
||||
http.Redirect(w,r,"/topic/" + strconv.Itoa(tid),http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
@ -312,6 +321,12 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
|
|||
if err != nil {
|
||||
InternalErrorJSQ(err,w,r,is_js)
|
||||
}
|
||||
|
||||
err = topics.Load(tid)
|
||||
if err != nil {
|
||||
LocalError("This topic no longer exists!",w,r,user)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func route_profile_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -374,7 +389,6 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
|
|||
LocalError("Bad Form",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
is_js := r.PostFormValue("is_js")
|
||||
if is_js == "" {
|
||||
is_js = "0"
|
||||
|
@ -387,7 +401,7 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
var uid int
|
||||
err = db.QueryRow("SELECT uid from users_replies where rid = ?", rid).Scan(&uid)
|
||||
err = db.QueryRow("select uid from users_replies where rid = ?", rid).Scan(&uid)
|
||||
if err == sql.ErrNoRows {
|
||||
LocalErrorJSQ("The reply you tried to delete doesn't exist.",w,r,user,is_js)
|
||||
return
|
||||
|
@ -502,6 +516,12 @@ func route_ban_submit(w http.ResponseWriter, r *http.Request) {
|
|||
InternalError(err,w,r)
|
||||
return
|
||||
}
|
||||
|
||||
err = users.Load(uid)
|
||||
if err != nil {
|
||||
LocalError("This user no longer exists!",w,r,user)
|
||||
return
|
||||
}
|
||||
http.Redirect(w,r,"/users/" + strconv.Itoa(uid),http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
@ -546,6 +566,12 @@ func route_unban(w http.ResponseWriter, r *http.Request) {
|
|||
InternalError(err,w,r)
|
||||
return
|
||||
}
|
||||
|
||||
err = users.Load(uid)
|
||||
if err != nil {
|
||||
LocalError("This user no longer exists!",w,r,user)
|
||||
return
|
||||
}
|
||||
http.Redirect(w,r,"/users/" + strconv.Itoa(uid),http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
@ -595,6 +621,12 @@ func route_activate(w http.ResponseWriter, r *http.Request) {
|
|||
InternalError(err,w,r)
|
||||
return
|
||||
}
|
||||
|
||||
err = users.Load(uid)
|
||||
if err != nil {
|
||||
LocalError("This user no longer exists!",w,r,user)
|
||||
return
|
||||
}
|
||||
http.Redirect(w,r,"/users/" + strconv.Itoa(uid),http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
@ -973,7 +1005,7 @@ func route_panel_setting_edit(w http.ResponseWriter, r *http.Request) {
|
|||
sname := r.URL.Path[len("/panel/settings/edit/submit/"):]
|
||||
scontent := r.PostFormValue("setting-value")
|
||||
|
||||
err = db.QueryRow("SELECT name, type, constraints from settings where name = ?", sname).Scan(&sname, &stype, &sconstraints)
|
||||
err = db.QueryRow("select name, type, constraints from settings where name = ?", sname).Scan(&sname, &stype, &sconstraints)
|
||||
if err == sql.ErrNoRows {
|
||||
LocalError("The setting you want to edit doesn't exist.",w,r,user)
|
||||
return
|
||||
|
@ -1208,15 +1240,13 @@ func route_panel_users_edit(w http.ResponseWriter, r *http.Request){
|
|||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
targetUser := User{ID: 0,}
|
||||
targetUser.ID, err = strconv.Atoi(r.URL.Path[len("/panel/users/edit/"):])
|
||||
uid, err := strconv.Atoi(r.URL.Path[len("/panel/users/edit/"):])
|
||||
if err != nil {
|
||||
LocalError("The provided User ID is not a valid number.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
err = db.QueryRow("select `name`,`email`,`group` from `users` where `uid` = ?", targetUser.ID).Scan(&targetUser.Name,&targetUser.Email,&targetUser.Group)
|
||||
targetUser, err := users.Get(uid)
|
||||
if err == sql.ErrNoRows {
|
||||
LocalError("The user you're trying to edit doesn't exist.",w,r,user)
|
||||
return
|
||||
|
@ -1225,8 +1255,6 @@ func route_panel_users_edit(w http.ResponseWriter, r *http.Request){
|
|||
return
|
||||
}
|
||||
|
||||
targetUser.Is_Admin = targetUser.Is_Super_Admin || groups[targetUser.Group].Is_Admin
|
||||
targetUser.Is_Super_Mod = groups[targetUser.Group].Is_Mod || targetUser.Is_Admin
|
||||
if targetUser.Is_Admin && !user.Is_Admin {
|
||||
LocalError("Only administrators can edit the account of an administrator.",w,r,user)
|
||||
return
|
||||
|
@ -1264,15 +1292,13 @@ func route_panel_users_edit_submit(w http.ResponseWriter, r *http.Request){
|
|||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
targetUser := User{ID: 0,}
|
||||
targetUser.ID, err = strconv.Atoi(r.URL.Path[len("/panel/users/edit/submit/"):])
|
||||
tid, err := strconv.Atoi(r.URL.Path[len("/panel/users/edit/submit/"):])
|
||||
if err != nil {
|
||||
LocalError("The provided User ID is not a valid number.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
err = db.QueryRow("select `name`,`email`,`group` from `users` where `uid` = ?", targetUser.ID).Scan(&targetUser.Name, &targetUser.Email, &targetUser.Group)
|
||||
targetUser, err := users.Get(tid)
|
||||
if err == sql.ErrNoRows {
|
||||
LocalError("The user you're trying to edit doesn't exist.",w,r,user)
|
||||
return
|
||||
|
@ -1281,8 +1307,6 @@ func route_panel_users_edit_submit(w http.ResponseWriter, r *http.Request){
|
|||
return
|
||||
}
|
||||
|
||||
targetUser.Is_Admin = targetUser.Is_Super_Admin || groups[targetUser.Group].Is_Admin
|
||||
targetUser.Is_Super_Mod = groups[targetUser.Group].Is_Mod || targetUser.Is_Admin
|
||||
if targetUser.Is_Admin && !user.Is_Admin {
|
||||
LocalError("Only administrators can edit the account of an administrator.",w,r,user)
|
||||
return
|
||||
|
@ -1340,6 +1364,12 @@ func route_panel_users_edit_submit(w http.ResponseWriter, r *http.Request){
|
|||
SetPassword(targetUser.ID, newpassword)
|
||||
}
|
||||
|
||||
err = users.Load(targetUser.ID)
|
||||
if err != nil {
|
||||
LocalError("This user no longer exists!",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w,r,"/panel/users/edit/" + strconv.Itoa(targetUser.ID),http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
|
5
mysql.go
|
@ -9,6 +9,8 @@ import "strconv"
|
|||
import "encoding/json"
|
||||
|
||||
var db *sql.DB
|
||||
var db_version string
|
||||
|
||||
var get_user_stmt *sql.Stmt
|
||||
var get_full_user_stmt *sql.Stmt
|
||||
var get_topic_list_stmt *sql.Stmt
|
||||
|
@ -92,6 +94,9 @@ func init_database(err error) {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Getting the database version..
|
||||
db.QueryRow("SELECT VERSION()").Scan(&db_version)
|
||||
|
||||
/*log.Print("Preparing get_session statement.")
|
||||
get_session_stmt, err = db.Prepare("select `uid`,`name`,`group`,`is_super_admin`,`session`,`email`,`avatar`,`message`,`url_prefix`,`url_name`,`level`,`score`,`last_ip` from `users` where `uid` = ? and `session` = ? AND `session` <> ''")
|
||||
if err != nil {
|
||||
|
|
After Width: | Height: | Size: 126 KiB |
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
|
@ -153,6 +153,8 @@ func init() {
|
|||
ExtData: make(map[string]bool),
|
||||
}
|
||||
|
||||
guest_user.Perms = GuestPerms
|
||||
|
||||
if debug {
|
||||
fmt.Printf("Guest Perms: ")
|
||||
fmt.Printf("%+v\n", GuestPerms)
|
||||
|
|
|
@ -28,17 +28,13 @@ func (router *Router) HandleFunc(pattern string, handle func(http.ResponseWriter
|
|||
}
|
||||
|
||||
func (router *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
router.mu.RLock()
|
||||
|
||||
if req.URL.Path[0] != '/' {
|
||||
router.mu.RUnlock()
|
||||
w.WriteHeader(405)
|
||||
w.Write([]byte(""))
|
||||
return
|
||||
}
|
||||
|
||||
// Do something on the path to turn slashes facing the wrong way "\" into "/" slashes. Like what? Wouldn't that be slow? Might need to move to fasthttp for this
|
||||
|
||||
router.mu.RLock()
|
||||
handle, ok := router.routes[req.URL.Path]
|
||||
if ok {
|
||||
router.mu.RUnlock()
|
||||
|
|
78
routes.go
|
@ -113,7 +113,7 @@ func route_topics(w http.ResponseWriter, r *http.Request){
|
|||
return
|
||||
}
|
||||
|
||||
topicItem := TopicsRow{ID: 0,}
|
||||
topicItem := TopicsRow{ID: 0}
|
||||
for rows.Next() {
|
||||
err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.Is_Closed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.LastReplyAt, &topicItem.ParentID, &topicItem.LikeCount, &topicItem.CreatedByName, &topicItem.Avatar)
|
||||
if err != nil {
|
||||
|
@ -316,33 +316,25 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
|||
return
|
||||
}
|
||||
if !user.Perms.ViewTopic {
|
||||
//fmt.Printf("%+v\n", user.Perms)
|
||||
NoPermissions(w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
topic.ContentLines = strings.Count(topic.Content,"\n")
|
||||
topic.Content = parse_message(topic.Content)
|
||||
topic.ContentLines = strings.Count(topic.Content,"\n")
|
||||
|
||||
// We don't want users posting in locked topics...
|
||||
if topic.Is_Closed && !user.Is_Mod {
|
||||
user.Perms.CreateReply = false
|
||||
}
|
||||
|
||||
if topic.Avatar != "" {
|
||||
if topic.Avatar[0] == '.' {
|
||||
topic.Avatar = "/uploads/avatar_" + strconv.Itoa(topic.CreatedBy) + topic.Avatar
|
||||
}
|
||||
} else {
|
||||
topic.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(topic.CreatedBy),1)
|
||||
}
|
||||
if groups[topic.Group].Is_Mod || groups[topic.Group].Is_Admin {
|
||||
if groups[topic.Group].Is_Mod {
|
||||
topic.Css = staff_css_tmpl
|
||||
topic.Level = -1
|
||||
}
|
||||
|
||||
topic.Tag = groups[topic.Group].Tag
|
||||
|
||||
if settings["url_tags"] == false {
|
||||
/*if settings["url_tags"] == false {
|
||||
topic.URLName = ""
|
||||
} else {
|
||||
topic.URL, ok = external_sites[topic.URLPrefix]
|
||||
|
@ -351,7 +343,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
|||
} else {
|
||||
topic.URL = topic.URL + topic.URLName
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// Calculate the offset
|
||||
last_page := int(topic.PostCount / items_per_page) + 1
|
||||
|
@ -415,7 +407,6 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
|
|||
replyItem.URL = replyItem.URL + replyItem.URLName
|
||||
}
|
||||
}*/
|
||||
|
||||
replyItem.Liked = false
|
||||
|
||||
if hooks["rrow_assign"] != nil {
|
||||
|
@ -465,19 +456,19 @@ func route_profile(w http.ResponseWriter, r *http.Request){
|
|||
replyList []Reply
|
||||
)
|
||||
|
||||
puser := User{ID: 0,}
|
||||
puser.ID, err = strconv.Atoi(r.URL.Path[len("/user/"):])
|
||||
pid, err := strconv.Atoi(r.URL.Path[len("/user/"):])
|
||||
if err != nil {
|
||||
LocalError("The provided TopicID is not a valid number.",w,r,user)
|
||||
LocalError("The provided User ID is not a valid number.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
if puser.ID == user.ID {
|
||||
var puser *User
|
||||
if pid == user.ID {
|
||||
user.Is_Mod = true
|
||||
puser = user
|
||||
puser = &user
|
||||
} else {
|
||||
// Fetch the user data
|
||||
err = get_user_stmt.QueryRow(puser.ID).Scan(&puser.Name, &puser.Group, &puser.Is_Super_Admin, &puser.Avatar, &puser.Message, &puser.URLPrefix, &puser.URLName, &puser.Level)
|
||||
puser, err = users.CascadeGet(pid)
|
||||
if err == sql.ErrNoRows {
|
||||
NotFound(w,r)
|
||||
return
|
||||
|
@ -485,24 +476,6 @@ func route_profile(w http.ResponseWriter, r *http.Request){
|
|||
InternalError(err,w,r)
|
||||
return
|
||||
}
|
||||
|
||||
puser.Is_Admin = puser.Is_Super_Admin || groups[puser.Group].Is_Admin
|
||||
puser.Is_Super_Mod = puser.Is_Admin || groups[puser.Group].Is_Mod
|
||||
puser.Is_Mod = puser.Is_Super_Mod
|
||||
puser.Is_Banned = groups[puser.Group].Is_Banned
|
||||
if puser.Is_Banned && puser.Is_Super_Mod {
|
||||
puser.Is_Banned = false
|
||||
}
|
||||
}
|
||||
|
||||
puser.Tag = groups[puser.Group].Tag
|
||||
|
||||
if puser.Avatar != "" {
|
||||
if puser.Avatar[0] == '.' {
|
||||
puser.Avatar = "/uploads/avatar_" + strconv.Itoa(puser.ID) + puser.Avatar
|
||||
}
|
||||
} else {
|
||||
puser.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(puser.ID),1)
|
||||
}
|
||||
|
||||
// Get the replies..
|
||||
|
@ -553,7 +526,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
|
|||
return
|
||||
}
|
||||
|
||||
ppage := ProfilePage{puser.Name + "'s Profile",user,noticeList,replyList,puser,false}
|
||||
ppage := ProfilePage{puser.Name + "'s Profile",user,noticeList,replyList,*puser,false}
|
||||
if template_profile_handle != nil {
|
||||
template_profile_handle(ppage,w)
|
||||
} else {
|
||||
|
@ -922,7 +895,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
LocalError("Bad Form", w, r, user)
|
||||
LocalError("Bad Form",w,r,user)
|
||||
return
|
||||
}
|
||||
if r.FormValue("session") != user.Session {
|
||||
|
@ -1213,6 +1186,11 @@ func route_account_own_edit_avatar_submit(w http.ResponseWriter, r *http.Request
|
|||
return
|
||||
}
|
||||
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + "." + ext
|
||||
err = users.Load(user.ID)
|
||||
if err != nil {
|
||||
LocalError("This user no longer exists!",w,r,user)
|
||||
return
|
||||
}
|
||||
noticeList = append(noticeList, "Your avatar was successfully updated")
|
||||
|
||||
pi := Page{"Edit Avatar",user,noticeList,tList,nil}
|
||||
|
@ -1253,7 +1231,13 @@ func route_account_own_edit_username_submit(w http.ResponseWriter, r *http.Reque
|
|||
LocalError("Unable to change the username. Does someone else already have this name?",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
user.Name = new_username
|
||||
err = users.Load(user.ID)
|
||||
if err != nil {
|
||||
LocalError("Your account doesn't exist!",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
noticeList = append(noticeList,"Your username was successfully updated")
|
||||
pi := Page{"Edit Username",user,noticeList,tList,nil}
|
||||
|
@ -1305,7 +1289,7 @@ func route_account_own_edit_email(w http.ResponseWriter, r *http.Request) {
|
|||
if !enable_emails {
|
||||
noticeList = append(noticeList, "The email system has been turned off. All features involving sending emails have been disabled.")
|
||||
}
|
||||
pi := Page{"Email Manager",user,noticeList,emailList,0}
|
||||
pi := Page{"Email Manager",user,noticeList,emailList,nil}
|
||||
templates.ExecuteTemplate(w,"account-own-edit-email.html", pi)
|
||||
}
|
||||
|
||||
|
@ -1376,7 +1360,7 @@ func route_account_own_edit_email_token_submit(w http.ResponseWriter, r *http.Re
|
|||
noticeList = append(noticeList,"The email system has been turned off. All features involving sending emails have been disabled.")
|
||||
}
|
||||
noticeList = append(noticeList,"Your email was successfully verified")
|
||||
pi := Page{"Email Manager",user,noticeList,emailList,0}
|
||||
pi := Page{"Email Manager",user,noticeList,emailList,nil}
|
||||
templates.ExecuteTemplate(w,"account-own-edit-email.html", pi)
|
||||
}
|
||||
|
||||
|
@ -1395,6 +1379,12 @@ func route_logout(w http.ResponseWriter, r *http.Request) {
|
|||
InternalError(err,w,r)
|
||||
return
|
||||
}
|
||||
|
||||
err = users.Load(user.ID)
|
||||
if err != nil {
|
||||
LocalError("Your account doesn't exist!",w,r,user)
|
||||
return
|
||||
}
|
||||
http.Redirect(w,r, "/", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
@ -1408,7 +1398,7 @@ func route_login(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
pi := Page{"Login",user,noticeList,tList,nil}
|
||||
templates.ExecuteTemplate(w,"login.html", pi)
|
||||
templates.ExecuteTemplate(w,"login.html",pi)
|
||||
}
|
||||
|
||||
func route_login_submit(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||
package main
|
||||
import "io"
|
||||
import "strconv"
|
||||
import "io"
|
||||
|
||||
func init() {
|
||||
template_forum_handle = template_forum
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||
package main
|
||||
import "strconv"
|
||||
import "io"
|
||||
import "strconv"
|
||||
|
||||
func init() {
|
||||
template_forums_handle = template_forums
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||
package main
|
||||
import "strconv"
|
||||
import "io"
|
||||
import "strconv"
|
||||
|
||||
func init() {
|
||||
template_topic_handle = template_topic
|
||||
|
|
|
@ -871,6 +871,7 @@ func (c *CTemplateSet) compile_subtemplate(pvarholder string, pholdreflect refle
|
|||
}
|
||||
|
||||
func (c *CTemplateSet) compile_command(*parse.CommandNode) (out string) {
|
||||
panic("Uh oh! Something went wrong!")
|
||||
return ""
|
||||
}
|
||||
|
||||
|
|
657
templates_old.go
|
@ -1,657 +0,0 @@
|
|||
package main
|
||||
import "log"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
import "reflect"
|
||||
import "path/filepath"
|
||||
import "io/ioutil"
|
||||
import "text/template/parse"
|
||||
|
||||
/* Keeping this so I can benchmark against it */
|
||||
|
||||
type CTemplateSet2 struct
|
||||
{
|
||||
tlist map[string]*parse.Tree
|
||||
dir string
|
||||
funcMap map[string]interface{}
|
||||
importMap map[string]string
|
||||
varList map[string]VarItem
|
||||
localVars map[string]map[string]VarItemReflect
|
||||
//tempVars map[string]string
|
||||
doImports bool
|
||||
expectsInt interface{}
|
||||
}
|
||||
|
||||
func (c *CTemplateSet2) compile_template_2(name string, dir string, expects string, expectsInt interface{}, varList map[string]VarItem) (out string) {
|
||||
c.dir = dir
|
||||
c.doImports = true
|
||||
c.funcMap = make(map[string]interface{})
|
||||
c.funcMap["and"] = "&&"
|
||||
c.funcMap["not"] = "!"
|
||||
c.funcMap["or"] = "||"
|
||||
c.funcMap["eq"] = true
|
||||
c.funcMap["ge"] = true
|
||||
c.funcMap["gt"] = true
|
||||
c.funcMap["le"] = true
|
||||
c.funcMap["lt"] = true
|
||||
c.funcMap["ne"] = true
|
||||
c.importMap = make(map[string]string)
|
||||
c.importMap["strconv"] = "strconv"
|
||||
c.varList = varList
|
||||
c.expectsInt = expectsInt
|
||||
holdreflect := reflect.ValueOf(expectsInt)
|
||||
|
||||
res, err := ioutil.ReadFile(dir + name)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
content := string(res)
|
||||
|
||||
tree := parse.New(name, c.funcMap)
|
||||
var treeSet map[string]*parse.Tree = make(map[string]*parse.Tree)
|
||||
tree, err = tree.Parse(content,"{{","}}", treeSet, c.funcMap)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if debug {
|
||||
fmt.Println(name)
|
||||
}
|
||||
|
||||
out = ""
|
||||
fname := strings.TrimSuffix(name, filepath.Ext(name))
|
||||
c.tlist = make(map[string]*parse.Tree)
|
||||
c.tlist[fname] = tree
|
||||
varholder := "tmpl_" + fname + "_vars"
|
||||
|
||||
if debug {
|
||||
fmt.Println(c.tlist)
|
||||
}
|
||||
|
||||
c.localVars = make(map[string]map[string]VarItemReflect)
|
||||
c.localVars[fname] = make(map[string]VarItemReflect)
|
||||
c.localVars[fname]["."] = VarItemReflect{".",varholder,holdreflect}
|
||||
|
||||
subtree := c.tlist[fname]
|
||||
if debug {
|
||||
fmt.Println(subtree.Root)
|
||||
}
|
||||
|
||||
for _, node := range subtree.Root.Nodes {
|
||||
if debug {
|
||||
fmt.Println("Node: " + node.String())
|
||||
}
|
||||
out += c.compile_switch(varholder, holdreflect, fname, node)
|
||||
}
|
||||
|
||||
var importList string
|
||||
if c.doImports {
|
||||
for _, item := range c.importMap {
|
||||
importList += "import \"" + item + "\"\n"
|
||||
}
|
||||
}
|
||||
|
||||
var varString string
|
||||
for _, varItem := range c.varList {
|
||||
varString += "var " + varItem.Name + " " + varItem.Type + " = " + varItem.Destination + "\n"
|
||||
}
|
||||
|
||||
out = "package main\n" + importList + "\nfunc init() {\nctemplates[\"" + fname + "\"] = template_" + fname + "\n}\n\nfunc template_" + fname + "(tmpl_" + fname + "_vars " + expects + ") (tmpl string) {\n" + varString + out + "return tmpl\n}\n"
|
||||
if debug {
|
||||
fmt.Println("Output!")
|
||||
fmt.Println(out)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (c *CTemplateSet2) compile_switch(varholder string, holdreflect reflect.Value, template_name string, node interface{}) (out string) {
|
||||
switch node := node.(type) {
|
||||
case *parse.ActionNode:
|
||||
if debug {
|
||||
fmt.Println("Action Node")
|
||||
}
|
||||
|
||||
if node.Pipe == nil {
|
||||
break
|
||||
}
|
||||
for _, cmd := range node.Pipe.Cmds {
|
||||
out += c.compile_subswitch(varholder, holdreflect, template_name, cmd)
|
||||
}
|
||||
return out
|
||||
case *parse.IfNode:
|
||||
if debug {
|
||||
fmt.Println("If Node: ")
|
||||
fmt.Println(node.Pipe)
|
||||
}
|
||||
|
||||
var expr string
|
||||
for _, cmd := range node.Pipe.Cmds {
|
||||
if debug {
|
||||
fmt.Println("If Node Bit: ")
|
||||
fmt.Println(cmd)
|
||||
fmt.Println(reflect.ValueOf(cmd).Type().Name())
|
||||
}
|
||||
expr += c.compile_varswitch(varholder, holdreflect, template_name, cmd)
|
||||
}
|
||||
|
||||
if node.ElseList == nil {
|
||||
if debug {
|
||||
fmt.Println("Branch 1")
|
||||
}
|
||||
return "if " + expr + " {\n" + c.compile_switch(varholder, holdreflect, template_name, node.List) + "}\n"
|
||||
} else {
|
||||
if debug {
|
||||
fmt.Println("Branch 2")
|
||||
}
|
||||
return "if " + expr + " {\n" + c.compile_switch(varholder, holdreflect, template_name, node.List) + "} else {\n" + c.compile_switch(varholder, holdreflect, template_name, node.ElseList) + "}\n"
|
||||
}
|
||||
case *parse.ListNode:
|
||||
if debug {
|
||||
fmt.Println("List Node")
|
||||
}
|
||||
for _, subnode := range node.Nodes {
|
||||
out += c.compile_switch(varholder, holdreflect, template_name, subnode)
|
||||
}
|
||||
return out
|
||||
case *parse.RangeNode:
|
||||
if debug {
|
||||
fmt.Println("Range Node!")
|
||||
fmt.Println(node.Pipe)
|
||||
}
|
||||
|
||||
var outVal reflect.Value
|
||||
for _, cmd := range node.Pipe.Cmds {
|
||||
if debug {
|
||||
fmt.Println("Range Bit: ")
|
||||
fmt.Println(cmd)
|
||||
}
|
||||
out, outVal = c.compile_reflectswitch(varholder, holdreflect, template_name, cmd)
|
||||
}
|
||||
|
||||
if debug {
|
||||
fmt.Println("Returned: ")
|
||||
fmt.Println(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)
|
||||
}
|
||||
|
||||
out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compile_switch("item", item, template_name, node.List) + "}\n}"
|
||||
case reflect.Invalid:
|
||||
return ""
|
||||
}
|
||||
|
||||
if node.ElseList != nil {
|
||||
out += " else {\n" + c.compile_switch(varholder, holdreflect, template_name, node.ElseList) + "}\n"
|
||||
} else {
|
||||
out += "\n"
|
||||
}
|
||||
return out
|
||||
case *parse.TemplateNode:
|
||||
if debug {
|
||||
fmt.Println("Template Node")
|
||||
}
|
||||
return c.compile_subtemplate(varholder, holdreflect, node)
|
||||
case *parse.TextNode:
|
||||
return "tmpl += `" + string(node.Text) + "`\n"
|
||||
default:
|
||||
panic("Unknown Node in main switch")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *CTemplateSet2) compile_subswitch(varholder string, holdreflect reflect.Value, template_name string, node *parse.CommandNode) (out string) {
|
||||
firstWord := node.Args[0]
|
||||
switch n := firstWord.(type) {
|
||||
case *parse.FieldNode:
|
||||
if debug {
|
||||
fmt.Println("Field Node: ")
|
||||
fmt.Println(n.Ident)
|
||||
}
|
||||
|
||||
/* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Coming Soon. */
|
||||
cur := holdreflect
|
||||
|
||||
var varbit string
|
||||
if cur.Kind() == reflect.Interface {
|
||||
cur = cur.Elem()
|
||||
varbit += ".(" + cur.Type().Name() + ")"
|
||||
}
|
||||
|
||||
for _, id := range n.Ident {
|
||||
if debug {
|
||||
fmt.Println("Data Kind: ")
|
||||
fmt.Println(cur.Kind().String())
|
||||
fmt.Println("Field Bit: ")
|
||||
fmt.Println(id)
|
||||
}
|
||||
|
||||
cur = cur.FieldByName(id)
|
||||
if cur.Kind() == reflect.Interface {
|
||||
cur = cur.Elem()
|
||||
/*if cur.Kind() == reflect.String && cur.Type().Name() != "string" {
|
||||
varbit = "string(" + varbit + "." + id + ")"*/
|
||||
//if cur.Kind() == reflect.String && cur.Type().Name() != "string" {
|
||||
if cur.Type().PkgPath() != "main" {
|
||||
c.importMap["html/template"] = "html/template"
|
||||
varbit += "." + id + ".(" + strings.TrimPrefix(cur.Type().PkgPath(),"html/") + "." + cur.Type().Name() + ")"
|
||||
} else {
|
||||
varbit += "." + id + ".(" + cur.Type().Name() + ")"
|
||||
}
|
||||
} else {
|
||||
varbit += "." + id
|
||||
}
|
||||
|
||||
if debug {
|
||||
fmt.Println("End Cycle")
|
||||
}
|
||||
}
|
||||
out = c.compile_varsub(varholder + varbit, cur)
|
||||
|
||||
for _, varItem := range c.varList {
|
||||
if strings.HasPrefix(out, varItem.Destination) {
|
||||
out = strings.Replace(out, varItem.Destination, varItem.Name, 1)
|
||||
}
|
||||
}
|
||||
return out
|
||||
case *parse.DotNode:
|
||||
if debug {
|
||||
fmt.Println("Dot Node")
|
||||
fmt.Println(node.String())
|
||||
}
|
||||
return c.compile_varsub(varholder, holdreflect)
|
||||
case *parse.NilNode:
|
||||
panic("Nil is not a command x.x")
|
||||
case *parse.VariableNode:
|
||||
if debug {
|
||||
fmt.Println("Variable Node")
|
||||
fmt.Println(n.String())
|
||||
fmt.Println(n.Ident)
|
||||
}
|
||||
|
||||
out, _ = c.compile_if_varsub(n.String(), varholder, template_name, holdreflect)
|
||||
return "tmpl += " + out + "\n"
|
||||
case *parse.StringNode:
|
||||
return n.Quoted
|
||||
default:
|
||||
fmt.Println("Unknown Kind: ")
|
||||
fmt.Println(reflect.ValueOf(firstWord).Elem().Kind())
|
||||
fmt.Println("Unknown Type: ")
|
||||
fmt.Println(reflect.ValueOf(firstWord).Elem().Type().Name())
|
||||
panic("I don't know what node this is")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *CTemplateSet2) compile_varswitch(varholder string, holdreflect reflect.Value, template_name string, node *parse.CommandNode) (out string) {
|
||||
firstWord := node.Args[0]
|
||||
switch n := firstWord.(type) {
|
||||
case *parse.FieldNode:
|
||||
if debug {
|
||||
fmt.Println("Field Node: ")
|
||||
fmt.Println(n.Ident)
|
||||
|
||||
for _, id := range n.Ident {
|
||||
fmt.Println("Field Bit: ")
|
||||
fmt.Println(id)
|
||||
}
|
||||
}
|
||||
|
||||
/* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Coming Soon. */
|
||||
return c.compile_boolsub(n.String(), varholder, template_name, holdreflect)
|
||||
case *parse.ChainNode:
|
||||
if debug {
|
||||
fmt.Println("Chain Node: ")
|
||||
fmt.Println(n.Node)
|
||||
fmt.Println(node.Args)
|
||||
}
|
||||
break
|
||||
case *parse.IdentifierNode:
|
||||
if debug {
|
||||
fmt.Println("Identifier Node: ")
|
||||
fmt.Println(node)
|
||||
fmt.Println(node.Args)
|
||||
}
|
||||
return c.compile_identswitch(varholder, holdreflect, template_name, node)
|
||||
case *parse.DotNode:
|
||||
return varholder
|
||||
case *parse.VariableNode:
|
||||
if debug {
|
||||
fmt.Println("Variable Node")
|
||||
fmt.Println(n.String())
|
||||
fmt.Println(n.Ident)
|
||||
}
|
||||
|
||||
out, _ = c.compile_if_varsub(n.String(), varholder, template_name, holdreflect)
|
||||
return out
|
||||
case *parse.NilNode:
|
||||
panic("Nil is not a command x.x")
|
||||
case *parse.PipeNode:
|
||||
if debug {
|
||||
fmt.Println("Pipe Node!")
|
||||
fmt.Println(n)
|
||||
}
|
||||
|
||||
/*for _, cmd := range n.Cmds {
|
||||
if debug {
|
||||
fmt.Println("Pipe Bit: ")
|
||||
fmt.Println(cmd)
|
||||
}
|
||||
out += c.compile_if_varsub_n(n.String(), varholder, template_name, holdreflect)
|
||||
}*/
|
||||
|
||||
if debug {
|
||||
fmt.Println("Args: ")
|
||||
fmt.Println(node.Args)
|
||||
}
|
||||
|
||||
/*argcopy := node.Args[1:]
|
||||
for _, arg := range argcopy {
|
||||
if debug {
|
||||
fmt.Println("Pipe Arg: ")
|
||||
fmt.Println(arg)
|
||||
fmt.Println(reflect.ValueOf(arg).Elem().Type().Name())
|
||||
fmt.Println(reflect.ValueOf(arg).Kind())
|
||||
}
|
||||
|
||||
switch arg.(type) {
|
||||
case *parse.IdentifierNode:
|
||||
out += c.compile_identswitch(varholder, holdreflect, template_name, node)
|
||||
break
|
||||
case *parse.PipeNode:
|
||||
break
|
||||
//out += c.compile_if_varsub_n(a.String(), varholder, template_name, holdreflect)
|
||||
default:
|
||||
panic("Unknown Pipe Arg type! Did Mario get stuck in the pipes again?")
|
||||
}
|
||||
//out += c.compile_varswitch(arg.String(), holdreflect, template_name, arg)
|
||||
}*/
|
||||
out += c.compile_identswitch(varholder, holdreflect, template_name, node)
|
||||
|
||||
if debug {
|
||||
fmt.Println("Out: ")
|
||||
fmt.Println(out)
|
||||
}
|
||||
return out
|
||||
default:
|
||||
fmt.Println("Unknown Kind: ")
|
||||
fmt.Println(reflect.ValueOf(firstWord).Elem().Kind())
|
||||
fmt.Println("Unknown Type: ")
|
||||
fmt.Println(reflect.ValueOf(firstWord).Elem().Type().Name())
|
||||
panic("I don't know what node this is! Grr...")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *CTemplateSet2) compile_identswitch(varholder string, holdreflect reflect.Value, template_name string, node *parse.CommandNode) (out string) {
|
||||
ArgLoop:
|
||||
for pos, id := range node.Args {
|
||||
if debug {
|
||||
fmt.Println(id)
|
||||
}
|
||||
|
||||
switch id.String() {
|
||||
case "not":
|
||||
out += "!"
|
||||
case "or":
|
||||
out += " || "
|
||||
case "and":
|
||||
out += " && "
|
||||
case "le":
|
||||
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " <= " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
|
||||
break ArgLoop
|
||||
default:
|
||||
if debug {
|
||||
fmt.Println("Variable!")
|
||||
}
|
||||
out += c.compile_if_varsub_n(id.String(), varholder, template_name, holdreflect)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (c *CTemplateSet2) compile_reflectswitch(varholder string, holdreflect reflect.Value, template_name string, node *parse.CommandNode) (out string, outVal reflect.Value) {
|
||||
firstWord := node.Args[0]
|
||||
switch n := firstWord.(type) {
|
||||
case *parse.FieldNode:
|
||||
if debug {
|
||||
fmt.Println("Field Node: ")
|
||||
fmt.Println(n.Ident)
|
||||
|
||||
for _, id := range n.Ident {
|
||||
fmt.Println("Field Bit: ")
|
||||
fmt.Println(id)
|
||||
}
|
||||
}
|
||||
/* Use reflect to determine if the field is for a method, otherwise assume it's a variable. Coming Soon. */
|
||||
return c.compile_if_varsub(n.String(), varholder, template_name, holdreflect)
|
||||
case *parse.ChainNode:
|
||||
if debug {
|
||||
fmt.Println("Chain Node: ")
|
||||
fmt.Println(n.Node)
|
||||
fmt.Println(node.Args)
|
||||
}
|
||||
return "", outVal
|
||||
/*case *parse.IdentifierNode:
|
||||
fmt.Println("Identifier Node: ")
|
||||
fmt.Println(node)
|
||||
fmt.Println(node.Args)
|
||||
|
||||
ArgLoop:
|
||||
for pos, id := range node.Args {
|
||||
fmt.Println(id)
|
||||
switch id.String() {
|
||||
case "not":
|
||||
out += "!"
|
||||
case "or":
|
||||
out += " || "
|
||||
case "and":
|
||||
out += " && "
|
||||
case "le":
|
||||
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, holdreflect) + " <= " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, holdreflect)
|
||||
break ArgLoop
|
||||
default:
|
||||
fmt.Println("Variable!")
|
||||
out += c.compile_if_varsub_n(id.String(), varholder, holdreflect)
|
||||
}
|
||||
}
|
||||
return out*/
|
||||
case *parse.DotNode:
|
||||
return varholder, holdreflect
|
||||
case *parse.NilNode:
|
||||
panic("Nil is not a command x.x")
|
||||
default:
|
||||
//panic("I don't know what node this is")
|
||||
}
|
||||
return "", outVal
|
||||
}
|
||||
|
||||
func (c *CTemplateSet2) compile_if_varsub_n(varname string, varholder string, template_name string, cur reflect.Value) (out string) {
|
||||
out, _ = c.compile_if_varsub(varname, varholder, template_name, cur)
|
||||
return out
|
||||
}
|
||||
|
||||
func (c *CTemplateSet2) compile_if_varsub(varname string, varholder string, template_name string, cur reflect.Value) (out string, val reflect.Value) {
|
||||
if varname[0] != '.' && varname[0] != '$' {
|
||||
return varname, cur
|
||||
}
|
||||
|
||||
bits := strings.Split(varname,".")
|
||||
if varname[0] == '$' {
|
||||
var res VarItemReflect
|
||||
if varname[1] == '.' {
|
||||
res = c.localVars[template_name]["."]
|
||||
} else {
|
||||
res = c.localVars[template_name][strings.TrimPrefix(bits[0],"$")]
|
||||
}
|
||||
out += res.Destination
|
||||
cur = res.Value
|
||||
|
||||
if cur.Kind() == reflect.Interface {
|
||||
cur = cur.Elem()
|
||||
}
|
||||
} else {
|
||||
if cur.Kind() == reflect.Interface {
|
||||
cur = cur.Elem()
|
||||
out += varholder + ".(" + cur.Type().Name() + ")"
|
||||
} else {
|
||||
out += varholder
|
||||
}
|
||||
}
|
||||
bits[0] = strings.TrimPrefix(bits[0],"$")
|
||||
|
||||
if debug {
|
||||
fmt.Println("Cur Kind: ")
|
||||
fmt.Println(cur.Kind())
|
||||
fmt.Println("Cur Type: ")
|
||||
fmt.Println(cur.Type().Name())
|
||||
}
|
||||
|
||||
for _, bit := range bits {
|
||||
if debug {
|
||||
fmt.Println("Variable Field!")
|
||||
fmt.Println(bit)
|
||||
}
|
||||
|
||||
if bit == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
cur = cur.FieldByName(bit)
|
||||
if cur.Kind() == reflect.Interface {
|
||||
cur = cur.Elem()
|
||||
out += "." + bit + ".(" + cur.Type().Name() + ")"
|
||||
} else {
|
||||
out += "." + bit
|
||||
}
|
||||
|
||||
if debug {
|
||||
fmt.Println("Data Kind: ")
|
||||
fmt.Println(cur.Kind())
|
||||
fmt.Println("Data Type: ")
|
||||
fmt.Println(cur.Type().Name())
|
||||
}
|
||||
}
|
||||
|
||||
for _, varItem := range c.varList {
|
||||
if strings.HasPrefix(out, varItem.Destination) {
|
||||
out = strings.Replace(out, varItem.Destination, varItem.Name, 1)
|
||||
}
|
||||
}
|
||||
return out, cur
|
||||
}
|
||||
|
||||
func (c *CTemplateSet2) compile_boolsub(varname string, varholder string, template_name string, val reflect.Value) string {
|
||||
out, val := c.compile_if_varsub(varname, varholder, template_name, val)
|
||||
switch val.Kind() {
|
||||
case reflect.Int:
|
||||
out += " > 0"
|
||||
case reflect.Bool:
|
||||
// Do nothing
|
||||
case reflect.String:
|
||||
out += " != \"\""
|
||||
case reflect.Int64:
|
||||
out += " > 0"
|
||||
default:
|
||||
panic("I don't know what this variable's type is o.o\n")
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (c *CTemplateSet2) compile_varsub(varname string, val reflect.Value) string {
|
||||
for _, varItem := range c.varList {
|
||||
if strings.HasPrefix(varname, varItem.Destination) {
|
||||
varname = strings.Replace(varname, varItem.Destination, varItem.Name, 1)
|
||||
}
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Interface {
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
switch val.Kind() {
|
||||
case reflect.Int:
|
||||
return "tmpl += strconv.Itoa(" + varname + ")\n"
|
||||
case reflect.Bool:
|
||||
return "if " + varname + " {\ntmpl += \"true\"} else {\ntmpl += \"false\"\n}\n"
|
||||
case reflect.String:
|
||||
if val.Type().Name() != "string" && !strings.HasPrefix(varname,"string(") {
|
||||
return "tmpl += string(" + varname + ")\n"
|
||||
} else {
|
||||
return "tmpl += " + varname + "\n"
|
||||
}
|
||||
case reflect.Int64:
|
||||
return "tmpl += strconv.FormatInt(" + varname + ", 10)"
|
||||
default:
|
||||
fmt.Println("Unknown Kind: ")
|
||||
fmt.Println(val.Kind())
|
||||
fmt.Println("Unknown Type: ")
|
||||
fmt.Println(val.Type().Name())
|
||||
panic("// I don't know what this variable's type is o.o\n")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CTemplateSet2) compile_subtemplate(pvarholder string, pholdreflect reflect.Value, node *parse.TemplateNode) (out string) {
|
||||
if debug {
|
||||
fmt.Println("Template Node: " + node.Name)
|
||||
}
|
||||
|
||||
fname := strings.TrimSuffix(node.Name, filepath.Ext(node.Name))
|
||||
varholder := "tmpl_" + fname + "_vars"
|
||||
var holdreflect reflect.Value
|
||||
if node.Pipe != nil {
|
||||
for _, cmd := range node.Pipe.Cmds {
|
||||
firstWord := cmd.Args[0]
|
||||
switch firstWord.(type) {
|
||||
case *parse.DotNode:
|
||||
varholder = pvarholder
|
||||
holdreflect = pholdreflect
|
||||
break
|
||||
case *parse.NilNode:
|
||||
panic("Nil is not a command x.x")
|
||||
default:
|
||||
out = "var " + varholder + " := false\n"
|
||||
out += c.compile_command(cmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res, err := ioutil.ReadFile(c.dir + node.Name)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
content := string(res)
|
||||
|
||||
tree := parse.New(node.Name, c.funcMap)
|
||||
var treeSet map[string]*parse.Tree = make(map[string]*parse.Tree)
|
||||
tree, err = tree.Parse(content,"{{","}}", treeSet, c.funcMap)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
c.tlist[fname] = tree
|
||||
subtree := c.tlist[fname]
|
||||
if debug {
|
||||
fmt.Println(subtree.Root)
|
||||
}
|
||||
|
||||
c.localVars[fname] = make(map[string]VarItemReflect)
|
||||
c.localVars[fname]["."] = VarItemReflect{".",varholder,holdreflect}
|
||||
|
||||
for _, node := range subtree.Root.Nodes {
|
||||
if debug {
|
||||
fmt.Println("Node: " + node.String())
|
||||
}
|
||||
out += c.compile_switch(varholder, holdreflect, fname, node)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (c *CTemplateSet2) compile_command(*parse.CommandNode) (out string) {
|
||||
return ""
|
||||
}
|
46
topic.go
|
@ -80,9 +80,11 @@ type TopicsRow struct
|
|||
}
|
||||
|
||||
type TopicStore interface {
|
||||
Load(id int) error
|
||||
Get(id int) (*Topic, error)
|
||||
GetUnsafe(id int) (*Topic, error)
|
||||
CascadeGet(id int) (*Topic, error)
|
||||
Set(item *Topic) error
|
||||
Add(item *Topic) error
|
||||
AddUnsafe(item *Topic) error
|
||||
Remove(id int) error
|
||||
|
@ -137,6 +139,31 @@ func (sts *StaticTopicStore) CascadeGet(id int) (*Topic, error) {
|
|||
return topic, err
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) Load(id int) error {
|
||||
topic := &Topic{ID:id}
|
||||
err := get_topic_stmt.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount)
|
||||
if err == nil {
|
||||
sts.Set(topic)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) Set(item *Topic) error {
|
||||
sts.mu.Lock()
|
||||
item, ok := sts.items[item.ID]
|
||||
if ok {
|
||||
sts.items[item.ID] = item
|
||||
} else if sts.length >= sts.capacity {
|
||||
sts.mu.Unlock()
|
||||
return ErrStoreCapacityOverflow
|
||||
} else {
|
||||
sts.items[item.ID] = item
|
||||
}
|
||||
sts.mu.Unlock()
|
||||
sts.length++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticTopicStore) Add(item *Topic) error {
|
||||
if sts.length >= sts.capacity {
|
||||
return ErrStoreCapacityOverflow
|
||||
|
@ -218,7 +245,16 @@ func (sus *SqlTopicStore) CascadeGet(id int) (*Topic, error) {
|
|||
return &topic, err
|
||||
}
|
||||
|
||||
func (sus *SqlTopicStore) Load(id int) error {
|
||||
topic := Topic{ID:id}
|
||||
err := get_topic_stmt.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount)
|
||||
return err
|
||||
}
|
||||
|
||||
// Placeholder methods, the actual queries are done elsewhere
|
||||
func (sus *SqlTopicStore) Set(item *Topic) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlTopicStore) Add(item *Topic) error {
|
||||
return nil
|
||||
}
|
||||
|
@ -252,6 +288,7 @@ func get_topicuser(tid int) (TopicUser,error) {
|
|||
if err != nil {
|
||||
return TopicUser{ID:tid}, err
|
||||
}
|
||||
init_user_perms(user)
|
||||
|
||||
// We might be better off just passing seperate topic and user structs to the caller?
|
||||
return copy_topic_to_topicuser(topic, user), nil
|
||||
|
@ -264,13 +301,8 @@ func get_topicuser(tid int) (TopicUser,error) {
|
|||
if err != nil {
|
||||
return TopicUser{ID:tid}, err
|
||||
}
|
||||
init_user_perms(user)
|
||||
tu := copy_topic_to_topicuser(topic, user)
|
||||
//fmt.Printf("%+v\n", topic)
|
||||
//fmt.Println("")
|
||||
//fmt.Printf("%+v\n", user)
|
||||
//fmt.Println("")
|
||||
//fmt.Printf("%+v\n", tu)
|
||||
//fmt.Println("")
|
||||
return tu, nil
|
||||
}
|
||||
}
|
||||
|
@ -280,7 +312,9 @@ func get_topicuser(tid int) (TopicUser,error) {
|
|||
|
||||
the_topic := Topic{ID:tu.ID, Title:tu.Title, Content:tu.Content, CreatedBy:tu.CreatedBy, Is_Closed:tu.Is_Closed, Sticky:tu.Sticky, CreatedAt:tu.CreatedAt, LastReplyAt:tu.LastReplyAt, ParentID:tu.ParentID, IpAddress:tu.IpAddress, PostCount:tu.PostCount, LikeCount:tu.LikeCount}
|
||||
//fmt.Printf("%+v\n", the_topic)
|
||||
tu.Tag = groups[tu.Group].Tag
|
||||
topics.Add(&the_topic)
|
||||
//err = errors.Error("Loaded data via query")
|
||||
return tu, err
|
||||
}
|
||||
|
||||
|
|
139
user.go
|
@ -9,6 +9,8 @@ import "golang.org/x/crypto/bcrypt"
|
|||
import "database/sql"
|
||||
import _ "github.com/go-sql-driver/mysql"
|
||||
|
||||
var guest_user User = User{ID:0,Group:6,Perms:GuestPerms}
|
||||
|
||||
type User struct
|
||||
{
|
||||
ID int
|
||||
|
@ -44,9 +46,11 @@ type Email struct
|
|||
}
|
||||
|
||||
type UserStore interface {
|
||||
Load(id int) error
|
||||
Get(id int) (*User, error)
|
||||
GetUnsafe(id int) (*User, error)
|
||||
CascadeGet(id int) (*User, error)
|
||||
Set(item *User) error
|
||||
Add(item *User) error
|
||||
AddUnsafe(item *User) error
|
||||
Remove(id int) error
|
||||
|
@ -94,12 +98,58 @@ func (sts *StaticUserStore) CascadeGet(id int) (*User, error) {
|
|||
|
||||
user = &User{ID:id}
|
||||
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
|
||||
|
||||
if user.Avatar != "" {
|
||||
if user.Avatar[0] == '.' {
|
||||
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
|
||||
}
|
||||
} else {
|
||||
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
|
||||
}
|
||||
user.Tag = groups[user.Group].Tag
|
||||
init_user_perms(user)
|
||||
if err == nil {
|
||||
sts.Add(user)
|
||||
}
|
||||
return user, err
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) Load(id int) error {
|
||||
user := &User{ID:id}
|
||||
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if user.Avatar != "" {
|
||||
if user.Avatar[0] == '.' {
|
||||
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
|
||||
}
|
||||
} else {
|
||||
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
|
||||
}
|
||||
user.Tag = groups[user.Group].Tag
|
||||
init_user_perms(user)
|
||||
sts.Set(user)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) Set(item *User) error {
|
||||
sts.mu.Lock()
|
||||
item, ok := sts.items[item.ID]
|
||||
if ok {
|
||||
sts.items[item.ID] = item
|
||||
} else if sts.length >= sts.capacity {
|
||||
sts.mu.Unlock()
|
||||
return ErrStoreCapacityOverflow
|
||||
} else {
|
||||
sts.items[item.ID] = item
|
||||
}
|
||||
sts.mu.Unlock()
|
||||
sts.length++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sts *StaticUserStore) Add(item *User) error {
|
||||
if sts.length >= sts.capacity {
|
||||
return ErrStoreCapacityOverflow
|
||||
|
@ -161,22 +211,62 @@ func NewSqlUserStore() *SqlUserStore {
|
|||
func (sus *SqlUserStore) Get(id int) (*User, error) {
|
||||
user := User{ID:id}
|
||||
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
|
||||
|
||||
if user.Avatar != "" {
|
||||
if user.Avatar[0] == '.' {
|
||||
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
|
||||
}
|
||||
} else {
|
||||
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
|
||||
}
|
||||
user.Tag = groups[user.Group].Tag
|
||||
init_user_perms(&user)
|
||||
return &user, err
|
||||
}
|
||||
|
||||
func (sus *SqlUserStore) GetUnsafe(id int) (*User, error) {
|
||||
user := User{ID:id}
|
||||
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
|
||||
|
||||
if user.Avatar != "" {
|
||||
if user.Avatar[0] == '.' {
|
||||
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
|
||||
}
|
||||
} else {
|
||||
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
|
||||
}
|
||||
user.Tag = groups[user.Group].Tag
|
||||
init_user_perms(&user)
|
||||
return &user, err
|
||||
}
|
||||
|
||||
func (sus *SqlUserStore) CascadeGet(id int) (*User, error) {
|
||||
user := User{ID:id}
|
||||
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
|
||||
|
||||
if user.Avatar != "" {
|
||||
if user.Avatar[0] == '.' {
|
||||
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
|
||||
}
|
||||
} else {
|
||||
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
|
||||
}
|
||||
user.Tag = groups[user.Group].Tag
|
||||
init_user_perms(&user)
|
||||
return &user, err
|
||||
}
|
||||
|
||||
func (sus *SqlUserStore) Load(id int) error {
|
||||
user := &User{ID:id}
|
||||
// Simplify this into a quick check whether the user exists
|
||||
err := get_full_user_stmt.QueryRow(id).Scan(&user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
|
||||
return err
|
||||
}
|
||||
|
||||
// Placeholder methods, the actual queries are done elsewhere
|
||||
func (sus *SqlUserStore) Set(item *User) error {
|
||||
return nil
|
||||
}
|
||||
func (sus *SqlUserStore) Add(item *User) error {
|
||||
return nil
|
||||
}
|
||||
|
@ -258,6 +348,8 @@ func ForumSessionCheck(w http.ResponseWriter, r *http.Request, fid int) (user Us
|
|||
}
|
||||
user, success = SimpleSessionCheck(w,r)
|
||||
fperms := groups[user.Group].Forums[fid]
|
||||
//fmt.Printf("%+v\n", user.Perms)
|
||||
//fmt.Printf("%+v\n", fperms)
|
||||
if fperms.Overrides && !user.Is_Super_Admin {
|
||||
user.Perms.ViewTopic = fperms.ViewTopic
|
||||
user.Perms.LikeItem = fperms.LikeItem
|
||||
|
@ -288,45 +380,28 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (User,bool) {
|
|||
// Are there any session cookies..?
|
||||
cookie, err := r.Cookie("uid")
|
||||
if err != nil {
|
||||
return User{ID:0,Group:6,Perms:GuestPerms}, true
|
||||
return guest_user, true
|
||||
}
|
||||
uid, err := strconv.Atoi(cookie.Value)
|
||||
if err != nil {
|
||||
return User{ID:0,Group:6,Perms:GuestPerms}, true
|
||||
return guest_user, true
|
||||
}
|
||||
cookie, err = r.Cookie("session")
|
||||
if err != nil {
|
||||
return User{ID:0,Group:6,Perms:GuestPerms}, true
|
||||
return guest_user, true
|
||||
}
|
||||
|
||||
// Is this session valid..?
|
||||
user, err := users.CascadeGet(uid)
|
||||
if err == sql.ErrNoRows {
|
||||
user.ID = 0
|
||||
user.Session = ""
|
||||
user.Group = 6
|
||||
user.Perms = GuestPerms
|
||||
return *user, true
|
||||
return guest_user, true
|
||||
} else if err != nil {
|
||||
InternalError(err,w,r)
|
||||
return *user, false
|
||||
return guest_user, false
|
||||
}
|
||||
|
||||
if user.Session == "" || cookie.Value != user.Session {
|
||||
user.ID = 0
|
||||
user.Session = ""
|
||||
user.Group = 6
|
||||
user.Perms = GuestPerms
|
||||
return *user, true
|
||||
}
|
||||
|
||||
user.Is_Admin = user.Is_Super_Admin || groups[user.Group].Is_Admin
|
||||
user.Is_Super_Mod = groups[user.Group].Is_Mod || user.Is_Admin
|
||||
user.Is_Mod = user.Is_Super_Mod
|
||||
user.Is_Banned = groups[user.Group].Is_Banned
|
||||
user.Loggedin = !user.Is_Banned || user.Is_Super_Mod
|
||||
if user.Is_Banned && user.Is_Super_Mod {
|
||||
user.Is_Banned = false
|
||||
return guest_user, true
|
||||
}
|
||||
|
||||
if user.Is_Super_Admin {
|
||||
|
@ -335,14 +410,6 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (User,bool) {
|
|||
user.Perms = groups[user.Group].Perms
|
||||
}
|
||||
|
||||
if user.Avatar != "" {
|
||||
if user.Avatar[0] == '.' {
|
||||
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
|
||||
}
|
||||
} else {
|
||||
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
|
||||
}
|
||||
|
||||
host, _, err := net.SplitHostPort(r.RemoteAddr)
|
||||
if err != nil {
|
||||
PreError("Bad IP",w,r)
|
||||
|
@ -448,3 +515,13 @@ func decrease_post_user_stats(wcount int, uid int, topic bool, user User) error
|
|||
_, err = update_user_level_stmt.Exec(getLevel(user.Score - base_score - mod), uid)
|
||||
return err
|
||||
}
|
||||
|
||||
func init_user_perms(user *User) {
|
||||
user.Is_Admin = user.Is_Super_Admin || groups[user.Group].Is_Admin
|
||||
user.Is_Super_Mod = user.Is_Admin || groups[user.Group].Is_Mod
|
||||
user.Is_Mod = user.Is_Super_Mod
|
||||
user.Is_Banned = groups[user.Group].Is_Banned
|
||||
if user.Is_Banned && user.Is_Super_Mod {
|
||||
user.Is_Banned = false
|
||||
}
|
||||
}
|