diff --git a/.gitignore b/.gitignore
index 008366cd..19cd88ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
tmp/*
tmp2/*
+cert_test/*
+
uploads/avatar_*
uploads/socialgroup_*
bin/*
diff --git a/extend.go b/extend.go
index f3e9ae38..7acb8237 100644
--- a/extend.go
+++ b/extend.go
@@ -18,7 +18,8 @@ var vhooks map[string]func(...interface{})interface{} = map[string]func(...inter
"forum_check_pre_perms": nil,
"intercept_build_widgets": nil,
"forum_trow_assign": nil,
- "topics_trow_assign": nil,
+ "topics_topic_row_assign": nil,
+ //"topics_user_row_assign": nil,
"create_group_preappend": nil, // What is this? Investigate!
"topic_create_pre_loop": nil,
}
diff --git a/gen_mysql.go b/gen_mysql.go
index 5e5f1131..f15a9931 100644
--- a/gen_mysql.go
+++ b/gen_mysql.go
@@ -39,8 +39,8 @@ var get_topic_basic_stmt *sql.Stmt
var get_activity_entry_stmt *sql.Stmt
var forum_entry_exists_stmt *sql.Stmt
var group_entry_exists_stmt *sql.Stmt
-var get_topic_replies_offset_stmt *sql.Stmt
var get_forum_topics_offset_stmt *sql.Stmt
+var get_topic_replies_offset_stmt *sql.Stmt
var get_topic_list_stmt *sql.Stmt
var get_topic_user_stmt *sql.Stmt
var get_topic_by_reply_stmt *sql.Stmt
@@ -310,14 +310,14 @@ func _gen_mysql() (err error) {
return err
}
- log.Print("Preparing get_topic_replies_offset statement.")
- get_topic_replies_offset_stmt, err = db.Prepare("SELECT `replies`.`rid`,`replies`.`content`,`replies`.`createdBy`,`replies`.`createdAt`,`replies`.`lastEdit`,`replies`.`lastEditBy`,`users`.`avatar`,`users`.`name`,`users`.`group`,`users`.`url_prefix`,`users`.`url_name`,`users`.`level`,`replies`.`ipaddress`,`replies`.`likeCount`,`replies`.`actionType` FROM `replies` LEFT JOIN `users` ON `replies`.`createdBy` = `users`.`uid` WHERE `tid` = ? LIMIT ?,?")
+ log.Print("Preparing get_forum_topics_offset statement.")
+ get_forum_topics_offset_stmt, err = db.Prepare("SELECT `tid`,`title`,`content`,`createdBy`,`is_closed`,`sticky`,`createdAt`,`lastReplyAt`,`lastReplyBy`,`parentID`,`postCount`,`likeCount` FROM `topics` WHERE `parentID` = ? ORDER BY sticky DESC,lastReplyAt DESC,createdBy DESC LIMIT ?,?")
if err != nil {
return err
}
- log.Print("Preparing get_forum_topics_offset statement.")
- get_forum_topics_offset_stmt, err = db.Prepare("SELECT `topics`.`tid`,`topics`.`title`,`topics`.`content`,`topics`.`createdBy`,`topics`.`is_closed`,`topics`.`sticky`,`topics`.`createdAt`,`topics`.`lastReplyAt`,`topics`.`parentID`,`topics`.`postCount`,`topics`.`likeCount`,`users`.`name`,`users`.`avatar` FROM `topics` LEFT JOIN `users` ON `topics`.`createdBy` = `users`.`uid` WHERE `topics`.`parentID` = ? ORDER BY topics.sticky DESC,topics.lastReplyAt DESC,topics.createdBy DESC LIMIT ?,?")
+ log.Print("Preparing get_topic_replies_offset statement.")
+ get_topic_replies_offset_stmt, err = db.Prepare("SELECT `replies`.`rid`,`replies`.`content`,`replies`.`createdBy`,`replies`.`createdAt`,`replies`.`lastEdit`,`replies`.`lastEditBy`,`users`.`avatar`,`users`.`name`,`users`.`group`,`users`.`url_prefix`,`users`.`url_name`,`users`.`level`,`replies`.`ipaddress`,`replies`.`likeCount`,`replies`.`actionType` FROM `replies` LEFT JOIN `users` ON `replies`.`createdBy` = `users`.`uid` WHERE `tid` = ? LIMIT ?,?")
if err != nil {
return err
}
@@ -365,7 +365,7 @@ func _gen_mysql() (err error) {
}
log.Print("Preparing create_topic statement.")
- create_topic_stmt, err = db.Prepare("INSERT INTO `topics`(`parentID`,`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`ipaddress`,`words`,`createdBy`) VALUES (?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?)")
+ create_topic_stmt, err = db.Prepare("INSERT INTO `topics`(`parentID`,`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`lastReplyBy`,`ipaddress`,`words`,`createdBy`) VALUES (?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,?)")
if err != nil {
return err
}
@@ -473,7 +473,7 @@ func _gen_mysql() (err error) {
}
log.Print("Preparing add_replies_to_topic statement.")
- add_replies_to_topic_stmt, err = db.Prepare("UPDATE `topics` SET `postCount` = `postCount` + ?,`lastReplyAt` = UTC_TIMESTAMP() WHERE `tid` = ?")
+ add_replies_to_topic_stmt, err = db.Prepare("UPDATE `topics` SET `postCount` = `postCount` + ?,`lastReplyBy` = ?,`lastReplyAt` = UTC_TIMESTAMP() WHERE `tid` = ?")
if err != nil {
return err
}
diff --git a/gen_pgsql.go b/gen_pgsql.go
index 0f466ca6..64e9e07e 100644
--- a/gen_pgsql.go
+++ b/gen_pgsql.go
@@ -50,7 +50,7 @@ func _gen_pgsql() (err error) {
}
log.Print("Preparing add_replies_to_topic statement.")
- add_replies_to_topic_stmt, err = db.Prepare("UPDATE `topics` SET `postCount` = `postCount` + ?,`lastReplyAt` = UTC_TIMESTAMP() WHERE `tid` = ?")
+ add_replies_to_topic_stmt, err = db.Prepare("UPDATE `topics` SET `postCount` = `postCount` + ?,`lastReplyBy` = ?,`lastReplyAt` = LOCALTIMESTAMP() WHERE `tid` = ?")
if err != nil {
return err
}
@@ -74,7 +74,7 @@ func _gen_pgsql() (err error) {
}
log.Print("Preparing update_forum_cache statement.")
- update_forum_cache_stmt, err = db.Prepare("UPDATE `forums` SET `lastTopic` = ?,`lastTopicID` = ?,`lastReplyer` = ?,`lastReplyerID` = ?,`lastTopicTime` = UTC_TIMESTAMP() WHERE `fid` = ?")
+ update_forum_cache_stmt, err = db.Prepare("UPDATE `forums` SET `lastTopic` = ?,`lastTopicID` = ?,`lastReplyer` = ?,`lastReplyerID` = ?,`lastTopicTime` = LOCALTIMESTAMP() WHERE `fid` = ?")
if err != nil {
return err
}
diff --git a/gen_router.go b/gen_router.go
index 3389cde1..d0f85e94 100644
--- a/gen_router.go
+++ b/gen_router.go
@@ -62,9 +62,13 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
extra_data = req.URL.Path[strings.LastIndexByte(req.URL.Path,'/') + 1:]
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
}
- //fmt.Println("prefix:",prefix)
- //fmt.Println("req.URL.Path:",req.URL.Path)
- //fmt.Println("extra_data:",extra_data)
+
+ if dev.SuperDebug {
+ fmt.Println("before route_static")
+ fmt.Println("prefix:",prefix)
+ fmt.Println("req.URL.Path:",req.URL.Path)
+ fmt.Println("extra_data:",extra_data)
+ }
if prefix == "/static" {
req.URL.Path += extra_data
@@ -207,6 +211,18 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
router.UploadHandler(w,req)
return
case "":
+ // Stop the favicons, robots.txt file, etc. resolving to the topics list
+ // TO-DO: Add support for favicons and robots.txt files
+ switch(extra_data) {
+ case "robots.txt":
+ route_robots_txt(w,req)
+ return
+ }
+
+ if extra_data != "" {
+ NotFound(w,req)
+ return
+ }
config.DefaultRoute(w,req,user)
return
//default: NotFound(w,req)
diff --git a/general_test.go b/general_test.go
index 9a0c646a..0f8dcd38 100644
--- a/general_test.go
+++ b/general_test.go
@@ -57,16 +57,16 @@ func gloinit() {
}
if config.CacheTopicUser == CACHE_STATIC {
- users = NewMemoryUserStore(user_cache_capacity)
- topics = NewMemoryTopicStore(topic_cache_capacity)
+ users = NewMemoryUserStore(config.UserCacheCapacity)
+ topics = NewMemoryTopicStore(config.TopicCacheCapacity)
} else {
users = NewSqlUserStore()
topics = NewSqlTopicStore()
}
init_static_files()
- external_sites["YT"] = "https://www.youtube.com/"
//log.SetOutput(os.Stdout)
+ auth = NewDefaultAuth()
router = NewGenRouter(http.FileServer(http.Dir("./uploads")))
gloinited = true
@@ -82,19 +82,19 @@ func BenchmarkTopicTemplateSerial(b *testing.B) {
user := User{0,"bob","Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,make(map[string]bool),"",false,"","","","","",0,0,"127.0.0.1"}
admin := User{1,"admin-alice","Admin Alice","admin@localhost",0,true,true,true,true,true,false,AllPerms,make(map[string]bool),"",false,"","","","","",-1,58,"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"}
+ topic := TopicUser{Title: "Lol",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",ClassName: "",Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}
var replyList []Reply
- replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry","Jerry",config.DefaultGroup,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
- replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry2","Jerry2",config.DefaultGroup,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
- replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry3","Jerry3",config.DefaultGroup,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
- replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry4","Jerry4",config.DefaultGroup,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
- replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry5","Jerry5",config.DefaultGroup,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
- replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry6","Jerry6",config.DefaultGroup,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
- replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry7","Jerry7",config.DefaultGroup,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
- replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry8","Jerry8",config.DefaultGroup,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
- replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry9","Jerry9",config.DefaultGroup,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
- replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry10","Jerry10",config.DefaultGroup,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
+ replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry","Jerry",config.DefaultGroup,"",0,0,"","",0,"","","","",0,"127.0.0.1",false,1,"",""})
+ replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry2","Jerry2",config.DefaultGroup,"",0,0,"","",0,"","","","",0,"127.0.0.1",false,1,"",""})
+ replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry3","Jerry3",config.DefaultGroup,"",0,0,"","",0,"","","","",0,"127.0.0.1",false,1,"",""})
+ replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry4","Jerry4",config.DefaultGroup,"",0,0,"","",0,"","","","",0,"127.0.0.1",false,1,"",""})
+ replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry5","Jerry5",config.DefaultGroup,"",0,0,"","",0,"","","","",0,"127.0.0.1",false,1,"",""})
+ replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry6","Jerry6",config.DefaultGroup,"",0,0,"","",0,"","","","",0,"127.0.0.1",false,1,"",""})
+ replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry7","Jerry7",config.DefaultGroup,"",0,0,"","",0,"","","","",0,"127.0.0.1",false,1,"",""})
+ replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry8","Jerry8",config.DefaultGroup,"",0,0,"","",0,"","","","",0,"127.0.0.1",false,1,"",""})
+ replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry9","Jerry9",config.DefaultGroup,"",0,0,"","",0,"","","","",0,"127.0.0.1",false,1,"",""})
+ replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"jerry10","Jerry10",config.DefaultGroup,"",0,0,"","",0,"","","","",0,"127.0.0.1",false,1,"",""})
headerVars := HeaderVars{
NoticeList:[]string{"test"},
@@ -103,6 +103,7 @@ func BenchmarkTopicTemplateSerial(b *testing.B) {
Widgets:PageWidgets{
LeftSidebar: template.HTML("lalala"),
},
+ Site:site,
}
tpage := TopicPage{"Topic Blah",user,headerVars,replyList,topic,1,1,extData}
@@ -167,20 +168,20 @@ func BenchmarkTopicTemplateSerial(b *testing.B) {
func BenchmarkTopicsTemplateSerial(b *testing.B) {
b.ReportAllocs()
- user := User{0,"bob","Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,make(map[string]bool),"",false,"","","","","",0,0,"127.0.0.1"}
- admin := User{1,"admin-alice","Admin Alice","admin@localhost",0,true,true,true,true,true,false,AllPerms,make(map[string]bool),"",false,"","","","","",-1,58,"127.0.0.1"}
+ user := User{0,build_profile_url("bob",0),"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,make(map[string]bool),"",false,"","","","","",0,0,"127.0.0.1"}
+ admin := User{1,build_profile_url("admin-alice",1),"Admin Alice","admin@localhost",0,true,true,true,true,true,false,AllPerms,make(map[string]bool),"",false,"","","","","Admin",58,580,"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,UserLink:build_profile_url("admin-alice",1),CreatedByName:"Admin Alice",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,UserLink:build_profile_url("admin-alice",1),CreatedByName:"Admin Alice",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,UserLink:build_profile_url("admin-alice",1),CreatedByName:"Admin Alice",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,UserLink:build_profile_url("admin-alice",1),CreatedByName:"Admin Alice",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,UserLink:build_profile_url("admin-alice",1),CreatedByName:"Admin Alice",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,UserLink:build_profile_url("admin-alice",1),CreatedByName:"Admin Alice",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,UserLink:build_profile_url("admin-alice",1),CreatedByName:"Admin Alice",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,UserLink:build_profile_url("admin-alice",1),CreatedByName:"Admin Alice",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,UserLink:build_profile_url("admin-alice",1),CreatedByName:"Admin Alice",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,UserLink:build_profile_url("admin-alice",1),CreatedByName:"Admin Alice",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,Creator:&admin,LastUser:&user,ClassName:"", 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,Creator:&admin,LastUser:&user,ClassName:"", 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,Creator:&admin,LastUser:&user,ClassName:"", 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,Creator:&admin,LastUser:&user,ClassName:"", 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,Creator:&admin,LastUser:&user,ClassName:"", 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,Creator:&admin,LastUser:&user,ClassName:"", 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,Creator:&admin,LastUser:&user,ClassName:"", 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,Creator:&admin,LastUser:&user,ClassName:"", 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,Creator:&admin,LastUser:&user,ClassName:"", 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,Creator:&admin,LastUser:&user,ClassName:"", IpAddress: "127.0.0.1"})
headerVars := HeaderVars{
NoticeList:[]string{"test"},
@@ -189,6 +190,7 @@ func BenchmarkTopicsTemplateSerial(b *testing.B) {
Widgets:PageWidgets{
LeftSidebar: template.HTML("lalala"),
},
+ Site:site,
}
w := ioutil.Discard
@@ -242,8 +244,7 @@ func BenchmarkStaticRouteParallel(b *testing.B) {
})
}
-// TO-DO: Make these routes compatible with the changes to the router
-/*
+// TO-DO: Swap out LocalError for a panic for this?
func BenchmarkTopicAdminRouteParallel(b *testing.B) {
b.ReportAllocs()
if !gloinited {
@@ -253,10 +254,10 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
admin, err := users.CascadeGet(1)
if err != nil {
- panic(err)
+ b.Fatal(err)
}
if !admin.Is_Admin {
- panic("UID1 is not an admin")
+ b.Fatal("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}
@@ -266,11 +267,16 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) {
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)
+
+ // Deal with the session stuff, etc.
+ user, ok := PreRoute(topic_w,topic_req_admin)
+ if !ok {
+ b.Fatal("Mysterious error!")
+ }
for pb.Next() {
topic_w.Body.Reset()
- topic_handler.ServeHTTP(topic_w,topic_req_admin)
+ route_topic_id(topic_w,topic_req_admin,user)
}
})
}
@@ -284,14 +290,15 @@ func BenchmarkTopicGuestRouteParallel(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
topic_w := httptest.NewRecorder()
topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil))
- topic_handler := http.HandlerFunc(route_topic_id)
for pb.Next() {
topic_w.Body.Reset()
- topic_handler.ServeHTTP(topic_w,topic_req)
+ route_topic_id(topic_w,topic_req,guest_user)
}
})
}
+// TO-DO: Make these routes compatible with the changes to the router
+/*
func BenchmarkForumsAdminRouteParallel(b *testing.B) {
b.ReportAllocs()
if !gloinited {
@@ -619,7 +626,7 @@ func BenchmarkQueryTopicParallel(b *testing.B) {
}
b.RunParallel(func(pb *testing.PB) {
- tu := TopicUser{Css: no_css_tmpl}
+ var tu TopicUser
for pb.Next() {
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 == ErrNoRows {
@@ -640,7 +647,7 @@ func BenchmarkQueryPreparedTopicParallel(b *testing.B) {
}
b.RunParallel(func(pb *testing.PB) {
- tu := TopicUser{Css: no_css_tmpl}
+ var tu TopicUser
for pb.Next() {
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 == ErrNoRows {
@@ -656,7 +663,7 @@ func BenchmarkQueryPreparedTopicParallel(b *testing.B) {
func BenchmarkQueriesSerial(b *testing.B) {
b.ReportAllocs()
- tu := TopicUser{Css: no_css_tmpl}
+ var tu TopicUser
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, 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)
@@ -686,7 +693,7 @@ func BenchmarkQueriesSerial(b *testing.B) {
}
})
- replyItem := Reply{Css: no_css_tmpl}
+ var replyItem Reply
var is_super_admin bool
var group int
b.Run("topic_replies_scan", func(b *testing.B) {
diff --git a/install/install.go b/install/install.go
index 363fb9a2..a0ee4972 100644
--- a/install/install.go
+++ b/install/install.go
@@ -160,8 +160,8 @@ config.MaxRequestSize = 5 * megabyte
// Caching
config.CacheTopicUser = CACHE_STATIC
-config.UserCacheCapacity = 100 // The max number of users held in memory
-config.TopicCacheCapacity = 100 // The max number of topics held in memory
+config.UserCacheCapacity = 120 // The max number of users held in memory
+config.TopicCacheCapacity = 200 // The max number of topics held in memory
// Email
config.SmtpServer = ""
diff --git a/main.go b/main.go
index 57254cb9..bca4ae57 100644
--- a/main.go
+++ b/main.go
@@ -32,7 +32,9 @@ var startTime time.Time
var templates = template.New("")
//var no_css_tmpl template.CSS = template.CSS("")
var settings map[string]interface{} = make(map[string]interface{})
-var external_sites map[string]string = make(map[string]string)
+var external_sites map[string]string = map[string]string{
+ "YT":"https://www.youtube.com/",
+}
var groups []Group
var groupCapCount int
var static_files map[string]SFile = make(map[string]SFile)
@@ -48,6 +50,9 @@ var template_create_topic_handle func(CreateTopicPage,io.Writer) = nil
func compile_templates() error {
var c CTemplateSet
user := User{62,build_profile_url("fake-user",62),"Fake User","compiler@localhost",0,false,false,false,false,false,false,GuestPerms,make(map[string]bool),"",false,"","","","","",0,0,"0.0.0.0.0"}
+ // TO-DO: Do a more accurate level calculation for this?
+ user2 := User{1,build_profile_url("admin-alice",1),"Admin Alice","alice@localhost",1,true,true,true,true,false,false,AllPerms,make(map[string]bool),"",true,"","","","","",58,1000,"127.0.0.1"}
+ user3 := User{2,build_profile_url("admin-fred",62),"Admin Fred","fred@localhost",1,true,true,true,true,false,false,AllPerms,make(map[string]bool),"",true,"","","","","",42,900,"::1"}
headerVars := HeaderVars{
Site:site,
NoticeList:[]string{"test"},
@@ -88,15 +93,15 @@ func compile_templates() error {
forums_page := ForumsPage{"Forum List",user,headerVars,forumList,extData}
forums_tmpl := c.compile_template("forums.html","templates/","ForumsPage",forums_page,varList)
- var topicsList []TopicsRow
- topicsList = append(topicsList,TopicsRow{1,"topic-title","Topic Title","The topic content.",1,false,false,"Date","Date",1,"","127.0.0.1",0,1,"classname","admin-alice","Admin Alice","","",0,"","","","",58,"General","/forum/general.2"})
+ var topicsList []*TopicsRow
+ topicsList = append(topicsList,&TopicsRow{1,"topic-title","Topic Title","The topic content.",1,false,false,"Date","Date",user3.ID,1,"","127.0.0.1",0,1,"classname","",&user2,"",0,&user3,"General","/forum/general.2"})
topics_page := TopicsPage{"Topic List",user,headerVars,topicsList,extData}
topics_tmpl := c.compile_template("topics.html","templates/","TopicsPage",topics_page,varList)
- var topicList []TopicUser
- topicList = append(topicList,TopicUser{1,"topic-title","Topic Title","The topic content.",1,false,false,"Date","Date",1,"","127.0.0.1",0,1,"classname","","admin-fred","Admin Fred",config.DefaultGroup,"",0,"","","","",58,false})
+ //var topicList []TopicUser
+ //topicList = append(topicList,TopicUser{1,"topic-title","Topic Title","The topic content.",1,false,false,"Date","Date",1,"","127.0.0.1",0,1,"classname","","admin-fred","Admin Fred",config.DefaultGroup,"",0,"","","","",58,false})
forum_item := Forum{1,"general","General Forum","Where the general stuff happens",true,"all",0,"",0,"","",0,"",0,""}
- forum_page := ForumPage{"General Forum",user,headerVars,topicList,forum_item,1,1,extData}
+ forum_page := ForumPage{"General Forum",user,headerVars,topicsList,forum_item,1,1,extData}
forum_tmpl := c.compile_template("forum.html","templates/","ForumPage",forum_page,varList)
log.Print("Writing the templates")
@@ -191,7 +196,6 @@ func main(){
}
init_static_files()
- external_sites["YT"] = "https://www.youtube.com/"
log.Print("Initialising the widgets")
err = init_widgets()
@@ -298,6 +302,7 @@ func main(){
// pprof.StopCPUProfile()
//}
+ // TO-DO: Let users run *both* HTTP and HTTPS
log.Print("Initialising the HTTP server")
if !site.EnableSsl {
if site.Port == "" {
diff --git a/misc_test.go b/misc_test.go
index 6abbbf4d..af13ba8a 100644
--- a/misc_test.go
+++ b/misc_test.go
@@ -37,7 +37,42 @@ func TestUserStore(t *testing.T) {
}
if user.ID != 1 {
- t.Error("user.ID doesn't not match the requested UID. Got '" + strconv.Itoa(user.ID) + "' instead.")
+ t.Error("user.ID does not match the requested UID. Got '" + strconv.Itoa(user.ID) + "' instead.")
+ }
+
+ // TO-DO: Lock onto the specific error type. Is this even possible without sacrificing the detailed information in the error message?
+ var userList map[int]*User
+ userList, err = users.BulkCascadeGetMap([]int{-1})
+ if err == nil {
+ t.Error("UID #-1 shouldn't exist")
+ }
+
+ userList, err = users.BulkCascadeGetMap([]int{0})
+ if err == nil {
+ t.Error("UID #0 shouldn't exist")
+ }
+
+ userList, err = users.BulkCascadeGetMap([]int{1})
+ if err == ErrNoRows {
+ t.Error("Couldn't find UID #1")
+ } else if err != nil {
+ t.Fatal(err)
+ }
+
+ if len(userList) == 0 {
+ t.Error("The returned map is empty for UID #0")
+ } else if len(userList) > 1 {
+ t.Error("Too many results were returned for UID #0")
+ }
+
+ user, ok := userList[1]
+ if !ok {
+ t.Error("We couldn't find UID #0 in the returned map")
+ t.Error("userList",userList)
+ }
+
+ if user.ID != 1 {
+ t.Error("user.ID does not match the requested UID. Got '" + strconv.Itoa(user.ID) + "' instead.")
}
}
diff --git a/mysql.sql b/mysql.sql
index 047ff7aa..dcff8cf3 100644
--- a/mysql.sql
+++ b/mysql.sql
@@ -49,7 +49,7 @@ CREATE TABLE `topics`(
`parsed_content` text not null,
`createdAt` datetime not null,
`lastReplyAt` datetime not null,
- /*`lastReplyBy` int not null,*/
+ `lastReplyBy` int not null,
`createdBy` int not null,
`is_closed` tinyint DEFAULT 0 not null,
`sticky` tinyint DEFAULT 0 not null,
@@ -243,8 +243,8 @@ INSERT INTO forums_permissions(`gid`,`fid`,`permissions`) VALUES (3,1,'{}');
INSERT INTO forums_permissions(`gid`,`fid`,`permissions`) VALUES (4,1,'{}');
INSERT INTO forums_permissions(`gid`,`fid`,`permissions`) VALUES (5,1,'{}');
INSERT INTO forums_permissions(`gid`,`fid`,`permissions`) VALUES (6,1,'{}');
-INSERT INTO topics(`title`,`content`,`createdAt`,`lastReplyAt`,`createdBy`,`parentID`)
-VALUES ('Test Topic','A topic automatically generated by the software.',UTC_TIMESTAMP(),UTC_TIMESTAMP(),1,2);
+INSERT INTO topics(`title`,`content`,`createdAt`,`lastReplyAt`,`lastReplyBy`,`createdBy`,`parentID`)
+VALUES ('Test Topic','A topic automatically generated by the software.',UTC_TIMESTAMP(),UTC_TIMESTAMP(),1,1,2);
INSERT INTO replies(`tid`,`content`,`createdAt`,`createdBy`,`lastEdit`,`lastEditBy`)
VALUES (1,'Reply 1',UTC_TIMESTAMP(),1,0,0);
diff --git a/pages.go b/pages.go
index 9d08732f..71cc7772 100644
--- a/pages.go
+++ b/pages.go
@@ -61,7 +61,7 @@ type TopicsPage struct
Title string
CurrentUser User
Header HeaderVars
- ItemList []TopicsRow
+ ItemList []*TopicsRow
ExtData ExtData
}
@@ -70,7 +70,7 @@ type ForumPage struct
Title string
CurrentUser User
Header HeaderVars
- ItemList []TopicUser
+ ItemList []*TopicsRow
Forum Forum
Page int
LastPage int
diff --git a/panel_routes.go b/panel_routes.go
index 66060c09..6233f9f1 100644
--- a/panel_routes.go
+++ b/panel_routes.go
@@ -965,6 +965,7 @@ func route_panel_users(w http.ResponseWriter, r *http.Request, user User){
}
defer rows.Close()
+ // TO-DO: Add a UserStore method for iterating over global users
for rows.Next() {
puser := User{ID: 0,}
err := rows.Scan(&puser.ID, &puser.Name, &puser.Group, &puser.Active, &puser.Is_Super_Admin, &puser.Avatar)
diff --git a/plugin_socialgroups.go b/plugin_socialgroups.go
index dee9f633..774addd3 100644
--- a/plugin_socialgroups.go
+++ b/plugin_socialgroups.go
@@ -55,7 +55,7 @@ type SocialGroupPage struct
Title string
CurrentUser User
Header HeaderVars
- ItemList []TopicUser
+ ItemList []*TopicsRow
Forum Forum
SocialGroup SocialGroup
Page int
diff --git a/plugin_test.go b/plugin_test.go
index aa92896a..c19e5323 100644
--- a/plugin_test.go
+++ b/plugin_test.go
@@ -3,6 +3,7 @@ package main
import "strconv"
import "testing"
+// TO-DO: Replace the soft tabs with hard ones
// go test -v
type ME_Pair struct
@@ -16,6 +17,7 @@ func addMEPair(msgList []ME_Pair, msg string, expects string) []ME_Pair {
}
func TestBBCodeRender(t *testing.T) {
+ //t.Skip()
var res string
var msgList []ME_Pair
msgList = addMEPair(msgList,"hi","hi")
@@ -27,10 +29,12 @@ func TestBBCodeRender(t *testing.T) {
msgList = addMEPair(msgList,"[i]hi[/i]","hi")
msgList = addMEPair(msgList,"[s]hi[/s]","hi")
msgList = addMEPair(msgList,"[c]hi[/c]","[c]hi[/c]")
- msgList = addMEPair(msgList,"[b]hi[/i]","[b]hi[/i]")
- msgList = addMEPair(msgList,"[/b]hi[b]","[/b]hi[b]")
- msgList = addMEPair(msgList,"[/b]hi[/b]","[/b]hi[/b]")
- msgList = addMEPair(msgList,"[b][b]hi[/b]","hi")
+ if !testing.Short() {
+ msgList = addMEPair(msgList,"[b]hi[/i]","[b]hi[/i]")
+ msgList = addMEPair(msgList,"[/b]hi[b]","[/b]hi[b]")
+ msgList = addMEPair(msgList,"[/b]hi[/b]","[/b]hi[/b]")
+ msgList = addMEPair(msgList,"[b][b]hi[/b]","hi")
+ }
msgList = addMEPair(msgList,"[b][b]hi","[b][b]hi")
msgList = addMEPair(msgList,"[b][b][b]hi","[b][b][b]hi")
msgList = addMEPair(msgList,"[/b]hi","[/b]hi")
@@ -185,6 +189,7 @@ func TestBBCodeRender(t *testing.T) {
}
func TestMarkdownRender(t *testing.T) {
+ //t.Skip()
var res string
var msgList []ME_Pair
msgList = addMEPair(msgList,"hi","hi")
diff --git a/public/global.js b/public/global.js
index 2ccba975..524d6851 100644
--- a/public/global.js
+++ b/public/global.js
@@ -95,7 +95,10 @@ $(document).ready(function(){
}
if(window["WebSocket"]) {
- conn = new WebSocket("ws://" + document.location.host + "/ws/");
+ if(window.location.protocol == "https:")
+ conn = new WebSocket("wss://" + document.location.host + "/ws/");
+ else conn = new WebSocket("ws://" + document.location.host + "/ws/");
+
conn.onopen = function() {
conn.send("page " + document.location.pathname + '\r');
}
diff --git a/query_gen/lib/pgsql.go b/query_gen/lib/pgsql.go
index 71c2d6b5..aa7ab457 100644
--- a/query_gen/lib/pgsql.go
+++ b/query_gen/lib/pgsql.go
@@ -1,4 +1,4 @@
-/* WIP Under *Heavy* Construction */
+/* WIP Under Really Heavy Construction */
package qgen
import "strings"
@@ -144,7 +144,13 @@ func (adapter *Pgsql_Adapter) SimpleUpdate(name string, table string, set string
querystr += "`" + item.Column + "` ="
for _, token := range item.Expr {
switch(token.Type) {
- case "function","operator","number","substitute":
+ case "function":
+ // TO-DO: Write a more sophisticated function parser on the utils side.
+ if strings.ToUpper(token.Contents) == "UTC_TIMESTAMP()" {
+ token.Contents = "LOCALTIMESTAMP()"
+ }
+ querystr += " " + token.Contents + ""
+ case "operator","number","substitute":
querystr += " " + token.Contents + ""
case "column":
querystr += " `" + token.Contents + "`"
@@ -166,8 +172,7 @@ func (adapter *Pgsql_Adapter) SimpleUpdate(name string, table string, set string
switch(token.Type) {
case "function":
// TO-DO: Write a more sophisticated function parser on the utils side. What's the situation in regards to case sensitivity?
- // TO-DO: Change things on the MySQL and Gosora side to timestamps
- if token.Contents == "UTC_TIMESTAMP()" {
+ if strings.ToUpper(token.Contents) == "UTC_TIMESTAMP()" {
token.Contents = "LOCALTIMESTAMP()"
}
querystr += " " + token.Contents + ""
diff --git a/query_gen/lib/querygen.go b/query_gen/lib/querygen.go
index 1dac170e..5ea55d23 100644
--- a/query_gen/lib/querygen.go
+++ b/query_gen/lib/querygen.go
@@ -108,12 +108,12 @@ type DB_Adapter interface {
GetName() string
CreateTable(name string, table string, charset string, collation string, columns []DB_Table_Column, keys []DB_Table_Key) (string, error)
SimpleInsert(name string, table string, columns string, fields string) (string, error)
- SimpleReplace(string,string,string,string) (string, error)
- SimpleUpdate(string,string,string,string) (string, error)
- SimpleDelete(string,string,string) (string, error)
- Purge(string,string) (string, error)
- SimpleSelect(string,string,string,string,string,string) (string, error)
- SimpleLeftJoin(string,string,string,string,string,string,string,string) (string, error)
+ SimpleReplace(name string, table string, columns string, fields string) (string, error)
+ SimpleUpdate(name string, table string, set string, where string) (string, error)
+ SimpleDelete(name string, table string, where string) (string, error)
+ Purge(name string, table string) (string, error)
+ SimpleSelect(name string, table string, columns string, where string, orderby string, limit string) (string, error)
+ SimpleLeftJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (string, error)
SimpleInnerJoin(string,string,string,string,string,string,string,string) (string, error)
SimpleInsertSelect(string,DB_Insert,DB_Select) (string,error)
SimpleInsertLeftJoin(string,DB_Insert,DB_Join) (string,error)
diff --git a/query_gen/main.go b/query_gen/main.go
index 6ac7b1f6..c71bdea9 100644
--- a/query_gen/main.go
+++ b/query_gen/main.go
@@ -223,14 +223,14 @@ func write_selects(adapter qgen.DB_Adapter) error {
adapter.SimpleSelect("group_entry_exists","users_groups","gid","name = ''","gid ASC","0,1")
+ adapter.SimpleSelect("get_forum_topics_offset","topics","tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, parentID, postCount, likeCount","parentID = ?","sticky DESC, lastReplyAt DESC, createdBy DESC","?,?")
+
return nil
}
func write_left_joins(adapter qgen.DB_Adapter) error {
adapter.SimpleLeftJoin("get_topic_replies_offset","replies","users","replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress, replies.likeCount, replies.actionType","replies.createdBy = users.uid","tid = ?","","?,?")
- adapter.SimpleLeftJoin("get_forum_topics_offset","topics","users","topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, topics.postCount, topics.likeCount, users.name, users.avatar","topics.createdBy = users.uid","topics.parentID = ?","topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC","?,?")
-
adapter.SimpleLeftJoin("get_topic_list","topics","users","topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar","topics.createdBy = users.uid","","topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC","")
adapter.SimpleLeftJoin("get_topic_user","topics","users","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","topics.createdBy = users.uid","tid = ?","","")
@@ -253,7 +253,7 @@ func write_inner_joins(adapter qgen.DB_Adapter) error {
}
func write_inserts(adapter qgen.DB_Adapter) error {
- adapter.SimpleInsert("create_topic","topics","parentID,title,content,parsed_content,createdAt,lastReplyAt,ipaddress,words,createdBy","?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?")
+ adapter.SimpleInsert("create_topic","topics","parentID,title,content,parsed_content,createdAt,lastReplyAt,lastReplyBy,ipaddress,words,createdBy","?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,?")
adapter.SimpleInsert("create_report","topics","title,content,parsed_content,createdAt,lastReplyAt,createdBy,data,parentID,css_class","?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,1,'report'")
@@ -298,7 +298,7 @@ func write_replaces(adapter qgen.DB_Adapter) error {
}
func write_updates(adapter qgen.DB_Adapter) error {
- adapter.SimpleUpdate("add_replies_to_topic","topics","postCount = postCount + ?, lastReplyAt = UTC_TIMESTAMP()","tid = ?")
+ adapter.SimpleUpdate("add_replies_to_topic","topics","postCount = postCount + ?, lastReplyBy = ?, lastReplyAt = UTC_TIMESTAMP()","tid = ?")
adapter.SimpleUpdate("remove_replies_from_topic","topics","postCount = postCount - ?","tid = ?")
diff --git a/router_gen/main.go b/router_gen/main.go
index 9c6f126d..58bb9ffc 100644
--- a/router_gen/main.go
+++ b/router_gen/main.go
@@ -140,9 +140,13 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
extra_data = req.URL.Path[strings.LastIndexByte(req.URL.Path,'/') + 1:]
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
}
- //fmt.Println("prefix:",prefix)
- //fmt.Println("req.URL.Path:",req.URL.Path)
- //fmt.Println("extra_data:",extra_data)
+
+ if dev.SuperDebug {
+ fmt.Println("before route_static")
+ fmt.Println("prefix:",prefix)
+ fmt.Println("req.URL.Path:",req.URL.Path)
+ fmt.Println("extra_data:",extra_data)
+ }
if prefix == "/static" {
req.URL.Path += extra_data
@@ -174,6 +178,18 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
router.UploadHandler(w,req)
return
case "":
+ // Stop the favicons, robots.txt file, etc. resolving to the topics list
+ // TO-DO: Add support for favicons and robots.txt files
+ switch(extra_data) {
+ case "robots.txt":
+ route_robots_txt(w,req)
+ return
+ }
+
+ if extra_data != "" {
+ NotFound(w,req)
+ return
+ }
config.DefaultRoute(w,req,user)
return
//default: NotFound(w,req)
diff --git a/routes.go b/routes.go
index 0ee099d3..2e387d3d 100644
--- a/routes.go
+++ b/routes.go
@@ -70,6 +70,18 @@ func route_fstatic(w http.ResponseWriter, r *http.Request){
http.ServeFile(w,r,r.URL.Path)
}*/
+// TO-DO: Make this a static file somehow? Is it possible for us to put this file somewhere else?
+// TO-DO: Add a sitemap
+// TO-DO: Add an API so that plugins can register disallowed areas. E.g. /groups/join for plugin_socialgroups
+func route_robots_txt(w http.ResponseWriter, r *http.Request) {
+ w.Write([]byte(`User-agent: *
+Disallow: /panel/
+Disallow: /topics/create/
+Disallow: /user/edit/
+Disallow: /accounts/
+`))
+}
+
func route_overview(w http.ResponseWriter, r *http.Request, user User){
headerVars, ok := SessionCheck(w,r,&user)
if !ok {
@@ -134,8 +146,9 @@ func route_topics(w http.ResponseWriter, r *http.Request, user User){
}
qlist = qlist[0:len(qlist) - 1]
- var topicList []TopicsRow
- stmt, err := qgen.Builder.SimpleLeftJoin("topics","users","topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, topics.postCount, topics.likeCount, users.name, users.avatar","topics.createdBy = users.uid","parentID IN("+qlist+")","topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC","")
+ var topicList []*TopicsRow
+ //stmt, err := qgen.Builder.SimpleLeftJoin("topics","users","topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, topics.postCount, topics.likeCount, users.name, users.avatar","topics.createdBy = users.uid","parentID IN("+qlist+")","topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC","")
+ stmt, err := qgen.Builder.SimpleSelect("topics","tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, parentID, postCount, likeCount","parentID IN("+qlist+")","sticky DESC, lastReplyAt DESC, createdBy DESC","")
if err != nil {
InternalError(err,w,r)
return
@@ -146,25 +159,18 @@ func route_topics(w http.ResponseWriter, r *http.Request, user User){
InternalError(err,w,r)
return
}
+ defer rows.Close()
- topicItem := TopicsRow{ID: 0}
+ var reqUserList map[int]bool = make(map[int]bool)
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.PostCount, &topicItem.LikeCount, &topicItem.CreatedByName, &topicItem.Avatar)
+ topicItem := TopicsRow{ID: 0}
+ err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.Is_Closed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.LastReplyAt, &topicItem.LastReplyBy, &topicItem.ParentID, &topicItem.PostCount, &topicItem.LikeCount)
if err != nil {
InternalError(err,w,r)
return
}
topicItem.Link = build_topic_url(name_to_slug(topicItem.Title),topicItem.ID)
- topicItem.UserLink = build_profile_url(name_to_slug(topicItem.CreatedByName),topicItem.CreatedBy)
-
- if topicItem.Avatar != "" {
- if topicItem.Avatar[0] == '.' {
- topicItem.Avatar = "/uploads/avatar_" + strconv.Itoa(topicItem.CreatedBy) + topicItem.Avatar
- }
- } else {
- topicItem.Avatar = strings.Replace(config.Noavatar,"{id}",strconv.Itoa(topicItem.CreatedBy),1)
- }
forum := fstore.DirtyGet(topicItem.ParentID)
if topicItem.ParentID >= 0 {
@@ -183,17 +189,40 @@ func route_topics(w http.ResponseWriter, r *http.Request, user User){
InternalError(err,w,r)
}
- if hooks["topics_trow_assign"] != nil {
- run_vhook("topics_trow_assign", &topicItem, &forum)
+ if hooks["topics_topic_row_assign"] != nil {
+ run_vhook("topics_topic_row_assign", &topicItem, &forum)
}
- topicList = append(topicList, topicItem)
+ topicList = append(topicList, &topicItem)
+ reqUserList[topicItem.CreatedBy] = true
+ reqUserList[topicItem.LastReplyBy] = true
}
err = rows.Err()
if err != nil {
InternalError(err,w,r)
return
}
- rows.Close()
+
+ // Convert the user ID map to a slice, then bulk load the users
+ var idSlice []int = make([]int,len(reqUserList))
+ var i int
+ for userID, _ := range reqUserList {
+ idSlice[i] = userID
+ i++
+ }
+
+ // TO-DO: What if a user is deleted via the Control Panel?
+ userList, err := users.BulkCascadeGetMap(idSlice)
+ if err != nil {
+ InternalError(err,w,r)
+ return
+ }
+
+ // Second pass to the add the user data
+ // TO-DO: Use a pointer to TopicsRow instead of TopicsRow itself?
+ for _, topicItem := range topicList {
+ topicItem.Creator = userList[topicItem.CreatedBy]
+ topicItem.LastUser = userList[topicItem.LastReplyBy]
+ }
pi := TopicsPage{"Topic List",user,headerVars,topicList,extData}
if pre_render_hooks["pre_render_topic_list"] != nil {
@@ -268,27 +297,20 @@ func route_forum(w http.ResponseWriter, r *http.Request, user User, sfid string)
InternalError(err,w,r)
return
}
+ defer rows.Close()
- var topicList []TopicUser
- var topicItem TopicUser = TopicUser{ID: 0}
+ // TO-DO: Use something other than TopicsRow as we don't need to store the forum name and link on each and every topic item?
+ var topicList []*TopicsRow
+ var reqUserList map[int]bool = make(map[int]bool)
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.PostCount, &topicItem.LikeCount, &topicItem.CreatedByName, &topicItem.Avatar)
+ var topicItem TopicsRow = TopicsRow{ID: 0}
+ err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.Is_Closed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.LastReplyAt, &topicItem.LastReplyBy, &topicItem.ParentID, &topicItem.PostCount, &topicItem.LikeCount)
if err != nil {
InternalError(err,w,r)
return
}
topicItem.Link = build_topic_url(name_to_slug(topicItem.Title),topicItem.ID)
- topicItem.UserLink = build_profile_url(name_to_slug(topicItem.CreatedByName),topicItem.CreatedBy)
-
- if topicItem.Avatar != "" {
- if topicItem.Avatar[0] == '.' {
- topicItem.Avatar = "/uploads/avatar_" + strconv.Itoa(topicItem.CreatedBy) + topicItem.Avatar
- }
- } else {
- topicItem.Avatar = strings.Replace(config.Noavatar,"{id}",strconv.Itoa(topicItem.CreatedBy),1)
- }
-
topicItem.LastReplyAt, err = relative_time(topicItem.LastReplyAt)
if err != nil {
InternalError(err,w,r)
@@ -297,14 +319,37 @@ func route_forum(w http.ResponseWriter, r *http.Request, user User, sfid string)
if hooks["forum_trow_assign"] != nil {
run_vhook("forum_trow_assign", &topicItem, &forum)
}
- topicList = append(topicList, topicItem)
+ topicList = append(topicList, &topicItem)
+ reqUserList[topicItem.CreatedBy] = true
+ reqUserList[topicItem.LastReplyBy] = true
}
err = rows.Err()
if err != nil {
InternalError(err,w,r)
return
}
- rows.Close()
+
+ // Convert the user ID map to a slice, then bulk load the users
+ var idSlice []int = make([]int,len(reqUserList))
+ var i int
+ for userID, _ := range reqUserList {
+ idSlice[i] = userID
+ i++
+ }
+
+ // TO-DO: What if a user is deleted via the Control Panel?
+ userList, err := users.BulkCascadeGetMap(idSlice)
+ if err != nil {
+ InternalError(err,w,r)
+ return
+ }
+
+ // Second pass to the add the user data
+ // TO-DO: Use a pointer to TopicsRow instead of TopicsRow itself?
+ for _, topicItem := range topicList {
+ topicItem.Creator = userList[topicItem.CreatedBy]
+ topicItem.LastUser = userList[topicItem.LastReplyBy]
+ }
pi := ForumPage{forum.Name,user,headerVars,topicList,*forum,page,last_page,extData}
if pre_render_hooks["pre_render_view_forum"] != nil {
@@ -482,6 +527,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request, user User){
InternalError(err,w,r)
return
}
+ defer rows.Close()
replyItem := Reply{ClassName:""}
for rows.Next() {
@@ -561,7 +607,6 @@ func route_topic_id(w http.ResponseWriter, r *http.Request, user User){
InternalError(err,w,r)
return
}
- rows.Close()
tpage := TopicPage{topic.Title,user,headerVars,replyList,topic,page,last_page,extData}
if pre_render_hooks["pre_render_view_topic"] != nil {
@@ -802,7 +847,7 @@ func route_topic_create_submit(w http.ResponseWriter, r *http.Request, user User
}
wcount := word_count(content)
- res, err := create_topic_stmt.Exec(fid,topic_name,content,parse_message(content),ipaddress,wcount,user.ID)
+ res, err := create_topic_stmt.Exec(fid,topic_name,content,parse_message(content),user.ID,ipaddress,wcount,user.ID)
if err != nil {
InternalError(err,w,r)
return
@@ -882,7 +927,7 @@ func route_create_reply(w http.ResponseWriter, r *http.Request, user User) {
return
}
- _, err = add_replies_to_topic_stmt.Exec(1,tid)
+ _, err = add_replies_to_topic_stmt.Exec(1,user.ID,tid)
if err != nil {
InternalError(err,w,r)
return
@@ -1922,6 +1967,7 @@ func route_api(w http.ResponseWriter, r *http.Request, user User) {
InternalErrorJS(err,w,r)
return
}
+ defer rows.Close()
for rows.Next() {
err = rows.Scan(&asid,&actor_id,&targetUser_id,&event,&elementType,&elementID)
@@ -1942,7 +1988,6 @@ func route_api(w http.ResponseWriter, r *http.Request, user User) {
InternalErrorJS(err,w,r)
return
}
- rows.Close()
if len(msglist) != 0 {
msglist = msglist[0:len(msglist)-1]
diff --git a/template_forum.go b/template_forum.go
index 4e457433..a24ce4fb 100644
--- a/template_forum.go
+++ b/template_forum.go
@@ -111,9 +111,9 @@ w.Write(forum_19)
}
}
w.Write(forum_20)
-if item.Avatar != "" {
+if item.Creator.Avatar != "" {
w.Write(forum_21)
-w.Write([]byte(item.Avatar))
+w.Write([]byte(item.Creator.Avatar))
w.Write(forum_22)
}
w.Write(forum_23)
@@ -125,25 +125,40 @@ w.Write([]byte(item.Link))
w.Write(forum_26)
w.Write([]byte(item.Title))
w.Write(forum_27)
-w.Write([]byte(item.UserLink))
+w.Write([]byte(item.Creator.Link))
w.Write(forum_28)
-w.Write([]byte(item.CreatedByName))
+w.Write([]byte(item.Creator.Name))
w.Write(forum_29)
if item.Is_Closed {
w.Write(forum_30)
}
+if item.Sticky {
w.Write(forum_31)
}
-} else {
w.Write(forum_32)
-if tmpl_forum_vars.CurrentUser.Perms.CreateTopic {
+if item.LastUser.Avatar != "" {
w.Write(forum_33)
-w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
+w.Write([]byte(item.LastUser.Avatar))
w.Write(forum_34)
}
w.Write(forum_35)
-}
+w.Write([]byte(item.LastUser.Link))
w.Write(forum_36)
+w.Write([]byte(item.LastUser.Name))
+w.Write(forum_37)
+w.Write([]byte(item.LastReplyAt))
+w.Write(forum_38)
+}
+} else {
+w.Write(forum_39)
+if tmpl_forum_vars.CurrentUser.Perms.CreateTopic {
+w.Write(forum_40)
+w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
+w.Write(forum_41)
+}
+w.Write(forum_42)
+}
+w.Write(forum_43)
w.Write(footer_0)
if tmpl_forum_vars.Header.Widgets.RightSidebar != "" {
w.Write(footer_1)
diff --git a/template_list.go b/template_list.go
index 80cddd69..76241590 100644
--- a/template_list.go
+++ b/template_list.go
@@ -77,7 +77,7 @@ var header_15 []byte = []byte(``)
var topic_0 []byte = []byte(`