From d976a192fbcdae537c13c1406c7ba4369fcbc0af Mon Sep 17 00:00:00 2001 From: Azareal Date: Mon, 17 Jul 2017 11:23:42 +0100 Subject: [PATCH] Added the new theme, Shadow. It still isn't complete yet. Revamped the configuration system. If you have trouble installing this, try installing my fork of gopsutil with `go get` and delete the users_penalties table from the schema folder. That stuff will be cleaned up in the next commit. Fixed an issue with the links for the Uncategorised forum being broken. Swapped out NOW() for UTC_TIMESTAMP() in MySQL queries. We now get an error message when the server goes down for whatever reason. The template compiler now supports pointers. Swapped out shirou/gopsutil for a fork locked on an older and more stable commit of the same library. Fixed a bug where the preprocessor didn't play nice with empty CSS files. Added the site name to the navbar. Added more things to .gitignore Laid the foundations for the next commit. --- .gitignore | 2 + config.go | 72 +++---- database.go | 4 +- experimental/config.json | 46 +++-- experimental/plugin_sendmail.go | 4 +- files.go | 4 +- forum_store.go | 8 +- gen_mysql.go | 18 +- gen_pgsql.go | 6 +- gen_router.go | 12 +- general_test.go | 29 +-- install/install.go | 72 +++---- install/pgsql.go | 2 +- main.go | 57 ++++-- mod_routes.go | 4 +- mysql.go | 14 +- mysql.sql | 6 +- pages.go | 1 + panel_routes.go | 36 ++-- permissions.go | 16 +- pgsql.go | 5 +- plugin_socialgroups.go | 29 +-- query_gen/lib/mysql.go | 2 +- query_gen/lib/pgsql.go | 11 +- query_gen/main.go | 45 ++++- reply.go | 3 +- router_gen/main.go | 12 +- routes.go | 66 +++--- schema/mysql/query_users_penalties.sql | 12 ++ schema/pgsql/query_users_penalties.sql | 12 ++ site.go | 61 ++++++ template_forum.go | 28 +-- template_forums.go | 44 ++-- template_list.go | 258 ++++++++++++------------ template_profile.go | 71 +++---- template_topic.go | 160 +++++++-------- template_topic_alt.go | 20 +- template_topics.go | 22 +- templates.go | 152 +++++++------- templates/forum.html | 3 +- templates/forums.html | 3 +- templates/menu.html | 5 +- templates/profile.html | 2 +- templates/topic.html | 14 +- templates/topic_alt.html | 4 +- themes.go | 8 +- themes/cosmo-conflux/public/main.css | 4 + themes/cosmo/public/main.css | 4 + themes/shadow/public/main.css | 266 +++++++++++++++++++++++++ themes/shadow/public/panel.css | 0 themes/shadow/theme.json | 5 +- themes/tempra-conflux/public/main.css | 3 + themes/tempra-cursive/public/main.css | 24 ++- themes/tempra-simple/public/main.css | 43 +++- topic.go | 3 +- user.go | 8 +- user_store.go | 14 +- utils.go | 11 +- websockets.go | 4 +- widgets.go | 2 +- 60 files changed, 1190 insertions(+), 666 deletions(-) create mode 100644 schema/mysql/query_users_penalties.sql create mode 100644 schema/pgsql/query_users_penalties.sql create mode 100644 site.go create mode 100644 themes/shadow/public/main.css create mode 100644 themes/shadow/public/panel.css diff --git a/.gitignore b/.gitignore index 79aecf79..008366cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ tmp/* tmp2/* uploads/avatar_* +uploads/socialgroup_* bin/* *.exe +*.exe~ *.prof .DS_Store diff --git a/config.go b/config.go index 19764dab..ef798c93 100644 --- a/config.go +++ b/config.go @@ -1,50 +1,52 @@ package main +func init() { // Site Info -var site_name = "Test Install" // Should be a setting in the database -var site_url = "localhost:8080" -var server_port = "8080" -var enable_ssl = false -var ssl_privkey = "" -var ssl_fullchain = "" +site.Name = "Test Site" // Should be a setting in the database +site.Email = "" // Should be a setting in the database +site.Url = "localhost" +site.Port = "8080" +site.EnableSsl = false +site.EnableEmails = false +config.SslPrivkey = "" +config.SslFullchain = "" // Database details -var dbhost = "localhost" -var dbuser = "root" -var dbpassword = "password" -var dbname = "gosora" -var dbport = "3306" // You probably won't need to change this +db_config.Host = "localhost" +db_config.Username = "root" +db_config.Password = "password" +db_config.Dbname = "gosora" +db_config.Port = "3306" // You probably won't need to change this // Limiters -var max_request_size = 5 * megabyte +config.MaxRequestSize = 5 * megabyte // Caching -var cache_topicuser = CACHE_STATIC -var user_cache_capacity = 100 // The max number of users held in memory -var topic_cache_capacity = 100 // The max number of topics held in memory +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 // Email -var site_email = "" // Should be a setting in the database -var smtp_server = "" -var smtp_username = "" -var smtp_password = "" -var smtp_port = "25" -var enable_emails = false +config.SmtpServer = "" +config.SmtpUsername = "" +config.SmtpPassword = "" +config.SmtpPort = "25" // Misc -var default_route = route_topics -var default_group = 3 // Should be a setting in the database -var activation_group = 5 // Should be a setting in the database -var staff_css = " background-color: #ffeaff;" -var uncategorised_forum_visible = true -var minify_templates = false -var multi_server = false // Experimental: Enable Cross-Server Synchronisation and several other features +config.DefaultRoute = route_topics +config.DefaultGroup = 3 // Should be a setting in the database +config.ActivationGroup = 5 // Should be a setting in the database +config.StaffCss = "staff_post" +config.UncategorisedForumVisible = true +config.MinifyTemplates = false +config.MultiServer = false // Experimental: Enable Cross-Server Synchronisation and several other features -//var noavatar = "https://api.adorable.io/avatars/{width}/{id}@{site_url}.png" -var noavatar = "https://api.adorable.io/avatars/285/{id}@" + site_url + ".png" -var items_per_page = 25 +//config.Noavatar = "https://api.adorable.io/avatars/{width}/{id}@{site_url}.png" +config.Noavatar = "https://api.adorable.io/avatars/285/{id}@{site_url}.png" +config.ItemsPerPage = 25 -// Developer flags -var debug_mode = false -var super_debug = false -var profiling = false +// Developer flag +dev.DebugMode = true +//dev.SuperDebug = true +//dev.Profiling = true +} diff --git a/database.go b/database.go index b6a92f5c..d5a0c811 100644 --- a/database.go +++ b/database.go @@ -44,7 +44,7 @@ func init_database() (err error) { if err != nil { return err } - if debug_mode { + if dev.DebugMode { log.Print(group.Name + ": ") fmt.Printf("%+v\n", group.Perms) } @@ -53,7 +53,7 @@ func init_database() (err error) { if err != nil { return err } - if debug_mode { + if dev.DebugMode { log.Print(group.Name + ": ") fmt.Printf("%+v\n", group.PluginPerms) } diff --git a/experimental/config.json b/experimental/config.json index 4a09ee4d..105aaafd 100644 --- a/experimental/config.json +++ b/experimental/config.json @@ -1,23 +1,35 @@ { - "dbhost": "127.0.0.1", - "dbuser": "root", - "dbpassword": "password", - "dbname": "gosora", - "dbport": "3306", - - "default_group": 3, - "activation_group": 5, + "config.DefaultGroup": 3, + "config.ActivationGroup": 5, "staff_css": " background-color: #ffeaff;", "uncategorised_forum_visible": true, - "enable_emails": false, - "smtp_server": "", - "items_per_page": 40, + "site.EnableEmails": false, + "config.SmtpServer": "", + "config.ItemsPerPage": 40, - "site_url": "localhost:8080", - "server_port": "8080", - "enable_ssl": false, - "ssl_privkey": "", - "ssl_fullchain": "", + "db": { + "Host": "127.0.0.1", + "Username": "root", + "Password": "password", + "Dbname": "gosora", + "Port": "3306" + }, - "debug": false + "site": + { + "Url": "localhost:8080", + "Port": "8080", + "EnableSsl": false + }, + + "config": + { + "SslPrivkey": "", + "SslFullchain": "" + }, + + "dev": + { + "debug": false + }, } \ No newline at end of file diff --git a/experimental/plugin_sendmail.go b/experimental/plugin_sendmail.go index 9b250d34..79b9631b 100644 --- a/experimental/plugin_sendmail.go +++ b/experimental/plugin_sendmail.go @@ -19,7 +19,7 @@ func init_sendmail() { // Sendmail is only available on Linux func activate_sendmail() error { - if !enable_emails { + if !site.EnableEmails { return errors.New("You have emails disabled in your configuration file") } if runtime.GOOS != "linux" { @@ -37,7 +37,7 @@ func send_sendmail(data ...interface{}) interface{} { subject := data[1].(string) body := data[2].(string) - msg := "From: " + site_email + "\n" + msg := "From: " + site.Email + "\n" msg += "To: " + to + "\n" msg += "Subject: " + subject + "\n\n" msg += body + "\n" diff --git a/files.go b/files.go index 70bbf5d0..008f8161 100644 --- a/files.go +++ b/files.go @@ -49,7 +49,7 @@ func init_static_files() { static_files["/static/" + path] = SFile{data,gzip_data,0,int64(len(data)),int64(len(gzip_data)),mime.TypeByExtension(ext),f,f.ModTime().UTC().Format(http.TimeFormat)} - if debug_mode { + if dev.DebugMode { log.Print("Added the '" + path + "' static file.") } return nil @@ -79,7 +79,7 @@ func add_static_file(path string, prefix string) error { static_files["/static" + path] = SFile{data,gzip_data,0,int64(len(data)),int64(len(gzip_data)),mime.TypeByExtension(ext),f,f.ModTime().UTC().Format(http.TimeFormat)} - if debug_mode { + if dev.DebugMode { log.Print("Added the '" + path + "' static file") } return nil diff --git a/forum_store.go b/forum_store.go index 20cc019b..68a10822 100644 --- a/forum_store.go +++ b/forum_store.go @@ -65,7 +65,7 @@ func NewStaticForumStore() *StaticForumStore { func (sfs *StaticForumStore) LoadForums() error { log.Print("Adding the uncategorised forum") var forums []*Forum = []*Forum{ - &Forum{0,"uncategorised","Uncategorised","",uncategorised_forum_visible,"all",0,"",0,"","",0,"",0,""}, + &Forum{0,build_forum_url(name_to_slug("Uncategorised"),0),"Uncategorised","",config.UncategorisedForumVisible,"all",0,"",0,"","",0,"",0,""}, } rows, err := get_forums_stmt.Query() @@ -89,7 +89,7 @@ func (sfs *StaticForumStore) LoadForums() error { } if forum.Name == "" { - if debug_mode { + if dev.DebugMode { log.Print("Adding a placeholder forum") } } else { @@ -111,14 +111,14 @@ func (sfs *StaticForumStore) LoadForums() error { } func (sfs *StaticForumStore) DirtyGet(id int) *Forum { - if !((id <= sfs.forumCapCount) && (id >= 0) && sfs.forums[id].Name!="") { + if !((id <= sfs.forumCapCount) && (id >= 0) && sfs.forums[id].Name != "") { return &Forum{ID:-1,Name:""} } return sfs.forums[id] } func (sfs *StaticForumStore) Get(id int) (*Forum, error) { - if !((id <= sfs.forumCapCount) && (id >= 0) && sfs.forums[id].Name!="") { + if !((id <= sfs.forumCapCount) && (id >= 0) && sfs.forums[id].Name != "") { return nil, ErrNoRows } return sfs.forums[id], nil diff --git a/gen_mysql.go b/gen_mysql.go index 8a5860a2..5e5f1131 100644 --- a/gen_mysql.go +++ b/gen_mysql.go @@ -114,7 +114,7 @@ var add_forum_perms_to_forum_members_stmt *sql.Stmt var notify_watchers_stmt *sql.Stmt func _gen_mysql() (err error) { - if debug_mode { + if dev.DebugMode { log.Print("Building the generated statements") } @@ -365,19 +365,19 @@ 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 (?,?,?,?,NOW(),NOW(),?,?,?)") + create_topic_stmt, err = db.Prepare("INSERT INTO `topics`(`parentID`,`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`ipaddress`,`words`,`createdBy`) VALUES (?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?)") if err != nil { return err } log.Print("Preparing create_report statement.") - create_report_stmt, err = db.Prepare("INSERT INTO `topics`(`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`createdBy`,`data`,`parentID`,`css_class`) VALUES (?,?,?,NOW(),NOW(),?,?,1,'report')") + create_report_stmt, err = db.Prepare("INSERT INTO `topics`(`title`,`content`,`parsed_content`,`createdAt`,`lastReplyAt`,`createdBy`,`data`,`parentID`,`css_class`) VALUES (?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,1,'report')") if err != nil { return err } log.Print("Preparing create_reply statement.") - create_reply_stmt, err = db.Prepare("INSERT INTO `replies`(`tid`,`content`,`parsed_content`,`createdAt`,`ipaddress`,`words`,`createdBy`) VALUES (?,?,?,NOW(),?,?,?)") + create_reply_stmt, err = db.Prepare("INSERT INTO `replies`(`tid`,`content`,`parsed_content`,`createdAt`,`ipaddress`,`words`,`createdBy`) VALUES (?,?,?,UTC_TIMESTAMP(),?,?,?)") if err != nil { return err } @@ -413,7 +413,7 @@ func _gen_mysql() (err error) { } log.Print("Preparing create_profile_reply statement.") - create_profile_reply_stmt, err = db.Prepare("INSERT INTO `users_replies`(`uid`,`content`,`parsed_content`,`createdAt`,`createdBy`,`ipaddress`) VALUES (?,?,?,NOW(),?,?)") + create_profile_reply_stmt, err = db.Prepare("INSERT INTO `users_replies`(`uid`,`content`,`parsed_content`,`createdAt`,`createdBy`,`ipaddress`) VALUES (?,?,?,UTC_TIMESTAMP(),?,?)") if err != nil { return err } @@ -455,13 +455,13 @@ func _gen_mysql() (err error) { } log.Print("Preparing add_modlog_entry statement.") - add_modlog_entry_stmt, err = db.Prepare("INSERT INTO `moderation_logs`(`action`,`elementID`,`elementType`,`ipaddress`,`actorID`,`doneAt`) VALUES (?,?,?,?,?,NOW())") + add_modlog_entry_stmt, err = db.Prepare("INSERT INTO `moderation_logs`(`action`,`elementID`,`elementType`,`ipaddress`,`actorID`,`doneAt`) VALUES (?,?,?,?,?,UTC_TIMESTAMP())") if err != nil { return err } log.Print("Preparing add_adminlog_entry statement.") - add_adminlog_entry_stmt, err = db.Prepare("INSERT INTO `administration_logs`(`action`,`elementID`,`elementType`,`ipaddress`,`actorID`,`doneAt`) VALUES (?,?,?,?,?,NOW())") + add_adminlog_entry_stmt, err = db.Prepare("INSERT INTO `administration_logs`(`action`,`elementID`,`elementType`,`ipaddress`,`actorID`,`doneAt`) VALUES (?,?,?,?,?,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` = NOW() WHERE `tid` = ?") + add_replies_to_topic_stmt, err = db.Prepare("UPDATE `topics` SET `postCount` = `postCount` + ?,`lastReplyAt` = UTC_TIMESTAMP() WHERE `tid` = ?") if err != nil { return err } @@ -497,7 +497,7 @@ func _gen_mysql() (err error) { } log.Print("Preparing update_forum_cache statement.") - update_forum_cache_stmt, err = db.Prepare("UPDATE `forums` SET `lastTopic` = ?,`lastTopicID` = ?,`lastReplyer` = ?,`lastReplyerID` = ?,`lastTopicTime` = NOW() WHERE `fid` = ?") + update_forum_cache_stmt, err = db.Prepare("UPDATE `forums` SET `lastTopic` = ?,`lastTopicID` = ?,`lastReplyer` = ?,`lastReplyerID` = ?,`lastTopicTime` = UTC_TIMESTAMP() WHERE `fid` = ?") if err != nil { return err } diff --git a/gen_pgsql.go b/gen_pgsql.go index 0feef6bc..0f466ca6 100644 --- a/gen_pgsql.go +++ b/gen_pgsql.go @@ -45,12 +45,12 @@ var update_email_stmt *sql.Stmt var verify_email_stmt *sql.Stmt func _gen_pgsql() (err error) { - if debug_mode { + if dev.DebugMode { log.Print("Building the generated statements") } log.Print("Preparing add_replies_to_topic statement.") - add_replies_to_topic_stmt, err = db.Prepare("UPDATE `topics` SET `postCount` = `postCount` + ?,`lastReplyAt` = NOW() WHERE `tid` = ?") + add_replies_to_topic_stmt, err = db.Prepare("UPDATE `topics` SET `postCount` = `postCount` + ?,`lastReplyAt` = UTC_TIMESTAMP() 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` = NOW() WHERE `fid` = ?") + update_forum_cache_stmt, err = db.Prepare("UPDATE `forums` SET `lastTopic` = ?,`lastTopicID` = ?,`lastReplyer` = ?,`lastReplyerID` = ?,`lastTopicTime` = UTC_TIMESTAMP() WHERE `fid` = ?") if err != nil { return err } diff --git a/gen_router.go b/gen_router.go index 97226773..3389cde1 100644 --- a/gen_router.go +++ b/gen_router.go @@ -2,7 +2,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 "fmt" +import "fmt" import "strings" import "sync" import "errors" @@ -72,12 +72,20 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } + if dev.SuperDebug { + fmt.Println("before PreRoute") + } + // Deal with the session stuff, etc. user, ok := PreRoute(w,req) if !ok { return } + if dev.SuperDebug { + fmt.Println("after PreRoute") + } + switch(prefix) { case "/api": route_api(w,req,user) @@ -199,7 +207,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { router.UploadHandler(w,req) return case "": - default_route(w,req,user) + config.DefaultRoute(w,req,user) return //default: NotFound(w,req) } diff --git a/general_test.go b/general_test.go index c628c00d..0fe8aa15 100644 --- a/general_test.go +++ b/general_test.go @@ -26,7 +26,7 @@ var db_prod *sql.DB var gloinited bool func gloinit() { - debug_mode = false + dev.DebugMode = false //nogrouplog = true // init_database is a little noisy for a benchmark @@ -34,8 +34,9 @@ func gloinit() { //log.SetOutput(discard) startTime = time.Now() - timeLocation = startTime.Location() - + //timeLocation = startTime.Location() + process_config() + init_themes() err := init_database() if err != nil { @@ -55,7 +56,7 @@ func gloinit() { log.Fatal(err) } - if cache_topicuser == CACHE_STATIC { + if config.CacheTopicUser == CACHE_STATIC { users = NewMemoryUserStore(user_cache_capacity) topics = NewMemoryTopicStore(topic_cache_capacity) } else { @@ -84,16 +85,16 @@ func BenchmarkTopicTemplateSerial(b *testing.B) { 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!","Hey everyone!",0,"jerry","Jerry",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,"jerry2","Jerry2",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,"jerry3","Jerry3",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,"jerry4","Jerry4",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,"jerry5","Jerry5",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,"jerry6","Jerry6",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,"jerry7","Jerry7",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,"jerry8","Jerry8",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,"jerry9","Jerry9",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,"jerry10","Jerry10",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,"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,"",""}) headerVars := HeaderVars{ NoticeList:[]string{"test"}, diff --git a/install/install.go b/install/install.go index 5fff8df8..363fb9a2 100644 --- a/install/install.go +++ b/install/install.go @@ -100,7 +100,7 @@ func main() { } // Build the admin user query - admin_user_stmt, err := qgen.Builder.SimpleInsert("users","name, password, salt, email, group, is_super_admin, active, createdAt, lastActiveAt, message, last_ip","'Admin',?,?,'admin@localhost',1,1,1,NOW(),NOW(),'','127.0.0.1'") + admin_user_stmt, err := qgen.Builder.SimpleInsert("users","name, password, salt, email, group, is_super_admin, active, createdAt, lastActiveAt, message, last_ip","'Admin',?,?,'admin@localhost',1,1,1,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'','127.0.0.1'") if err != nil { fmt.Println(err) fmt.Println("Aborting installation...") @@ -137,54 +137,56 @@ func main() { configContents := []byte(`package main +func init() { // Site Info -var site_name = "` + site_name + `" // Should be a setting in the database -var site_url = "` + site_url + `" -var server_port = "` + server_port + `" -var enable_ssl = false -var ssl_privkey = "" -var ssl_fullchain = "" +site.Name = "` + site_name + `" // Should be a setting in the database +site.Email = "" // Should be a setting in the database +site.Url = "` + site_url + `" +site.Port = "` + server_port + `" +site.EnableSsl = false +site.EnableEmails = false +config.SslPrivkey = "" +config.SslFullchain = "" // Database details -var dbhost = "` + db_host + `" -var dbuser = "` + db_username + `" -var dbpassword = "` + db_password + `" -var dbname = "` + db_name + `" -var dbport = "` + db_port + `" // You probably won't need to change this +db_config.Host = "` + db_host + `" +db_config.Username = "` + db_username + `" +db_config.Password = "` + db_password + `" +db_config.Dbname = "` + db_name + `" +db_config.Port = "` + db_port + `" // You probably won't need to change this // Limiters -var max_request_size = 5 * megabyte +config.MaxRequestSize = 5 * megabyte // Caching -var cache_topicuser = CACHE_STATIC -var user_cache_capacity = 100 // The max number of users held in memory -var topic_cache_capacity = 100 // The max number of topics held in memory +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 // Email -var site_email = "" // Should be a setting in the database -var smtp_server = "" -var smtp_username = "" -var smtp_password = "" -var smtp_port = "25" -var enable_emails = false +config.SmtpServer = "" +config.SmtpUsername = "" +config.SmtpPassword = "" +config.SmtpPort = "25" // Misc -var default_route = route_topics -var default_group = 3 // Should be a setting in the database -var activation_group = 5 // Should be a setting in the database -var staff_css = " background-color: #ffeaff;" -var uncategorised_forum_visible = true -var minify_templates = true -var multi_server = false // Experimental: Enable Cross-Server Synchronisation and several other features +config.DefaultRoute = route_topics +config.DefaultGroup = 3 // Should be a setting in the database +config.ActivationGroup = 5 // Should be a setting in the database +config.StaffCss = "staff_post" +config.UncategorisedForumVisible = true +config.MinifyTemplates = true +config.MultiServer = false // Experimental: Enable Cross-Server Synchronisation and several other features -//var noavatar = "https://api.adorable.io/avatars/{width}/{id}@{site_url}.png" -var noavatar = "https://api.adorable.io/avatars/285/{id}@" + site_url + ".png" -var items_per_page = 25 +//config.Noavatar = "https://api.adorable.io/avatars/{width}/{id}@{site_url}.png" +config.Noavatar = "https://api.adorable.io/avatars/285/{id}@{site_url}.png" +config.ItemsPerPage = 25 // Developer flag -var debug_mode = true -var super_debug = false -var profiling = false +dev.DebugMode = true +//dev.SuperDebug = true +//dev.Profiling = true +} `) fmt.Println("Opening the configuration file") diff --git a/install/pgsql.go b/install/pgsql.go index b4db22a9..2233a00b 100644 --- a/install/pgsql.go +++ b/install/pgsql.go @@ -11,7 +11,7 @@ import _ "github.com/go-sql-driver/mysql" var db_sslmode = "disable" func _set_pgsql_adapter() { - db_port = "3306" + db_port = "5432" init_database = _init_pgsql } diff --git a/main.go b/main.go index 30f56a8f..072595a4 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "net/http" "fmt" "log" + "strings" "time" "io" "html/template" @@ -27,10 +28,9 @@ var enable_websockets bool = false // Don't change this, the value is overwritte var router *GenRouter var startTime time.Time -var timeLocation *time.Location +//var timeLocation *time.Location var templates = template.New("") -var no_css_tmpl template.CSS = template.CSS("") -var staff_css_tmpl template.CSS = template.CSS(staff_css) +//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 groups []Group @@ -49,6 +49,7 @@ func compile_templates() error { var c CTemplateSet user := User{62,"fake-user","Fake User","compiler@localhost",0,false,false,false,false,false,false,GuestPerms,make(map[string]bool),"",false,"","","","","",0,0,"0.0.0.0.0"} headerVars := HeaderVars{ + Site:site, NoticeList:[]string{"test"}, Stylesheets:[]string{"panel"}, Scripts:[]string{"whatever"}, @@ -59,9 +60,9 @@ func compile_templates() error { log.Print("Compiling the templates") - topic := TopicUser{1,"blah","Blah","Hey there!",0,false,false,"Date","Date",0,"","127.0.0.1",0,1,"classname","weird-data","fake-user","Fake User",default_group,"",no_css_tmpl,0,"","","","",58,false} + topic := TopicUser{1,"blah","Blah","Hey there!",0,false,false,"Date","Date",0,"","127.0.0.1",0,1,"classname","weird-data","fake-user","Fake User",config.DefaultGroup,"",0,"","","","",58,false} var replyList []Reply - replyList = append(replyList, Reply{0,0,"Yo!","Yo!",0,"alice","Alice",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""}) + replyList = append(replyList, Reply{0,0,"Yo!","Yo!",0,"alice","Alice",config.DefaultGroup,"",0,0,"","",0,"","","","",0,"127.0.0.1",false,1,"",""}) var varList map[string]VarItem = make(map[string]VarItem) tpage := TopicPage{"Title",user,headerVars,replyList,topic,1,1,extData} @@ -93,7 +94,7 @@ func compile_templates() error { 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",default_group,"","",0,"","","","",58,false}) + 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_tmpl := c.compile_template("forum.html","templates/","ForumPage",forum_page,varList) @@ -118,7 +119,7 @@ func write_template(name string, content string) { } func init_templates() { - if debug_mode { + if dev.DebugMode { log.Print("Initialising the template system") } compile_templates() @@ -134,7 +135,7 @@ func init_templates() { fmap["divide"] = filler_func // The interpreted templates... - if debug_mode { + if dev.DebugMode { log.Print("Loading the template files...") } templates.Funcs(fmap) @@ -142,6 +143,16 @@ func init_templates() { template.Must(templates.ParseGlob("pages/*")) } +func process_config() { + config.Noavatar = strings.Replace(config.Noavatar,"{site_url}",site.Url,-1) + if site.Port != "80" && site.Port != "443" { + site.Url = strings.TrimSuffix(site.Url,"/") + site.Url = strings.TrimSuffix(site.Url,"\\") + site.Url = strings.TrimSuffix(site.Url,":") + site.Url = site.Url + ":" + site.Port + } +} + func main(){ //if profiling { // f, err := os.Create("startup_cpu.prof") @@ -154,7 +165,10 @@ func main(){ log.Print("Running Gosora v" + version.String()) fmt.Println("") startTime = time.Now() - timeLocation = startTime.Location() + //timeLocation = startTime.Location() + + fmt.Println("Processing configuration data") + process_config() init_themes() err := init_database() @@ -168,9 +182,9 @@ func main(){ log.Fatal(err) } - if cache_topicuser == CACHE_STATIC { - users = NewMemoryUserStore(user_cache_capacity) - topics = NewMemoryTopicStore(topic_cache_capacity) + if config.CacheTopicUser == CACHE_STATIC { + users = NewMemoryUserStore(config.UserCacheCapacity) + topics = NewMemoryTopicStore(config.TopicCacheCapacity) } else { users = NewSqlUserStore() topics = NewSqlTopicStore() @@ -285,15 +299,20 @@ func main(){ //} log.Print("Initialising the HTTP server") - if !enable_ssl { - if server_port == "" { - server_port = "80" + if !site.EnableSsl { + if site.Port == "" { + site.Port = "80" } - http.ListenAndServe(":" + server_port, router) + err = http.ListenAndServe(":" + site.Port, router) } else { - if server_port == "" { - server_port = "443" + if site.Port == "" { + site.Port = "443" } - http.ListenAndServeTLS(":" + server_port, ssl_fullchain, ssl_privkey, router) + err = http.ListenAndServeTLS(":" + site.Port, config.SslFullchain, config.SslPrivkey, router) + } + + // Why did the server stop? + if err != nil { + log.Fatal(err) } } diff --git a/mod_routes.go b/mod_routes.go index 79754ade..18b1c2ce 100644 --- a/mod_routes.go +++ b/mod_routes.go @@ -659,7 +659,7 @@ func route_unban(w http.ResponseWriter, r *http.Request, user User) { return } - _, err = change_group_stmt.Exec(default_group, uid) + _, err = change_group_stmt.Exec(config.DefaultGroup, uid) if err != nil { InternalError(err,w,r) return @@ -724,7 +724,7 @@ func route_activate(w http.ResponseWriter, r *http.Request, user User) { return } - _, err = change_group_stmt.Exec(default_group, uid) + _, err = change_group_stmt.Exec(config.DefaultGroup, uid) if err != nil { InternalError(err,w,r) return diff --git a/mysql.go b/mysql.go index 5b4a9824..ce502aa7 100644 --- a/mysql.go +++ b/mysql.go @@ -18,12 +18,12 @@ var todays_newuser_count_stmt *sql.Stmt func _init_database() (err error) { var _dbpassword string - if(dbpassword != ""){ - _dbpassword = ":" + dbpassword + if(db_config.Password != ""){ + _dbpassword = ":" + db_config.Password } // Open the database connection - db, err = sql.Open("mysql",dbuser + _dbpassword + "@tcp(" + dbhost + ":" + dbport + ")/" + dbname + "?collation=" + db_collation) + db, err = sql.Open("mysql", db_config.Username + _dbpassword + "@tcp(" + db_config.Host + ":" + db_config.Port + ")/" + db_config.Dbname + "?collation=" + db_collation) if err != nil { return err } @@ -66,25 +66,25 @@ func _init_database() (err error) { } log.Print("Preparing todays_post_count statement.") - todays_post_count_stmt, err = db.Prepare("select count(*) from replies where createdAt BETWEEN (now() - interval 1 day) and now()") + todays_post_count_stmt, err = db.Prepare("select count(*) from replies where createdAt BETWEEN (utc_timestamp() - interval 1 day) and utc_timestamp()") if err != nil { return err } log.Print("Preparing todays_topic_count statement.") - todays_topic_count_stmt, err = db.Prepare("select count(*) from topics where createdAt BETWEEN (now() - interval 1 day) and now()") + todays_topic_count_stmt, err = db.Prepare("select count(*) from topics where createdAt BETWEEN (utc_timestamp() - interval 1 day) and utc_timestamp()") if err != nil { return err } log.Print("Preparing todays_report_count statement.") - todays_report_count_stmt, err = db.Prepare("select count(*) from topics where createdAt BETWEEN (now() - interval 1 day) and now() and parentID = 1") + todays_report_count_stmt, err = db.Prepare("select count(*) from topics where createdAt BETWEEN (utc_timestamp() - interval 1 day) and utc_timestamp() and parentID = 1") if err != nil { return err } log.Print("Preparing todays_newuser_count statement.") - todays_newuser_count_stmt, err = db.Prepare("select count(*) from users where createdAt BETWEEN (now() - interval 1 day) and now()") + todays_newuser_count_stmt, err = db.Prepare("select count(*) from users where createdAt BETWEEN (utc_timestamp() - interval 1 day) and utc_timestamp()") if err != nil { return err } diff --git a/mysql.sql b/mysql.sql index 623a0685..6dd1da08 100644 --- a/mysql.sql +++ b/mysql.sql @@ -234,7 +234,7 @@ INSERT INTO users_groups(`name`,`permissions`,`plugin_perms`) VALUES ('Awaiting INSERT INTO users_groups(`name`,`permissions`,`plugin_perms`,`tag`) VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest'); INSERT INTO forums(`name`,`active`) VALUES ('Reports',0); -INSERT INTO forums(`name`,`lastTopicTime`) VALUES ('General',NOW()); +INSERT INTO forums(`name`,`lastTopicTime`) VALUES ('General',UTC_TIMESTAMP()); INSERT INTO forums_permissions(`gid`,`fid`,`permissions`) VALUES (1,1,'{"ViewTopic":true,"CreateReply":true,"CreateTopic":true,"PinTopic":true,"CloseTopic":true}'); INSERT INTO forums_permissions(`gid`,`fid`,`permissions`) VALUES (2,1,'{"ViewTopic":true,"CreateReply":true,"CloseTopic":true}'); INSERT INTO forums_permissions(`gid`,`fid`,`permissions`) VALUES (3,1,'{}'); @@ -242,7 +242,7 @@ 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.',NOW(),NOW(),1,2); +VALUES ('Test Topic','A topic automatically generated by the software.',UTC_TIMESTAMP(),UTC_TIMESTAMP(),1,2); INSERT INTO replies(`tid`,`content`,`createdAt`,`createdBy`,`lastEdit`,`lastEditBy`) -VALUES (1,'Reply 1',NOW(),1,0,0); +VALUES (1,'Reply 1',UTC_TIMESTAMP(),1,0,0); diff --git a/pages.go b/pages.go index 8592f9bb..3c3ebdc2 100644 --- a/pages.go +++ b/pages.go @@ -14,6 +14,7 @@ type HeaderVars struct Scripts []string Stylesheets []string Widgets PageWidgets + Site *Site ExtData ExtData } diff --git a/panel_routes.go b/panel_routes.go index b8a859ae..d83103e0 100644 --- a/panel_routes.go +++ b/panel_routes.go @@ -7,14 +7,11 @@ import ( "strings" "strconv" "html" - "time" - "runtime" "encoding/json" "net/http" "html/template" - "github.com/shirou/gopsutil/cpu" - "github.com/shirou/gopsutil/mem" + "github.com/Azareal/gopsutil/mem" ) func route_panel(w http.ResponseWriter, r *http.Request, user User){ @@ -23,22 +20,14 @@ func route_panel(w http.ResponseWriter, r *http.Request, user User){ return } - var cpustr, cpuColour string - perc2, err := cpu.Percent(time.Duration(time.Second),true) - if err != nil { - cpustr = "Unknown" - } else { - calcperc := int(perc2[0]) / runtime.NumCPU() - cpustr = strconv.Itoa(calcperc) - if calcperc < 30 { - cpuColour = "stat_green" - } else if calcperc < 75 { - cpuColour = "stat_orange" - } else { - cpuColour = "stat_red" - } + if dev.SuperDebug { + fmt.Println("past PanelSessionCheck") } + // We won't calculate this on the spot anymore, as the system doesn't seem to like it if we do multiple fetches simultaneously. Should we constantly calculate this on a background thread? Perhaps, the watchdog to scale back heavy features under load? One plus side is that we'd get immediate CPU percentages here instead of waiting it to kick in with WebSockets + var cpustr string = "Unknown" + var cpuColour string + var ramstr, ramColour string memres, err := mem.VirtualMemory() if err != nil { @@ -126,7 +115,7 @@ func route_panel(w http.ResponseWriter, r *http.Request, user User){ var gridElements []GridElement = []GridElement{ GridElement{"dash-version","v" + version.String(),0,"grid_istat stat_green","","","Gosora is up-to-date :)"}, - GridElement{"dash-cpu","CPU: " + cpustr + "%",1,"grid_istat " + cpuColour,"","","The global CPU usage of this server"}, + GridElement{"dash-cpu","CPU: " + cpustr,1,"grid_istat " + cpuColour,"","","The global CPU usage of this server"}, GridElement{"dash-ram","RAM: " + ramstr,2,"grid_istat " + ramColour,"","","The global RAM usage of this server"}, } @@ -189,7 +178,10 @@ func route_panel(w http.ResponseWriter, r *http.Request, user User){ return } } - templates.ExecuteTemplate(w,"panel-dashboard.html",pi) + err = templates.ExecuteTemplate(w,"panel-dashboard.html",pi) + if err != nil { + InternalError(err,w,r) + } } func route_panel_forums(w http.ResponseWriter, r *http.Request, user User){ @@ -334,7 +326,7 @@ func route_panel_forums_delete_submit(w http.ResponseWriter, r *http.Request, us InternalError(err,w,r) return } - + http.Redirect(w,r,"/panel/forums/",http.StatusSeeOther) } @@ -987,7 +979,7 @@ func route_panel_users(w http.ResponseWriter, r *http.Request, user User){ puser.Avatar = "/uploads/avatar_" + strconv.Itoa(puser.ID) + puser.Avatar } } else { - puser.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(puser.ID),1) + puser.Avatar = strings.Replace(config.Noavatar,"{id}",strconv.Itoa(puser.ID),1) } if groups[puser.Group].Tag != "" { diff --git a/permissions.go b/permissions.go index 3b951fa9..bc5217c5 100644 --- a/permissions.go +++ b/permissions.go @@ -205,7 +205,7 @@ func init() { guest_user.Perms = GuestPerms - if debug_mode { + if dev.DebugMode { fmt.Printf("Guest Perms: ") fmt.Printf("%+v\n", GuestPerms) fmt.Printf("All Perms: ") @@ -304,7 +304,7 @@ func permmap_to_query(permmap map[string]ForumPerms, fid int) error { } func rebuild_forum_permissions(fid int) error { - if debug_mode { + if dev.DebugMode { log.Print("Loading the forum permissions") } forums, err := fstore.GetAll() @@ -318,7 +318,7 @@ func rebuild_forum_permissions(fid int) error { } defer rows.Close() - if debug_mode { + if dev.DebugMode { log.Print("Updating the forum permissions") } for rows.Next() { @@ -342,7 +342,7 @@ func rebuild_forum_permissions(fid int) error { forum_perms[gid][fid] = pperms } for gid, _ := range groups { - if debug_mode { + if dev.DebugMode { log.Print("Updating the forum permissions for Group #" + strconv.Itoa(gid)) } var blank_list []ForumPerms @@ -369,7 +369,7 @@ func rebuild_forum_permissions(fid int) error { groups[gid].CanSee = append(groups[gid].CanSee, ffid) } } - if super_debug { + if dev.SuperDebug { fmt.Printf("groups[gid].CanSee %+v\n", groups[gid].CanSee) fmt.Printf("groups[gid].Forums %+v\n", groups[gid].Forums) fmt.Println("len(groups[gid].Forums)",len(groups[gid].Forums)) @@ -390,7 +390,7 @@ func build_forum_permissions() error { } defer rows.Close() - if debug_mode { + if dev.DebugMode { log.Print("Adding the forum permissions") } // Temporarily store the forum perms in a map before transferring it to a much faster and thread-safe slice @@ -416,7 +416,7 @@ func build_forum_permissions() error { forum_perms[gid][fid] = pperms } for gid, _ := range groups { - if debug_mode { + if dev.DebugMode { log.Print("Adding the forum permissions for Group #" + strconv.Itoa(gid) + " - " + groups[gid].Name) } //groups[gid].Forums = append(groups[gid].Forums,BlankForumPerms) // GID 0. No longer needed now that Uncategorised occupies that slot @@ -441,7 +441,7 @@ func build_forum_permissions() error { groups[gid].CanSee = append(groups[gid].CanSee, fid) } } - if super_debug { + if dev.SuperDebug { //fmt.Printf("groups[gid].CanSee %+v\n", groups[gid].CanSee) //fmt.Printf("groups[gid].Forums %+v\n", groups[gid].Forums) //fmt.Println("len(groups[gid].CanSee)",len(groups[gid].CanSee)) diff --git a/pgsql.go b/pgsql.go index ad6e9e74..e51118ca 100644 --- a/pgsql.go +++ b/pgsql.go @@ -17,15 +17,14 @@ var todays_post_count_stmt *sql.Stmt var todays_topic_count_stmt *sql.Stmt var todays_report_count_stmt *sql.Stmt var todays_newuser_count_stmt *sql.Stmt -// Note to self: PostgreSQL listens on a different port than MySQL does func _init_database() (err error) { // TO-DO: Investigate connect_timeout to see what it does exactly and whether it's relevant to us var _dbpassword string if(dbpassword != ""){ - _dbpassword = " password='" + _escape_bit(dbpassword) + "'" + _dbpassword = " password='" + _escape_bit(db_config.Password) + "'" } - db, err = sql.Open("postgres", "host='" + _escape_bit(dbhost) + "' port='" + _escape_bit(dbport) + "' user='" + _escape_bit(dbuser) + "' dbname='" + _escape_bit(dbname) + "'" + _dbpassword + " sslmode='" + db_sslmode + "'") + db, err = sql.Open("postgres", "host='" + _escape_bit(db_config.Host) + "' port='" + _escape_bit(db_config.Port) + "' user='" + _escape_bit(db_config.Username) + "' dbname='" + _escape_bit(config.Dbname) + "'" + _dbpassword + " sslmode='" + db_sslmode + "'") if err != nil { return err } diff --git a/plugin_socialgroups.go b/plugin_socialgroups.go index 52c82c0c..9b228190 100644 --- a/plugin_socialgroups.go +++ b/plugin_socialgroups.go @@ -34,6 +34,10 @@ type SocialGroup struct Desc string Active bool Privacy int /* 0: Public, 1: Protected, 2: Private */ + + // Who should be able to accept applications and create invites? Mods+ or just admins? Mods is a good start, we can ponder over whether we should make this more flexible in the future. + Joinable int /* 0: Private, 1: Anyone can join, 2: Applications, 3: Invite-only */ + MemberCount int Owner int Backdrop string @@ -97,7 +101,7 @@ func init() { } func init_socialgroups() (err error) { - plugins["socialgroups"].AddHook("intercept_build_widgets", socialgroups_widgets) + plugins["socialgroups"].AddHook("intercept_build_widgets", socialgroups_widgets) plugins["socialgroups"].AddHook("trow_assign", socialgroups_trow_assign) plugins["socialgroups"].AddHook("topic_create_pre_loop", socialgroups_topic_create_pre_loop) plugins["socialgroups"].AddHook("pre_render_view_forum", socialgroups_pre_render_view_forum) @@ -111,11 +115,11 @@ func init_socialgroups() (err error) { router.HandleFunc("/group/create/submit/", socialgroups_create_group_submit) router.HandleFunc("/group/members/", socialgroups_member_list) - socialgroups_list_stmt, err = qgen.Builder.SimpleSelect("socialgroups","sgid, name, desc, active, privacy, owner, memberCount, createdAt, lastUpdateTime","","","") + socialgroups_list_stmt, err = qgen.Builder.SimpleSelect("socialgroups","sgid, name, desc, active, privacy, joinable, owner, memberCount, createdAt, lastUpdateTime","","","") if err != nil { return err } - socialgroups_get_group_stmt, err = qgen.Builder.SimpleSelect("socialgroups","name, desc, active, privacy, owner, memberCount, mainForum, backdrop, createdAt, lastUpdateTime","sgid = ?","","") + socialgroups_get_group_stmt, err = qgen.Builder.SimpleSelect("socialgroups","name, desc, active, privacy, joinable, owner, memberCount, mainForum, backdrop, createdAt, lastUpdateTime","sgid = ?","","") if err != nil { return err } @@ -131,7 +135,7 @@ func init_socialgroups() (err error) { if err != nil { return err } - socialgroups_create_group_stmt, err = qgen.Builder.SimpleInsert("socialgroups","name, desc, active, privacy, owner, memberCount, mainForum, backdrop, createdAt, lastUpdateTime","?,?,?,?,?,1,?,'',NOW(),NOW()") + socialgroups_create_group_stmt, err = qgen.Builder.SimpleInsert("socialgroups","name, desc, active, privacy, joinable, owner, memberCount, mainForum, backdrop, createdAt, lastUpdateTime","?,?,?,?,1,?,1,?,'',UTC_TIMESTAMP(),UTC_TIMESTAMP()") if err != nil { return err } @@ -143,7 +147,7 @@ func init_socialgroups() (err error) { if err != nil { return err } - socialgroups_add_member_stmt, err = qgen.Builder.SimpleInsert("socialgroups_members","sgid, uid, rank, posts, joinedAt","?,?,?,0,NOW()") + socialgroups_add_member_stmt, err = qgen.Builder.SimpleInsert("socialgroups_members","sgid, uid, rank, posts, joinedAt","?,?,?,0,UTC_TIMESTAMP()") if err != nil { return err } @@ -181,12 +185,13 @@ func install_socialgroups() error { qgen.DB_Table_Column{"sgid","int",0,false,true,""}, qgen.DB_Table_Column{"name","varchar",100,false,false,""}, qgen.DB_Table_Column{"desc","varchar",200,false,false,""}, - qgen.DB_Table_Column{"active","tinyint",1,false,false,""}, - qgen.DB_Table_Column{"privacy","tinyint",1,false,false,""}, + qgen.DB_Table_Column{"active","boolean",1,false,false,""}, + qgen.DB_Table_Column{"privacy","smallint",0,false,false,""}, + qgen.DB_Table_Column{"joinable","smallint",0,false,false,"0"}, qgen.DB_Table_Column{"owner","int",0,false,false,""}, qgen.DB_Table_Column{"memberCount","int",0,false,false,""}, qgen.DB_Table_Column{"mainForum","int",0,false,false,"0"}, // The board the user lands on when they click ona group, we'll make it possible for group admins to change what users land on - //qgen.DB_Table_Column{"boards","varchar",200,false,false,""}, // Cap the max number of boards at 8 to avoid overflowing the confines of a 64-bit integer? + //qgen.DB_Table_Column{"boards","varchar",255,false,false,""}, // Cap the max number of boards at 8 to avoid overflowing the confines of a 64-bit integer? qgen.DB_Table_Column{"backdrop","varchar",200,false,false,""}, // File extension for the uploaded file, or an external link qgen.DB_Table_Column{"createdAt","createdAt",0,false,false,""}, qgen.DB_Table_Column{"lastUpdateTime","datetime",0,false,false,""}, @@ -295,7 +300,7 @@ func socialgroups_group_list(w http.ResponseWriter, r *http.Request, user User) var sgList []SocialGroup for rows.Next() { sgItem := SocialGroup{ID:0} - err := rows.Scan(&sgItem.ID, &sgItem.Name, &sgItem.Desc, &sgItem.Active, &sgItem.Privacy, &sgItem.Owner, &sgItem.MemberCount, &sgItem.CreatedAt, &sgItem.LastUpdateTime) + err := rows.Scan(&sgItem.ID, &sgItem.Name, &sgItem.Desc, &sgItem.Active, &sgItem.Privacy, &sgItem.Joinable, &sgItem.Owner, &sgItem.MemberCount, &sgItem.CreatedAt, &sgItem.LastUpdateTime) if err != nil { InternalError(err,w,r) return @@ -319,7 +324,7 @@ func socialgroups_group_list(w http.ResponseWriter, r *http.Request, user User) func socialgroups_get_group(sgid int) (sgItem SocialGroup, err error) { sgItem = SocialGroup{ID:sgid} - err = socialgroups_get_group_stmt.QueryRow(sgid).Scan(&sgItem.Name, &sgItem.Desc, &sgItem.Active, &sgItem.Privacy, &sgItem.Owner, &sgItem.MemberCount, &sgItem.MainForumID, &sgItem.Backdrop, &sgItem.CreatedAt, &sgItem.LastUpdateTime) + err = socialgroups_get_group_stmt.QueryRow(sgid).Scan(&sgItem.Name, &sgItem.Desc, &sgItem.Active, &sgItem.Privacy, &sgItem.Joinable, &sgItem.Owner, &sgItem.MemberCount, &sgItem.MainForumID, &sgItem.Backdrop, &sgItem.CreatedAt, &sgItem.LastUpdateTime) return sgItem, err } @@ -441,7 +446,7 @@ func socialgroups_member_list(w http.ResponseWriter, r *http.Request, user User) var sgItem SocialGroup = SocialGroup{ID:sgid} var mainForum int // Unused - err = socialgroups_get_group_stmt.QueryRow(sgid).Scan(&sgItem.Name, &sgItem.Desc, &sgItem.Active, &sgItem.Privacy, &sgItem.Owner, &sgItem.MemberCount, &mainForum, &sgItem.Backdrop, &sgItem.CreatedAt, &sgItem.LastUpdateTime) + err = socialgroups_get_group_stmt.QueryRow(sgid).Scan(&sgItem.Name, &sgItem.Desc, &sgItem.Active, &sgItem.Privacy, &sgItem.Joinable, &sgItem.Owner, &sgItem.MemberCount, &mainForum, &sgItem.Backdrop, &sgItem.CreatedAt, &sgItem.LastUpdateTime) if err != nil { LocalError("Bad group",w,r,user) return @@ -470,7 +475,7 @@ func socialgroups_member_list(w http.ResponseWriter, r *http.Request, user User) sgMember.User.Avatar = "/uploads/avatar_" + strconv.Itoa(sgMember.User.ID) + sgMember.User.Avatar } } else { - sgMember.User.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(sgMember.User.ID),1) + sgMember.User.Avatar = strings.Replace(config.Noavatar,"{id}",strconv.Itoa(sgMember.User.ID),1) } sgMember.JoinedAt, _ = relative_time(sgMember.JoinedAt) if sgItem.Owner == sgMember.User.ID { diff --git a/query_gen/lib/mysql.go b/query_gen/lib/mysql.go index 79536ff1..e3739d73 100644 --- a/query_gen/lib/mysql.go +++ b/query_gen/lib/mysql.go @@ -839,7 +839,7 @@ import "database/sql" ` + stmts + ` func _gen_mysql() (err error) { - if debug_mode { + if dev.DebugMode { log.Print("Building the generated statements") } ` + body + ` diff --git a/query_gen/lib/pgsql.go b/query_gen/lib/pgsql.go index 2010098a..71c2d6b5 100644 --- a/query_gen/lib/pgsql.go +++ b/query_gen/lib/pgsql.go @@ -164,7 +164,14 @@ func (adapter *Pgsql_Adapter) SimpleUpdate(name string, table string, set string for _, loc := range _process_where(where) { for _, token := range loc.Expr { switch(token.Type) { - case "function","operator","number","substitute": + 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()" { + token.Contents = "LOCALTIMESTAMP()" + } + querystr += " " + token.Contents + "" + case "operator","number","substitute": querystr += " " + token.Contents + "" case "column": querystr += " `" + token.Contents + "`" @@ -316,7 +323,7 @@ import "database/sql" ` + stmts + ` func _gen_pgsql() (err error) { - if debug_mode { + if dev.DebugMode { log.Print("Building the generated statements") } ` + body + ` diff --git a/query_gen/main.go b/query_gen/main.go index 032d1084..6ac7b1f6 100644 --- a/query_gen/main.go +++ b/query_gen/main.go @@ -109,6 +109,7 @@ func create_tables(adapter qgen.DB_Adapter) error { qgen.DB_Table_Column{"bigposts","int",0,false,false,"0"}, qgen.DB_Table_Column{"megaposts","int",0,false,false,"0"}, qgen.DB_Table_Column{"topics","int",0,false,false,"0"}, + //qgen.DB_Table_Column{"penalty_count","int",0,false,false,"0"}, }, []qgen.DB_Table_Key{ qgen.DB_Table_Key{"uid","primary"}, @@ -116,6 +117,34 @@ func create_tables(adapter qgen.DB_Adapter) error { }, ) + // What should we do about global penalties? Put them on the users table for speed? Or keep them here? + // Should we add IP Penalties? + qgen.Install.CreateTable("users_penalties","","", + []qgen.DB_Table_Column{ + qgen.DB_Table_Column{"uid","int",0,false,false,""}, + qgen.DB_Table_Column{"element_id","int",0,false,false,""}, + qgen.DB_Table_Column{"element_type","varchar",50,false,false,""}, //global,forum,profile?,social_group + qgen.DB_Table_Column{"overrides","text",0,false,false,"{}"}, // Perm overrides. Coming Soon + qgen.DB_Table_Column{"mod_queue","boolean",0,false,false,"0"}, // All of this user's posts will go through the mod_queue. Coming Soon + // TO-DO: Add a mod-queue and other basic auto-mod features. This is needed for awaiting activation and the mod_queue penalty flag + // TO-DO: Add a penalty type where a user is stopped from creating plugin_socialgroups social groups + + qgen.DB_Table_Column{"shadow_ban","boolean",0,false,false,"0"}, // Coming Soon. CanShadowBan permission. + qgen.DB_Table_Column{"no_avatar","boolean",0,false,false,"0"}, // Coming Soon. Should this be a perm override instead? + + //qgen.DB_Table_Column{"posts_per_hour","int",0,false,false,"0"}, // Rate-limit penalty type. Coming soon + //qgen.DB_Table_Column{"topics_per_hour","int",0,false,false,"0"}, // Coming Soon + + //qgen.DB_Table_Column{"posts_count","int",0,false,false,"0"}, // Coming soon + //qgen.DB_Table_Column{"topic_count","int",0,false,false,"0"}, // Coming Soon + //qgen.DB_Table_Column{"last_hour","int",0,false,false,"0"}, // UNIX Time, as we don't need to do anything too fancy here. When an hour has elapsed since that time, reset the hourly penalty counters. + qgen.DB_Table_Column{"issued_by","int",0,false,false,""}, + qgen.DB_Table_Column{"issued_at","createdAt",0,false,false,""}, + qgen.DB_Table_Column{"expiry","duration",0,false,false,""}, // TO-DO: Implement the duration parsing code on the adapter side + }, + []qgen.DB_Table_Key{}, + ) + return nil } @@ -224,11 +253,11 @@ 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","?,?,?,?,NOW(),NOW(),?,?,?") + adapter.SimpleInsert("create_topic","topics","parentID,title,content,parsed_content,createdAt,lastReplyAt,ipaddress,words,createdBy","?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?") - adapter.SimpleInsert("create_report","topics","title,content,parsed_content,createdAt,lastReplyAt,createdBy,data,parentID,css_class","?,?,?,NOW(),NOW(),?,?,1,'report'") + adapter.SimpleInsert("create_report","topics","title,content,parsed_content,createdAt,lastReplyAt,createdBy,data,parentID,css_class","?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,1,'report'") - adapter.SimpleInsert("create_reply","replies","tid,content,parsed_content,createdAt,ipaddress,words,createdBy","?,?,?,NOW(),?,?,?") + adapter.SimpleInsert("create_reply","replies","tid,content,parsed_content,createdAt,ipaddress,words,createdBy","?,?,?,UTC_TIMESTAMP(),?,?,?") adapter.SimpleInsert("create_action_reply","replies","tid,actionType,ipaddress,createdBy","?,?,?,?") @@ -240,7 +269,7 @@ func write_inserts(adapter qgen.DB_Adapter) error { adapter.SimpleInsert("add_email","emails","email, uid, validated, token","?,?,?,?") - adapter.SimpleInsert("create_profile_reply","users_replies","uid, content, parsed_content, createdAt, createdBy, ipaddress","?,?,?,NOW(),?,?") + adapter.SimpleInsert("create_profile_reply","users_replies","uid, content, parsed_content, createdAt, createdBy, ipaddress","?,?,?,UTC_TIMESTAMP(),?,?") adapter.SimpleInsert("add_subscription","activity_subscriptions","user,targetID,targetType,level","?,?,?,2") @@ -255,9 +284,9 @@ func write_inserts(adapter qgen.DB_Adapter) error { adapter.SimpleInsert("create_group","users_groups","name, tag, is_admin, is_mod, is_banned, permissions","?,?,?,?,?,?") - adapter.SimpleInsert("add_modlog_entry","moderation_logs","action, elementID, elementType, ipaddress, actorID, doneAt","?,?,?,?,?,NOW()") + adapter.SimpleInsert("add_modlog_entry","moderation_logs","action, elementID, elementType, ipaddress, actorID, doneAt","?,?,?,?,?,UTC_TIMESTAMP()") - adapter.SimpleInsert("add_adminlog_entry","administration_logs","action, elementID, elementType, ipaddress, actorID, doneAt","?,?,?,?,?,NOW()") + adapter.SimpleInsert("add_adminlog_entry","administration_logs","action, elementID, elementType, ipaddress, actorID, doneAt","?,?,?,?,?,UTC_TIMESTAMP()") return nil } @@ -269,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 = NOW()","tid = ?") + adapter.SimpleUpdate("add_replies_to_topic","topics","postCount = postCount + ?, lastReplyAt = UTC_TIMESTAMP()","tid = ?") adapter.SimpleUpdate("remove_replies_from_topic","topics","postCount = postCount - ?","tid = ?") @@ -277,7 +306,7 @@ func write_updates(adapter qgen.DB_Adapter) error { adapter.SimpleUpdate("remove_topics_from_forum","forums","topicCount = topicCount - ?","fid = ?") - adapter.SimpleUpdate("update_forum_cache","forums","lastTopic = ?, lastTopicID = ?, lastReplyer = ?, lastReplyerID = ?, lastTopicTime = NOW()","fid = ?") + adapter.SimpleUpdate("update_forum_cache","forums","lastTopic = ?, lastTopicID = ?, lastReplyer = ?, lastReplyerID = ?, lastTopicTime = UTC_TIMESTAMP()","fid = ?") adapter.SimpleUpdate("add_likes_to_topic","topics","likeCount = likeCount + ?","tid = ?") diff --git a/reply.go b/reply.go index a270fb01..8327864e 100644 --- a/reply.go +++ b/reply.go @@ -1,6 +1,5 @@ /* Copyright Azareal 2016 - 2017 */ package main -import "html/template" // Should we add a reply store to centralise all the reply logic? Would this cover profile replies too or would that be seperate? @@ -18,7 +17,7 @@ type Reply struct /* Should probably rename this to ReplyUser and rename ReplySh LastEdit int LastEditBy int Avatar string - Css template.CSS + ClassName string ContentLines int Tag string URL string diff --git a/router_gen/main.go b/router_gen/main.go index 577a917e..9c6f126d 100644 --- a/router_gen/main.go +++ b/router_gen/main.go @@ -80,7 +80,7 @@ func main() { fdata += `package main -//import "fmt" +import "fmt" import "strings" import "sync" import "errors" @@ -150,12 +150,20 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } + if dev.SuperDebug { + fmt.Println("before PreRoute") + } + // Deal with the session stuff, etc. user, ok := PreRoute(w,req) if !ok { return } + if dev.SuperDebug { + fmt.Println("after PreRoute") + } + switch(prefix) {` + out + ` case "/uploads": if extra_data == "" { @@ -166,7 +174,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { router.UploadHandler(w,req) return case "": - default_route(w,req,user) + config.DefaultRoute(w,req,user) return //default: NotFound(w,req) } diff --git a/routes.go b/routes.go index c8e683fb..dc97e697 100644 --- a/routes.go +++ b/routes.go @@ -14,7 +14,6 @@ import ( "net" "net/http" "html" - "html/template" "./query_gen/lib" ) @@ -26,6 +25,10 @@ var hvars HeaderVars var extData ExtData var success_json_bytes []byte = []byte(`{"success":"1"}`) +func init() { + hvars.Site = site +} + // GET functions func route_static(w http.ResponseWriter, r *http.Request){ //log.Print("Outputting static file '" + r.URL.Path + "'") @@ -160,7 +163,7 @@ func route_topics(w http.ResponseWriter, r *http.Request, user User){ topicItem.Avatar = "/uploads/avatar_" + strconv.Itoa(topicItem.CreatedBy) + topicItem.Avatar } } else { - topicItem.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(topicItem.CreatedBy),1) + topicItem.Avatar = strings.Replace(config.Noavatar,"{id}",strconv.Itoa(topicItem.CreatedBy),1) } forum := fstore.DirtyGet(topicItem.ParentID) @@ -251,16 +254,16 @@ func route_forum(w http.ResponseWriter, r *http.Request, user User, sfid string) // Calculate the offset var offset int - last_page := int(forum.TopicCount / items_per_page) + 1 + last_page := int(forum.TopicCount / config.ItemsPerPage) + 1 if page > 1 { - offset = (items_per_page * page) - items_per_page + offset = (config.ItemsPerPage * page) - config.ItemsPerPage } else if page == -1 { page = last_page - offset = (items_per_page * page) - items_per_page + offset = (config.ItemsPerPage * page) - config.ItemsPerPage } else { page = 1 } - rows, err := get_forum_topics_offset_stmt.Query(fid,offset,items_per_page) + rows, err := get_forum_topics_offset_stmt.Query(fid,offset,config.ItemsPerPage) if err != nil { InternalError(err,w,r) return @@ -283,7 +286,7 @@ func route_forum(w http.ResponseWriter, r *http.Request, user User, sfid string) topicItem.Avatar = "/uploads/avatar_" + strconv.Itoa(topicItem.CreatedBy) + topicItem.Avatar } } else { - topicItem.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(topicItem.CreatedBy),1) + topicItem.Avatar = strings.Replace(config.Noavatar,"{id}",strconv.Itoa(topicItem.CreatedBy),1) } topicItem.LastReplyAt, err = relative_time(topicItem.LastReplyAt) @@ -416,7 +419,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request, user User){ InternalError(err,w,r) return } - topic.Css = no_css_tmpl + topic.ClassName = "" headerVars, ok := ForumSessionCheck(w,r,&user,topic.ParentID) if !ok { @@ -440,7 +443,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request, user User){ topic.Tag = groups[topic.Group].Tag if groups[topic.Group].Is_Mod || groups[topic.Group].Is_Admin { - topic.Css = staff_css_tmpl + topic.ClassName = config.StaffCss } /*if settings["url_tags"] == false { @@ -460,18 +463,18 @@ func route_topic_id(w http.ResponseWriter, r *http.Request, user User){ } // Calculate the offset - last_page := int(topic.PostCount / items_per_page) + 1 + last_page := int(topic.PostCount / config.ItemsPerPage) + 1 if page > 1 { - offset = (items_per_page * page) - items_per_page + offset = (config.ItemsPerPage * page) - config.ItemsPerPage } else if page == -1 { page = last_page - offset = (items_per_page * page) - items_per_page + offset = (config.ItemsPerPage * page) - config.ItemsPerPage } else { page = 1 } // Get the replies.. - rows, err := get_topic_replies_offset_stmt.Query(topic.ID, offset, items_per_page) + rows, err := get_topic_replies_offset_stmt.Query(topic.ID, offset, config.ItemsPerPage) if err == ErrNoRows { LocalError("Bad Page. Some of the posts may have been deleted or you got here by directly typing in the page number.",w,r,user) return @@ -480,7 +483,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request, user User){ return } - replyItem := Reply{Css: no_css_tmpl} + replyItem := Reply{ClassName:""} for rows.Next() { err := rows.Scan(&replyItem.ID, &replyItem.Content, &replyItem.CreatedBy, &replyItem.CreatedAt, &replyItem.LastEdit, &replyItem.LastEditBy, &replyItem.Avatar, &replyItem.CreatedByName, &replyItem.Group, &replyItem.URLPrefix, &replyItem.URLName, &replyItem.Level, &replyItem.IpAddress, &replyItem.LikeCount, &replyItem.ActionType) if err != nil { @@ -494,9 +497,9 @@ func route_topic_id(w http.ResponseWriter, r *http.Request, user User){ replyItem.ContentLines = strings.Count(replyItem.Content,"\n") if groups[replyItem.Group].Is_Mod || groups[replyItem.Group].Is_Admin { - replyItem.Css = staff_css_tmpl + replyItem.ClassName = config.StaffCss } else { - replyItem.Css = no_css_tmpl + replyItem.ClassName = "" } if replyItem.Avatar != "" { @@ -504,7 +507,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request, user User){ replyItem.Avatar = "/uploads/avatar_" + strconv.Itoa(replyItem.CreatedBy) + replyItem.Avatar } } else { - replyItem.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(replyItem.CreatedBy),1) + replyItem.Avatar = strings.Replace(config.Noavatar,"{id}",strconv.Itoa(replyItem.CreatedBy),1) } replyItem.Tag = groups[replyItem.Group].Tag @@ -588,9 +591,8 @@ func route_profile(w http.ResponseWriter, r *http.Request, user User){ } var err error - var replyContent, replyCreatedByName, replyCreatedAt, replyAvatar, replyTag string + var replyContent, replyCreatedByName, replyCreatedAt, replyAvatar, replyTag, replyClassName string var rid, replyCreatedBy, replyLastEdit, replyLastEditBy, replyLines, replyGroup int - var replyCss template.CSS var replyList []Reply // SEO URLs... @@ -638,16 +640,16 @@ func route_profile(w http.ResponseWriter, r *http.Request, user User){ replyLines = strings.Count(replyContent,"\n") if groups[replyGroup].Is_Mod || groups[replyGroup].Is_Admin { - replyCss = staff_css_tmpl + replyClassName = config.StaffCss } else { - replyCss = no_css_tmpl + replyClassName = "" } if replyAvatar != "" { if replyAvatar[0] == '.' { replyAvatar = "/uploads/avatar_" + strconv.Itoa(replyCreatedBy) + replyAvatar } } else { - replyAvatar = strings.Replace(noavatar,"{id}",strconv.Itoa(replyCreatedBy),1) + replyAvatar = strings.Replace(config.Noavatar,"{id}",strconv.Itoa(replyCreatedBy),1) } if groups[replyGroup].Tag != "" { @@ -663,7 +665,7 @@ func route_profile(w http.ResponseWriter, r *http.Request, user User){ // TO-DO: Add a hook here - replyList = append(replyList, Reply{rid,puser.ID,replyContent,parse_message(replyContent),replyCreatedBy,name_to_slug(replyCreatedByName),replyCreatedByName,replyGroup,replyCreatedAt,replyLastEdit,replyLastEditBy,replyAvatar,replyCss,replyLines,replyTag,"","","",0,"",replyLiked,replyLikeCount,"",""}) + replyList = append(replyList, Reply{rid,puser.ID,replyContent,parse_message(replyContent),replyCreatedBy,name_to_slug(replyCreatedByName),replyCreatedByName,replyGroup,replyCreatedAt,replyLastEdit,replyLastEditBy,replyAvatar,replyClassName,replyLines,replyTag,"","","",0,"",replyLiked,replyLikeCount,"",""}) } err = rows.Err() if err != nil { @@ -1405,11 +1407,11 @@ func route_account_own_edit_avatar(w http.ResponseWriter, r *http.Request, user } func route_account_own_edit_avatar_submit(w http.ResponseWriter, r *http.Request, user User) { - if r.ContentLength > int64(max_request_size) { + if r.ContentLength > int64(config.MaxRequestSize) { http.Error(w,"Request too large",http.StatusExpectationFailed) return } - r.Body = http.MaxBytesReader(w, r.Body, int64(max_request_size)) + r.Body = http.MaxBytesReader(w, r.Body, int64(config.MaxRequestSize)) headerVars, ok := SessionCheck(w,r,&user) if !ok { @@ -1420,7 +1422,7 @@ func route_account_own_edit_avatar_submit(w http.ResponseWriter, r *http.Request return } - err := r.ParseMultipartForm(int64(max_request_size)) + err := r.ParseMultipartForm(int64(config.MaxRequestSize)) if err != nil { LocalError("Upload failed",w,r,user) return @@ -1594,7 +1596,7 @@ func route_account_own_edit_email(w http.ResponseWriter, r *http.Request, user U } // Was this site migrated from another forum software? Most of them don't have multiple emails for a single user. - // This also applies when the admin switches enable_emails on after having it off for a while. + // This also applies when the admin switches site.EnableEmails on after having it off for a while. if len(emailList) == 0 { email.Email = user.Email email.Validated = false @@ -1602,7 +1604,7 @@ func route_account_own_edit_email(w http.ResponseWriter, r *http.Request, user U emailList = append(emailList, email) } - if !enable_emails { + if !site.EnableEmails { headerVars.NoticeList = append(headerVars.NoticeList,"The mail system is currently disabled.") } pi := Page{"Email Manager",user,headerVars,emailList,nil} @@ -1680,7 +1682,7 @@ func route_account_own_edit_email_token_submit(w http.ResponseWriter, r *http.Re } } - if !enable_emails { + if !site.EnableEmails { headerVars.NoticeList = append(headerVars.NoticeList,"The mail system is currently disabled.") } headerVars.NoticeList = append(headerVars.NoticeList,"Your email was successfully verified") @@ -1823,9 +1825,9 @@ func route_register_submit(w http.ResponseWriter, r *http.Request, user User) { switch settings["activation_type"] { case 1: // Activate All active = 1 - group = default_group + group = config.DefaultGroup default: // Anything else. E.g. Admin Activation or Email Activation. - group = activation_group + group = config.ActivationGroup } uid, err := users.CreateUser(username, password, email, group, active) @@ -1838,7 +1840,7 @@ func route_register_submit(w http.ResponseWriter, r *http.Request, user User) { } // Check if this user actually owns this email, if email activation is on, automatically flip their account to active when the email is validated. Validation is also useful for determining whether this user should receive any alerts, etc. via email - if enable_emails { + if site.EnableEmails { token, err := GenerateSafeString(80) if err != nil { InternalError(err,w,r) diff --git a/schema/mysql/query_users_penalties.sql b/schema/mysql/query_users_penalties.sql new file mode 100644 index 00000000..98dc6d27 --- /dev/null +++ b/schema/mysql/query_users_penalties.sql @@ -0,0 +1,12 @@ +CREATE TABLE `users_penalties` ( + `uid` int not null, + `element_id` int not null, + `element_type` varchar(50) not null, + `overrides` text not null, + `mod_queue` boolean DEFAULT 0 not null, + `shadow_ban` boolean DEFAULT 0 not null, + `no_avatar` boolean DEFAULT 0 not null, + `issued_by` int not null, + `issued_at` datetime not null, + `expiry` duration not null +); \ No newline at end of file diff --git a/schema/pgsql/query_users_penalties.sql b/schema/pgsql/query_users_penalties.sql new file mode 100644 index 00000000..600639f5 --- /dev/null +++ b/schema/pgsql/query_users_penalties.sql @@ -0,0 +1,12 @@ +CREATE TABLE `users_penalties` ( + `uid` int not null, + `element_id` int not null, + `element_type` varchar (50) not null, + `overrides` text DEFAULT '{}' not null, + `mod_queue` boolean DEFAULT 0 not null, + `shadow_ban` boolean DEFAULT 0 not null, + `no_avatar` boolean DEFAULT 0 not null, + `issued_by` int not null, + `issued_at` timestamp not null, + `expiry` duration not null +); \ No newline at end of file diff --git a/site.go b/site.go new file mode 100644 index 00000000..56d39b04 --- /dev/null +++ b/site.go @@ -0,0 +1,61 @@ +package main + +import "net/http" + +var site *Site = &Site{Name:"Magical Fairy Land"} +var db_config DB_Config = DB_Config{Host:"localhost"} +var config Config +var dev DevConfig + +type Site struct +{ + Name string + Email string + Url string + Port string + EnableSsl bool + EnableEmails bool +} + +type DB_Config struct +{ + Host string + Username string + Password string + Dbname string + Port string +} + +type Config struct +{ + SslPrivkey string + SslFullchain string + + MaxRequestSize int + CacheTopicUser int + UserCacheCapacity int + TopicCacheCapacity int + + SmtpServer string + SmtpUsername string + SmtpPassword string + SmtpPort string + + DefaultRoute func(http.ResponseWriter, *http.Request, User) + DefaultGroup int + ActivationGroup int + StaffCss string + UncategorisedForumVisible bool + MinifyTemplates bool + MultiServer bool + + Noavatar string + ItemsPerPage int +} + +type DevConfig struct +{ + DebugMode bool + SuperDebug bool + Profiling bool +} diff --git a/template_forum.go b/template_forum.go index 382fd12d..0ec937c9 100644 --- a/template_forum.go +++ b/template_forum.go @@ -2,8 +2,8 @@ /* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */ // +build !no_templategen package main -import "strconv" import "io" +import "strconv" func init() { template_forum_handle = template_forum @@ -36,22 +36,24 @@ w.Write(header_7) w.Write([]byte(tmpl_forum_vars.CurrentUser.Session)) w.Write(header_8) w.Write(menu_0) -if tmpl_forum_vars.CurrentUser.Loggedin { +w.Write([]byte(tmpl_forum_vars.Header.Site.Name)) w.Write(menu_1) -w.Write([]byte(tmpl_forum_vars.CurrentUser.Slug)) +if tmpl_forum_vars.CurrentUser.Loggedin { w.Write(menu_2) -w.Write([]byte(strconv.Itoa(tmpl_forum_vars.CurrentUser.ID))) +w.Write([]byte(tmpl_forum_vars.CurrentUser.Slug)) w.Write(menu_3) -if tmpl_forum_vars.CurrentUser.Is_Super_Mod { +w.Write([]byte(strconv.Itoa(tmpl_forum_vars.CurrentUser.ID))) w.Write(menu_4) -} +if tmpl_forum_vars.CurrentUser.Is_Super_Mod { w.Write(menu_5) -w.Write([]byte(tmpl_forum_vars.CurrentUser.Session)) -w.Write(menu_6) -} else { -w.Write(menu_7) } +w.Write(menu_6) +w.Write([]byte(tmpl_forum_vars.CurrentUser.Session)) +w.Write(menu_7) +} else { w.Write(menu_8) +} +w.Write(menu_9) w.Write(header_9) if tmpl_forum_vars.Header.Widgets.RightSidebar != "" { w.Write(header_10) @@ -92,13 +94,13 @@ w.Write(forum_11) if tmpl_forum_vars.CurrentUser.ID != 0 { if tmpl_forum_vars.CurrentUser.Perms.CreateTopic { w.Write(forum_12) -} else { +w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID))) w.Write(forum_13) -} +} else { w.Write(forum_14) } w.Write(forum_15) -w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID))) +} w.Write(forum_16) if len(tmpl_forum_vars.ItemList) != 0 { for _, item := range tmpl_forum_vars.ItemList { diff --git a/template_forums.go b/template_forums.go index 2f5eae73..2b3a1111 100644 --- a/template_forums.go +++ b/template_forums.go @@ -36,22 +36,24 @@ w.Write(header_7) w.Write([]byte(tmpl_forums_vars.CurrentUser.Session)) w.Write(header_8) w.Write(menu_0) -if tmpl_forums_vars.CurrentUser.Loggedin { +w.Write([]byte(tmpl_forums_vars.Header.Site.Name)) w.Write(menu_1) -w.Write([]byte(tmpl_forums_vars.CurrentUser.Slug)) +if tmpl_forums_vars.CurrentUser.Loggedin { w.Write(menu_2) -w.Write([]byte(strconv.Itoa(tmpl_forums_vars.CurrentUser.ID))) +w.Write([]byte(tmpl_forums_vars.CurrentUser.Slug)) w.Write(menu_3) -if tmpl_forums_vars.CurrentUser.Is_Super_Mod { +w.Write([]byte(strconv.Itoa(tmpl_forums_vars.CurrentUser.ID))) w.Write(menu_4) -} +if tmpl_forums_vars.CurrentUser.Is_Super_Mod { w.Write(menu_5) -w.Write([]byte(tmpl_forums_vars.CurrentUser.Session)) -w.Write(menu_6) -} else { -w.Write(menu_7) } +w.Write(menu_6) +w.Write([]byte(tmpl_forums_vars.CurrentUser.Session)) +w.Write(menu_7) +} else { w.Write(menu_8) +} +w.Write(menu_9) w.Write(header_9) if tmpl_forums_vars.Header.Widgets.RightSidebar != "" { w.Write(header_10) @@ -81,36 +83,28 @@ w.Write(forums_6) w.Write([]byte(item.Desc)) w.Write(forums_7) } else { -if item.LastTopicTime != "" { w.Write(forums_8) w.Write([]byte(item.Link)) w.Write(forums_9) w.Write([]byte(item.Name)) w.Write(forums_10) -} else { +} w.Write(forums_11) -w.Write([]byte(item.Link)) -w.Write(forums_12) -w.Write([]byte(item.Name)) -w.Write(forums_13) -} -} -w.Write(forums_14) w.Write([]byte(item.LastTopicSlug)) -w.Write(forums_15) +w.Write(forums_12) w.Write([]byte(item.LastTopic)) -w.Write(forums_16) +w.Write(forums_13) if item.LastTopicTime != "" { -w.Write(forums_17) +w.Write(forums_14) w.Write([]byte(item.LastTopicTime)) -w.Write(forums_18) +w.Write(forums_15) } -w.Write(forums_19) +w.Write(forums_16) } } else { -w.Write(forums_20) +w.Write(forums_17) } -w.Write(forums_21) +w.Write(forums_18) w.Write(footer_0) if tmpl_forums_vars.Header.Widgets.RightSidebar != "" { w.Write(footer_1) diff --git a/template_list.go b/template_list.go index 68831fb6..99cf4efe 100644 --- a/template_list.go +++ b/template_list.go @@ -32,30 +32,32 @@ var menu_0 []byte = []byte(`