Added friendly URLs.

Added the Forum Store. Rewrote all the forum slice calls to use it.

Remapped sql.ErrNoRows to ErrNoRows for portability.
Removed a pointless column in the login query.
Revamped the tags and buttons on Tempra Simple, and on the profiles for the other themes.
Fixed a padding bug.
Tweaked the font sizes and padding in the Control Panel for Tempra Simple.
More progress with widgets.
This commit is contained in:
Azareal 2017-06-28 13:05:26 +01:00
parent 21d623cba4
commit 9a93f799bf
43 changed files with 1276 additions and 941 deletions

View File

@ -4,7 +4,6 @@ import "log"
import "strings" import "strings"
import "strconv" import "strconv"
import "errors" import "errors"
import "database/sql"
/* /*
"You received a friend invite from {user}" "You received a friend invite from {user}"
@ -37,7 +36,7 @@ func build_alert(event string, elementType string, actor_id int, targetUser_id i
}*/ }*/
if event == "friend_invite" { if event == "friend_invite" {
return `{"msg":"You received a friend invite from {0}","sub":["` + actor.Name + `"],"path":"\/user\/`+strconv.Itoa(actor.ID)+`","avatar":"`+strings.Replace(actor.Avatar,"/","\\/",-1)+`"}`, nil return `{"msg":"You received a friend invite from {0}","sub":["` + actor.Name + `"],"path":"\/user\/`+actor.Slug+`.`+strconv.Itoa(actor.ID)+`","avatar":"`+strings.Replace(actor.Avatar,"/","\\/",-1)+`"}`, nil
} }
var act, post_act, url, area string var act, post_act, url, area string
@ -50,7 +49,7 @@ func build_alert(event string, elementType string, actor_id int, targetUser_id i
if err != nil { if err != nil {
return "", errors.New("Unable to find the linked topic") return "", errors.New("Unable to find the linked topic")
} }
url = build_topic_url(elementID) url = build_topic_url(topic.Slug,elementID)
area = topic.Title area = topic.Title
// Store the forum ID in the targetUser column instead of making a new one? o.O // Store the forum ID in the targetUser column instead of making a new one? o.O
// Add an additional column for extra information later on when we add the ability to link directly to posts. We don't need the forum data for now... // Add an additional column for extra information later on when we add the ability to link directly to posts. We don't need the forum data for now...
@ -62,7 +61,7 @@ func build_alert(event string, elementType string, actor_id int, targetUser_id i
if err != nil { if err != nil {
return "", errors.New("Unable to find the linked topic") return "", errors.New("Unable to find the linked topic")
} }
url = build_topic_url(elementID) url = build_topic_url(topic.Slug,elementID)
area = topic.Title area = topic.Title
if targetUser_id == user.ID { if targetUser_id == user.ID {
@ -75,13 +74,13 @@ func build_alert(event string, elementType string, actor_id int, targetUser_id i
} }
area = targetUser.Name area = targetUser.Name
end_frag = "'s profile" end_frag = "'s profile"
url = build_profile_url(elementID) url = build_profile_url(targetUser.Slug,elementID)
case "post": case "post":
topic, err := get_topic_by_reply(elementID) topic, err := get_topic_by_reply(elementID)
if err != nil { if err != nil {
return "", errors.New("Unable to find the linked reply or parent topic") return "", errors.New("Unable to find the linked reply or parent topic")
} }
url = build_topic_url(topic.ID) url = build_topic_url(topic.Slug,topic.ID)
area = topic.Title area = topic.Title
if targetUser_id == user.ID { if targetUser_id == user.ID {
post_act = " your post in" post_act = " your post in"
@ -116,7 +115,7 @@ func build_alert(event string, elementType string, actor_id int, targetUser_id i
func notify_watchers(asid int64) { func notify_watchers(asid int64) {
rows, err := get_watchers_stmt.Query(asid) rows, err := get_watchers_stmt.Query(asid)
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
log.Fatal(err.Error()) log.Fatal(err.Error())
return return
} }
@ -141,7 +140,7 @@ func notify_watchers(asid int64) {
var actor_id, targetUser_id, elementID int var actor_id, targetUser_id, elementID int
var event, elementType string var event, elementType string
err = get_activity_entry_stmt.QueryRow(asid).Scan(&actor_id, &targetUser_id, &event, &elementType, &elementID) err = get_activity_entry_stmt.QueryRow(asid).Scan(&actor_id, &targetUser_id, &event, &elementType, &elementID)
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
log.Fatal(err.Error()) log.Fatal(err.Error())
return return
} }

View File

@ -29,7 +29,7 @@ type DefaultAuth struct
} }
func NewDefaultAuth() *DefaultAuth { func NewDefaultAuth() *DefaultAuth {
login_stmt, err := qgen.Builder.SimpleSelect("users","uid, name, password, salt","name = ?","","") login_stmt, err := qgen.Builder.SimpleSelect("users","uid, password, salt","name = ?","","")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -45,8 +45,8 @@ func NewDefaultAuth() *DefaultAuth {
func (auth *DefaultAuth) Authenticate(username string, password string) (uid int, err error) { func (auth *DefaultAuth) Authenticate(username string, password string) (uid int, err error) {
var real_password, salt string var real_password, salt string
err = auth.login.QueryRow(username).Scan(&uid, &username, &real_password, &salt) err = auth.login.QueryRow(username).Scan(&uid, &real_password, &salt)
if err == sql.ErrNoRows { if err == ErrNoRows {
return 0, errors.New("We couldn't find an account with that username.") return 0, errors.New("We couldn't find an account with that username.")
} else if err != nil { } else if err != nil {
LogError(err) LogError(err)

View File

@ -9,6 +9,8 @@ var db *sql.DB
var db_version string var db_version string
var db_collation string = "utf8mb4_general_ci" var db_collation string = "utf8mb4_general_ci"
var ErrNoRows = sql.ErrNoRows
func init_database() (err error) { func init_database() (err error) {
// Engine specific code // Engine specific code
err = _init_database() err = _init_database()
@ -61,7 +63,8 @@ func init_database() (err error) {
GuestPerms = groups[6].Perms GuestPerms = groups[6].Perms
log.Print("Loading the forums.") log.Print("Loading the forums.")
err = LoadForums() fstore = NewStaticForumStore()
err = fstore.LoadForums()
if err != nil { if err != nil {
return err return err
} }
@ -71,7 +74,7 @@ func init_database() (err error) {
if err != nil { if err != nil {
return err return err
} }
fstore = NewStaticForumStore()
log.Print("Loading the settings.") log.Print("Loading the settings.")
err = LoadSettings() err = LoadSettings()

View File

@ -8,7 +8,7 @@ var error_internal []byte
var error_notfound []byte var error_notfound []byte
func init_errors() error { func init_errors() error {
var b bytes.Buffer var b bytes.Buffer
user := User{0,"Guest","",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"0.0.0.0.0"} user := User{0,"guest","Guest","",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"0.0.0.0.0"}
pi := Page{"Internal Server Error",user,hvars,tList,"A problem has occurred in the system."} pi := Page{"Internal Server Error",user,hvars,tList,"A problem has occurred in the system."}
err := templates.ExecuteTemplate(&b,"error.html", pi) err := templates.ExecuteTemplate(&b,"error.html", pi)
if err != nil { if err != nil {

121
forum.go
View File

@ -1,10 +1,7 @@
package main package main
import "log"
//import "fmt" //import "fmt"
import "sync"
import "strconv" import "strconv"
import "database/sql"
import _ "github.com/go-sql-driver/mysql" import _ "github.com/go-sql-driver/mysql"
type ForumAdmin struct type ForumAdmin struct
@ -21,11 +18,13 @@ type ForumAdmin struct
type Forum struct type Forum struct
{ {
ID int ID int
Slug string
Name string Name string
Desc string Desc string
Active bool Active bool
Preset string Preset string
TopicCount int TopicCount int
LastTopicSlug string
LastTopic string LastTopic string
LastTopicID int LastTopicID int
LastReplyer string LastReplyer string
@ -41,117 +40,9 @@ type ForumSimple struct
Preset string Preset string
} }
func LoadForums() error { func build_forum_url(slug string, fid int) string {
//if debug { if slug == "" {
log.Print("Adding the uncategorised forum") return "/forum/" + strconv.Itoa(fid)
//}
forums = append(forums, Forum{0,"Uncategorised","",uncategorised_forum_visible,"all",0,"",0,"",0,""})
rows, err := get_forums_stmt.Query()
if err != nil {
return err
} }
defer rows.Close() return "/forum/" + slug + "." + strconv.Itoa(fid)
var i int = 1
for ;rows.Next();i++ {
forum := Forum{ID:0,Name:"",Active:true,Preset:"all"}
err = rows.Scan(&forum.ID, &forum.Name, &forum.Desc, &forum.Active, &forum.Preset, &forum.TopicCount, &forum.LastTopic, &forum.LastTopicID, &forum.LastReplyer, &forum.LastReplyerID, &forum.LastTopicTime)
if err != nil {
return err
}
// Ugh, you really shouldn't physically delete these items, it makes a big mess of things
if forum.ID != i {
log.Print("Stop physically deleting forums. You are messing up the IDs. Use the Forum Manager or delete_forum() instead x.x")
fill_forum_id_gap(i, forum.ID)
}
if forum.Name == "" {
if debug {
log.Print("Adding a placeholder forum")
}
} else {
log.Print("Adding the " + forum.Name + " forum")
}
forums = append(forums,forum)
}
err = rows.Err()
if err != nil {
return err
}
forumCapCount = i
return nil
}
var forum_update_mutex sync.Mutex
var forum_create_mutex sync.Mutex
func create_forum(forum_name string, forum_desc string, active bool, preset string) (int, error) {
var fid int
err := forum_entry_exists_stmt.QueryRow().Scan(&fid)
if err != nil && err != sql.ErrNoRows {
return 0, err
}
if err != sql.ErrNoRows {
forum_update_mutex.Lock()
_, err = update_forum_stmt.Exec(forum_name, forum_desc, active, preset, fid)
if err != nil {
return fid, err
}
forums[fid].Name = forum_name
forums[fid].Desc = forum_desc
forums[fid].Active = active
forums[fid].Preset = preset
forum_update_mutex.Unlock()
return fid, nil
}
forum_create_mutex.Lock()
res, err := create_forum_stmt.Exec(forum_name, forum_desc, active, preset)
if err != nil {
return 0, err
}
fid64, err := res.LastInsertId()
if err != nil {
return 0, err
}
fid = int(fid64)
forums = append(forums, Forum{fid,forum_name,forum_desc,active,preset,0,"",0,"",0,""})
forum_create_mutex.Unlock()
return fid, nil
}
func delete_forum(fid int) error {
forum_update_mutex.Lock()
_, err := delete_forum_stmt.Exec(fid)
if err != nil {
return err
}
forums[fid].Name = ""
forum_update_mutex.Unlock()
return nil
}
func get_forum(fid int) (forum *Forum, res bool) {
if !((fid <= forumCapCount) && (fid >= 0) && forums[fid].Name!="") {
return forum, false
}
return &forums[fid], true
}
func get_forum_copy(fid int) (forum Forum, res bool) {
if !((fid <= forumCapCount) && (fid >= 0) && forums[fid].Name != "") {
return forum, false
}
return forums[fid], true
}
func forum_exists(fid int) bool {
return (fid <= forumCapCount) && (fid >= 0) && forums[fid].Name != ""
}
func build_forum_url(fid int) string {
return "/forum/" + strconv.Itoa(fid)
} }

View File

@ -2,31 +2,44 @@
package main package main
import "log" import "log"
import "sync"
import "errors" import "errors"
import "database/sql" import "database/sql"
import "./query_gen/lib" import "./query_gen/lib"
var forums []Forum // The IDs for a forum tend to be low and sequential for the most part, so we can get more performance out of using a slice instead of a map AND it has better concurrency var forum_update_mutex sync.Mutex
var forum_create_mutex sync.Mutex
var forum_perms map[int]map[int]ForumPerms // [gid][fid]Perms var forum_perms map[int]map[int]ForumPerms // [gid][fid]Perms
var fstore ForumStore // :soon: var fstore ForumStore
var forumCapCount int
var err_noforum = errors.New("This forum doesn't exist") var err_noforum = errors.New("This forum doesn't exist")
type ForumStore interface type ForumStore interface
{ {
Get(int) (*Forum, error) LoadForums() error
CascadeGet(int) (*Forum, error) DirtyGet(id int) *Forum
BypassGet(int) (*Forum, error) Get(id int) (*Forum, error)
CascadeGet(id int) (*Forum, error)
CascadeGetCopy(id int) (Forum, error)
BypassGet(id int) (*Forum, error)
//Update(Forum) error //Update(Forum) error
//CascadeUpdate(Forum) error //CascadeUpdate(Forum) error
//Delete(int) error Delete(id int) error
//CascadeDelete(int) error CascadeDelete(id int) error
IncrementTopicCount(id int) error
DecrementTopicCount(id int) error
UpdateLastTopic(topic_name string, tid int, username string, uid int, time string, fid int) error
Exists(id int) bool
GetAll() ([]Forum,error)
CreateForum(forum_name string, forum_desc string, active bool, preset string) (int, error)
//QuickCreate(string, string, bool, string) (*Forum, error) //QuickCreate(string, string, bool, string) (*Forum, error)
Exists(int) bool
} }
type StaticForumStore struct type StaticForumStore struct
{ {
forums []Forum // The IDs for a forum tend to be low and sequential for the most part, so we can get more performance out of using a slice instead of a map AND it has better concurrency
forumCapCount int
get *sql.Stmt get *sql.Stmt
get_all *sql.Stmt get_all *sql.Stmt
} }
@ -46,18 +59,82 @@ func NewStaticForumStore() *StaticForumStore {
} }
} }
func (sfs *StaticForumStore) LoadForums() error {
//if debug {
log.Print("Adding the uncategorised forum")
//}
var forums []Forum = []Forum{
Forum{0,"uncategorised","Uncategorised","",uncategorised_forum_visible,"all",0,"","",0,"",0,""},
}
rows, err := get_forums_stmt.Query()
if err != nil {
return err
}
defer rows.Close()
var i int = 1
for ;rows.Next();i++ {
forum := Forum{ID:0,Active:true,Preset:"all"}
err = rows.Scan(&forum.ID, &forum.Name, &forum.Desc, &forum.Active, &forum.Preset, &forum.TopicCount, &forum.LastTopic, &forum.LastTopicID, &forum.LastReplyer, &forum.LastReplyerID, &forum.LastTopicTime)
if err != nil {
return err
}
// Ugh, you really shouldn't physically delete these items, it makes a big mess of things
if forum.ID != i {
log.Print("Stop physically deleting forums. You are messing up the IDs. Use the Forum Manager or delete_forum() instead x.x")
sfs.fill_forum_id_gap(i, forum.ID)
}
if forum.Name == "" {
if debug {
log.Print("Adding a placeholder forum")
}
} else {
log.Print("Adding the " + forum.Name + " forum")
}
forum.Slug = name_to_slug(forum.Name)
forum.LastTopicSlug = name_to_slug(forum.LastTopic)
forums = append(forums,forum)
}
err = rows.Err()
if err != nil {
return err
}
sfs.forums = forums
sfs.forumCapCount = i
return nil
}
func (sfs *StaticForumStore) DirtyGet(id int) *Forum {
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) { func (sfs *StaticForumStore) Get(id int) (*Forum, error) {
if !((id <= forumCapCount) && (id >= 0) && forums[id].Name!="") { if !((id <= sfs.forumCapCount) && (id >= 0) && sfs.forums[id].Name!="") {
return nil, err_noforum return nil, err_noforum
} }
return &forums[id], nil return &sfs.forums[id], nil
} }
func (sfs *StaticForumStore) CascadeGet(id int) (*Forum, error) { func (sfs *StaticForumStore) CascadeGet(id int) (*Forum, error) {
if !((id <= forumCapCount) && (id >= 0) && forums[id].Name!="") { if !((id <= sfs.forumCapCount) && (id >= 0) && sfs.forums[id].Name != "") {
return nil, err_noforum return nil, err_noforum
} }
return &forums[id], nil return &sfs.forums[id], nil
}
func (sfs *StaticForumStore) CascadeGetCopy(id int) (forum Forum, err error) {
if !((id <= sfs.forumCapCount) && (id >= 0) && sfs.forums[id].Name != "") {
return forum, err_noforum
}
return sfs.forums[id], nil
} }
func (sfs *StaticForumStore) BypassGet(id int) (*Forum, error) { func (sfs *StaticForumStore) BypassGet(id int) (*Forum, error) {
@ -70,5 +147,128 @@ func (sfs *StaticForumStore) BypassGet(id int) (*Forum, error) {
} }
func (sfs *StaticForumStore) Exists(id int) bool { func (sfs *StaticForumStore) Exists(id int) bool {
return (id <= forumCapCount) && (id >= 0) && forums[id].Name != "" return (id <= sfs.forumCapCount) && (id >= 0) && sfs.forums[id].Name != ""
}
func (sfs *StaticForumStore) GetAll() ([]Forum,error) {
return sfs.forums, nil
}
func (sfs *StaticForumStore) Delete(id int) error {
forum_update_mutex.Lock()
if !sfs.Exists(id) {
forum_update_mutex.Unlock()
return nil
}
sfs.forums[id].Name = ""
forum_update_mutex.Unlock()
return nil
}
func (sfs *StaticForumStore) CascadeDelete(id int) error {
forum, err := sfs.CascadeGet(id)
if err != nil {
return err
}
forum_update_mutex.Lock()
_, err = delete_forum_stmt.Exec(id)
if err != nil {
return err
}
forum.Name = ""
forum_update_mutex.Unlock()
return nil
}
func (sfs *StaticForumStore) IncrementTopicCount(id int) error {
forum, err := sfs.CascadeGet(id)
if err != nil {
return err
}
_, err = add_topics_to_forum_stmt.Exec(1,id)
if err != nil {
return err
}
forum.TopicCount += 1
return nil
}
func (sfs *StaticForumStore) DecrementTopicCount(id int) error {
forum, err := sfs.CascadeGet(id)
if err != nil {
return err
}
_, err = remove_topics_from_forum_stmt.Exec(1, id)
if err != nil {
return err
}
forum.TopicCount -= 1
return nil
}
// TO-DO: Have a pointer to the last topic rather than storing it on the forum itself
func (sfs *StaticForumStore) UpdateLastTopic(topic_name string, tid int, username string, uid int, time string, fid int) error {
forum, err := sfs.CascadeGet(fid)
if err != nil {
return err
}
_, err = update_forum_cache_stmt.Exec(topic_name,tid,username,uid,fid)
if err != nil {
return err
}
forum.LastTopic = topic_name
forum.LastTopicID = tid
forum.LastReplyer = username
forum.LastReplyerID = uid
forum.LastTopicTime = time
return nil
}
func (sfs *StaticForumStore) CreateForum(forum_name string, forum_desc string, active bool, preset string) (int, error) {
var fid int
err := forum_entry_exists_stmt.QueryRow().Scan(&fid)
if err != nil && err != ErrNoRows {
return 0, err
}
if err != ErrNoRows {
forum_update_mutex.Lock()
_, err = update_forum_stmt.Exec(forum_name, forum_desc, active, preset, fid)
if err != nil {
return fid, err
}
sfs.forums[fid].Name = forum_name
sfs.forums[fid].Desc = forum_desc
sfs.forums[fid].Active = active
sfs.forums[fid].Preset = preset
forum_update_mutex.Unlock()
return fid, nil
}
forum_create_mutex.Lock()
res, err := create_forum_stmt.Exec(forum_name, forum_desc, active, preset)
if err != nil {
return 0, err
}
fid64, err := res.LastInsertId()
if err != nil {
return 0, err
}
fid = int(fid64)
sfs.forums = append(sfs.forums, Forum{fid,name_to_slug(forum_name),forum_name,forum_desc,active,preset,0,"","",0,"",0,""})
sfs.forumCapCount++
forum_create_mutex.Unlock()
return fid, nil
}
func (sfs *StaticForumStore) fill_forum_id_gap(biggerID int, smallerID int) {
dummy := Forum{ID:0,Name:"",Active:false,Preset:"all"}
for i := smallerID; i > biggerID; i++ {
sfs.forums = append(sfs.forums, dummy)
}
} }

View File

@ -15,7 +15,7 @@ import (
"io/ioutil" "io/ioutil"
"database/sql" "database/sql"
"runtime/pprof" "runtime/pprof"
//_ "github.com/go-sql-driver/mysql" //_ "github.com/go-sql-driver/mysql"
//"github.com/erikstmartin/go-testdb" //"github.com/erikstmartin/go-testdb"
//"github.com/husobee/vestigo" //"github.com/husobee/vestigo"
@ -27,33 +27,33 @@ var gloinited bool = false
func gloinit() { func gloinit() {
debug = false debug = false
//nogrouplog = true //nogrouplog = true
// init_database is a little noisy for a benchmark // init_database is a little noisy for a benchmark
//discard := ioutil.Discard //discard := ioutil.Discard
//log.SetOutput(discard) //log.SetOutput(discard)
startTime = time.Now() startTime = time.Now()
timeLocation = startTime.Location() timeLocation = startTime.Location()
init_themes() init_themes()
err := init_database() err := init_database()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
db_prod = db db_prod = db
//db_test, err = sql.Open("testdb","") //db_test, err = sql.Open("testdb","")
//if err != nil { //if err != nil {
// log.Fatal(err) // log.Fatal(err)
//} //}
init_templates() init_templates()
db_prod.SetMaxOpenConns(64) db_prod.SetMaxOpenConns(64)
err = init_errors() err = init_errors()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
if cache_topicuser == CACHE_STATIC { if cache_topicuser == CACHE_STATIC {
users = NewMemoryUserStore(user_cache_capacity) users = NewMemoryUserStore(user_cache_capacity)
topics = NewMemoryTopicStore(topic_cache_capacity) topics = NewMemoryTopicStore(topic_cache_capacity)
@ -61,7 +61,7 @@ func gloinit() {
users = NewSqlUserStore() users = NewSqlUserStore()
topics = NewSqlTopicStore() topics = NewSqlTopicStore()
} }
init_static_files() init_static_files()
external_sites["YT"] = "https://www.youtube.com/" external_sites["YT"] = "https://www.youtube.com/"
hooks["trow_assign"] = nil hooks["trow_assign"] = nil
@ -76,13 +76,13 @@ func init() {
func BenchmarkTopicTemplateSerial(b *testing.B) { func BenchmarkTopicTemplateSerial(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"127.0.0.1"} user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"127.0.0.1"}
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58,"127.0.0.1"} admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58,"127.0.0.1"}
noticeList := []string{"test"} noticeList := []string{"test"}
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",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}
var replyList []Reply var replyList []Reply
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""}) replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""}) replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
@ -94,11 +94,11 @@ func BenchmarkTopicTemplateSerial(b *testing.B) {
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""}) replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""}) replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""}) replyList = append(replyList, Reply{0,0,"Hey everyone!","Hey everyone!",0,"",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
tpage := TopicPage{"Topic Blah",user,noticeList,replyList,topic,1,1,false} tpage := TopicPage{"Topic Blah",user,noticeList,replyList,topic,1,1,false}
tpage2 := TopicPage{"Topic Blah",admin,noticeList,replyList,topic,1,1,false} tpage2 := TopicPage{"Topic Blah",admin,noticeList,replyList,topic,1,1,false}
w := ioutil.Discard w := ioutil.Discard
b.Run("compiled_useradmin", func(b *testing.B) { b.Run("compiled_useradmin", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
template_topic(tpage2,w) template_topic(tpage2,w)
@ -119,7 +119,7 @@ func BenchmarkTopicTemplateSerial(b *testing.B) {
templates.ExecuteTemplate(w,"topic.html", tpage) templates.ExecuteTemplate(w,"topic.html", tpage)
} }
}) })
w2 := httptest.NewRecorder() w2 := httptest.NewRecorder()
b.Run("compiled_useradmin_recorder", func(b *testing.B) { b.Run("compiled_useradmin_recorder", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
@ -145,7 +145,7 @@ func BenchmarkTopicTemplateSerial(b *testing.B) {
templates.ExecuteTemplate(w2,"topic.html", tpage) templates.ExecuteTemplate(w2,"topic.html", tpage)
} }
}) })
/*f, err := os.Create("topic_bench.prof") /*f, err := os.Create("topic_bench.prof")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -156,11 +156,11 @@ func BenchmarkTopicTemplateSerial(b *testing.B) {
func BenchmarkTopicsTemplateSerial(b *testing.B) { func BenchmarkTopicsTemplateSerial(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"127.0.0.1"} user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"127.0.0.1"}
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58,"127.0.0.1"} admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58,"127.0.0.1"}
noticeList := []string{"test"} noticeList := []string{"test"}
var topicList []TopicsRow var topicList []TopicsRow
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
@ -172,11 +172,11 @@ func BenchmarkTopicsTemplateSerial(b *testing.B) {
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}) topicList = append(topicList, TopicsRow{Title: "Hey everyone!",Content: "Hey everyone!",CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
w := ioutil.Discard w := ioutil.Discard
tpage := TopicsPage{"Topic Blah",user,noticeList,topicList,nil} tpage := TopicsPage{"Topic Blah",user,noticeList,topicList,nil}
tpage2 := TopicsPage{"Topic Blah",admin,noticeList,topicList,nil} tpage2 := TopicsPage{"Topic Blah",admin,noticeList,topicList,nil}
b.Run("compiled_useradmin", func(b *testing.B) { b.Run("compiled_useradmin", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
template_topics(tpage2,w) template_topics(tpage2,w)
@ -207,7 +207,7 @@ func BenchmarkStaticRouteParallel(b *testing.B) {
if !plugins_inited { if !plugins_inited {
init_plugins() init_plugins()
} }
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
static_w := httptest.NewRecorder() static_w := httptest.NewRecorder()
static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil)) static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil))
@ -229,7 +229,7 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) {
if !gloinited { if !gloinited {
gloinit() gloinit()
} }
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
admin, err := users.CascadeGet(1) admin, err := users.CascadeGet(1)
if err != nil { if err != nil {
@ -240,14 +240,14 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) {
} }
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year} admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year}
topic_w := httptest.NewRecorder() topic_w := httptest.NewRecorder()
topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil)) topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil))
topic_req_admin := topic_req topic_req_admin := topic_req
topic_req_admin.AddCookie(&admin_uid_cookie) topic_req_admin.AddCookie(&admin_uid_cookie)
topic_req_admin.AddCookie(&admin_session_cookie) topic_req_admin.AddCookie(&admin_session_cookie)
topic_handler := http.HandlerFunc(route_topic_id) topic_handler := http.HandlerFunc(route_topic_id)
for pb.Next() { for pb.Next() {
topic_w.Body.Reset() topic_w.Body.Reset()
topic_handler.ServeHTTP(topic_w,topic_req_admin) topic_handler.ServeHTTP(topic_w,topic_req_admin)
@ -260,7 +260,7 @@ func BenchmarkTopicGuestRouteParallel(b *testing.B) {
if !gloinited { if !gloinited {
gloinit() gloinit()
} }
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
topic_w := httptest.NewRecorder() topic_w := httptest.NewRecorder()
topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil)) topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil))
@ -278,7 +278,7 @@ func BenchmarkForumsAdminRouteParallel(b *testing.B) {
if !gloinited { if !gloinited {
gloinit() gloinit()
} }
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
admin, err := users.CascadeGet(1) admin, err := users.CascadeGet(1)
if err != nil { if err != nil {
@ -289,14 +289,14 @@ func BenchmarkForumsAdminRouteParallel(b *testing.B) {
} }
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year} admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year}
forums_w := httptest.NewRecorder() forums_w := httptest.NewRecorder()
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil)) forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
forums_req_admin := forums_req forums_req_admin := forums_req
forums_req_admin.AddCookie(&admin_uid_cookie) forums_req_admin.AddCookie(&admin_uid_cookie)
forums_req_admin.AddCookie(&admin_session_cookie) forums_req_admin.AddCookie(&admin_session_cookie)
forums_handler := http.HandlerFunc(route_forums) forums_handler := http.HandlerFunc(route_forums)
for pb.Next() { for pb.Next() {
forums_w.Body.Reset() forums_w.Body.Reset()
forums_handler.ServeHTTP(forums_w,forums_req_admin) forums_handler.ServeHTTP(forums_w,forums_req_admin)
@ -309,7 +309,7 @@ func BenchmarkForumsAdminRouteParallelProf(b *testing.B) {
if !gloinited { if !gloinited {
gloinit() gloinit()
} }
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
admin, err := users.CascadeGet(1) admin, err := users.CascadeGet(1)
if err != nil { if err != nil {
@ -320,7 +320,7 @@ func BenchmarkForumsAdminRouteParallelProf(b *testing.B) {
} }
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path: "/",MaxAge: year} admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path: "/",MaxAge: year}
forums_w := httptest.NewRecorder() forums_w := httptest.NewRecorder()
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil)) forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
forums_req_admin := forums_req forums_req_admin := forums_req
@ -345,7 +345,7 @@ func BenchmarkForumsGuestRouteParallel(b *testing.B) {
if !gloinited { if !gloinited {
gloinit() gloinit()
} }
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
forums_w := httptest.NewRecorder() forums_w := httptest.NewRecorder()
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil)) forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
@ -367,49 +367,49 @@ func BenchmarkForumsGuestRouteParallel(b *testing.B) {
if !admin.Is_Admin { if !admin.Is_Admin {
panic("UID1 is not an admin") panic("UID1 is not an admin")
} }
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path: "/",MaxAge: year} admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path: "/",MaxAge: year}
if plugins_inited { if plugins_inited {
b.Log("Plugins have already been initialised, they can't be deinitialised so these tests will run with plugins on") b.Log("Plugins have already been initialised, they can't be deinitialised so these tests will run with plugins on")
} }
static_w := httptest.NewRecorder() static_w := httptest.NewRecorder()
static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil)) static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil))
static_handler := http.HandlerFunc(route_static) static_handler := http.HandlerFunc(route_static)
topic_w := httptest.NewRecorder() topic_w := httptest.NewRecorder()
topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil)) topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil))
topic_req_admin := topic_req topic_req_admin := topic_req
topic_req_admin.AddCookie(&admin_uid_cookie) topic_req_admin.AddCookie(&admin_uid_cookie)
topic_req_admin.AddCookie(&admin_session_cookie) topic_req_admin.AddCookie(&admin_session_cookie)
topic_handler := http.HandlerFunc(route_topic_id) topic_handler := http.HandlerFunc(route_topic_id)
topics_w := httptest.NewRecorder() topics_w := httptest.NewRecorder()
topics_req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil)) topics_req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil))
topics_req_admin := topics_req topics_req_admin := topics_req
topics_req_admin.AddCookie(&admin_uid_cookie) topics_req_admin.AddCookie(&admin_uid_cookie)
topics_req_admin.AddCookie(&admin_session_cookie) topics_req_admin.AddCookie(&admin_session_cookie)
topics_handler := http.HandlerFunc(route_topics) topics_handler := http.HandlerFunc(route_topics)
forum_w := httptest.NewRecorder() forum_w := httptest.NewRecorder()
forum_req := httptest.NewRequest("get","/forum/1",bytes.NewReader(nil)) forum_req := httptest.NewRequest("get","/forum/1",bytes.NewReader(nil))
forum_req_admin := forum_req forum_req_admin := forum_req
forum_req_admin.AddCookie(&admin_uid_cookie) forum_req_admin.AddCookie(&admin_uid_cookie)
forum_req_admin.AddCookie(&admin_session_cookie) forum_req_admin.AddCookie(&admin_session_cookie)
forum_handler := http.HandlerFunc(route_forum) forum_handler := http.HandlerFunc(route_forum)
forums_w := httptest.NewRecorder() forums_w := httptest.NewRecorder()
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil)) forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
forums_req_admin := forums_req forums_req_admin := forums_req
forums_req_admin.AddCookie(&admin_uid_cookie) forums_req_admin.AddCookie(&admin_uid_cookie)
forums_req_admin.AddCookie(&admin_session_cookie) forums_req_admin.AddCookie(&admin_session_cookie)
forums_handler := http.HandlerFunc(route_forums) forums_handler := http.HandlerFunc(route_forums)
if !gloinited { if !gloinited {
gloinit() gloinit()
} }
//f, err := os.Create("routes_bench_cpu.prof") //f, err := os.Create("routes_bench_cpu.prof")
//if err != nil { //if err != nil {
// log.Fatal(err) // log.Fatal(err)
@ -417,7 +417,7 @@ func BenchmarkForumsGuestRouteParallel(b *testing.B) {
//pprof.StartCPUProfile(f) //pprof.StartCPUProfile(f)
///defer pprof.StopCPUProfile() ///defer pprof.StopCPUProfile()
///pprof.StopCPUProfile() ///pprof.StopCPUProfile()
b.Run("static_recorder", func(b *testing.B) { b.Run("static_recorder", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
//static_w.Code = 200 //static_w.Code = 200
@ -429,7 +429,7 @@ func BenchmarkForumsGuestRouteParallel(b *testing.B) {
//} //}
} }
}) })
b.Run("topic_admin_recorder", func(b *testing.B) { b.Run("topic_admin_recorder", func(b *testing.B) {
//f, err := os.Create("routes_bench_topic_cpu.prof") //f, err := os.Create("routes_bench_topic_cpu.prof")
//if err != nil { //if err != nil {
@ -508,11 +508,11 @@ func BenchmarkForumsGuestRouteParallel(b *testing.B) {
} }
//pprof.StopCPUProfile() //pprof.StopCPUProfile()
}) })
if !plugins_inited { if !plugins_inited {
init_plugins() init_plugins()
} }
b.Run("topic_admin_recorder_with_plugins", func(b *testing.B) { b.Run("topic_admin_recorder_with_plugins", func(b *testing.B) {
//f, err := os.Create("routes_bench_topic_cpu.prof") //f, err := os.Create("routes_bench_topic_cpu.prof")
//if err != nil { //if err != nil {
@ -598,12 +598,12 @@ func BenchmarkQueryTopicParallel(b *testing.B) {
if !gloinited { if !gloinited {
gloinit() gloinit()
} }
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
tu := TopicUser{Css: no_css_tmpl} tu := TopicUser{Css: no_css_tmpl}
for pb.Next() { 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) err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.Is_Closed, &tu.Sticky, &tu.ParentID, &tu.IpAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level)
if err == sql.ErrNoRows { if err == ErrNoRows {
log.Fatal("No rows found!") log.Fatal("No rows found!")
return return
} else if err != nil { } else if err != nil {
@ -619,12 +619,12 @@ func BenchmarkQueryPreparedTopicParallel(b *testing.B) {
if !gloinited { if !gloinited {
gloinit() gloinit()
} }
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
tu := TopicUser{Css: no_css_tmpl} tu := TopicUser{Css: no_css_tmpl}
for pb.Next() { 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) err := get_topic_user_stmt.QueryRow(1).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.Is_Closed, &tu.Sticky, &tu.ParentID, &tu.IpAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level)
if err == sql.ErrNoRows { if err == ErrNoRows {
log.Fatal("No rows found!") log.Fatal("No rows found!")
return return
} else if err != nil { } else if err != nil {
@ -641,7 +641,7 @@ func BenchmarkQueriesSerial(b *testing.B) {
b.Run("topic", func(b *testing.B) { b.Run("topic", func(b *testing.B) {
for i := 0; i < b.N; i++ { 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) err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.Is_Closed, &tu.Sticky, &tu.ParentID, &tu.IpAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level)
if err == sql.ErrNoRows { if err == ErrNoRows {
log.Fatal("No rows found!") log.Fatal("No rows found!")
return return
} else if err != nil { } else if err != nil {
@ -666,7 +666,7 @@ func BenchmarkQueriesSerial(b *testing.B) {
defer rows.Close() defer rows.Close()
} }
}) })
replyItem := Reply{Css: no_css_tmpl} replyItem := Reply{Css: no_css_tmpl}
var is_super_admin bool var is_super_admin bool
var group int var group int
@ -705,7 +705,7 @@ func BenchmarkDefaultGoRouterSerial(b *testing.B) {
w := httptest.NewRecorder() w := httptest.NewRecorder()
req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil)) req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil))
routes := make([]string, 0) routes := make([]string, 0)
routes = append(routes,"/test/") routes = append(routes,"/test/")
serveMux := http.NewServeMux() serveMux := http.NewServeMux()
serveMux.HandleFunc("/test/", func(_ http.ResponseWriter,_ *http.Request){}) serveMux.HandleFunc("/test/", func(_ http.ResponseWriter,_ *http.Request){})
@ -715,7 +715,7 @@ func BenchmarkDefaultGoRouterSerial(b *testing.B) {
serveMux.ServeHTTP(w,req) serveMux.ServeHTTP(w,req)
} }
}) })
routes = append(routes,"/topic/") routes = append(routes,"/topic/")
routes = append(routes,"/forums/") routes = append(routes,"/forums/")
routes = append(routes,"/forum/") routes = append(routes,"/forum/")
@ -728,7 +728,7 @@ func BenchmarkDefaultGoRouterSerial(b *testing.B) {
serveMux.ServeHTTP(w,req) serveMux.ServeHTTP(w,req)
} }
}) })
serveMux = http.NewServeMux() serveMux = http.NewServeMux()
routes = append(routes,"/panel/plugins/") routes = append(routes,"/panel/plugins/")
routes = append(routes,"/panel/groups/") routes = append(routes,"/panel/groups/")
@ -742,7 +742,7 @@ func BenchmarkDefaultGoRouterSerial(b *testing.B) {
serveMux.ServeHTTP(w,req) serveMux.ServeHTTP(w,req)
} }
}) })
serveMux = http.NewServeMux() serveMux = http.NewServeMux()
routes = append(routes,"/panel/forums/create/submit/") routes = append(routes,"/panel/forums/create/submit/")
routes = append(routes,"/panel/forums/delete/") routes = append(routes,"/panel/forums/delete/")
@ -761,7 +761,7 @@ func BenchmarkDefaultGoRouterSerial(b *testing.B) {
serveMux.ServeHTTP(w,req) serveMux.ServeHTTP(w,req)
} }
}) })
serveMux = http.NewServeMux() serveMux = http.NewServeMux()
routes = append(routes,"/panel/plugins/deactivate/") routes = append(routes,"/panel/plugins/deactivate/")
routes = append(routes,"/panel/plugins/install/") routes = append(routes,"/panel/plugins/install/")
@ -780,7 +780,7 @@ func BenchmarkDefaultGoRouterSerial(b *testing.B) {
serveMux.ServeHTTP(w,req) serveMux.ServeHTTP(w,req)
} }
}) })
serveMux = http.NewServeMux() serveMux = http.NewServeMux()
routes = append(routes,"/panel/themes/create/") routes = append(routes,"/panel/themes/create/")
routes = append(routes,"/panel/themes/delete/") routes = append(routes,"/panel/themes/delete/")
@ -799,7 +799,7 @@ func BenchmarkDefaultGoRouterSerial(b *testing.B) {
serveMux.ServeHTTP(w,req) serveMux.ServeHTTP(w,req)
} }
}) })
serveMux = http.NewServeMux() serveMux = http.NewServeMux()
routes = append(routes,"/report/") routes = append(routes,"/report/")
routes = append(routes,"/report/submit/") routes = append(routes,"/report/submit/")
@ -818,7 +818,7 @@ func BenchmarkDefaultGoRouterSerial(b *testing.B) {
serveMux.ServeHTTP(w,req) serveMux.ServeHTTP(w,req)
} }
}) })
serveMux = http.NewServeMux() serveMux = http.NewServeMux()
routes = append(routes,"/topic/delete/submit/") routes = append(routes,"/topic/delete/submit/")
routes = append(routes,"/topic/stick/submit/") routes = append(routes,"/topic/stick/submit/")
@ -837,7 +837,7 @@ func BenchmarkDefaultGoRouterSerial(b *testing.B) {
serveMux.ServeHTTP(w,req) serveMux.ServeHTTP(w,req)
} }
}) })
serveMux = http.NewServeMux() serveMux = http.NewServeMux()
routes = append(routes,"/user/edit/avatar/") routes = append(routes,"/user/edit/avatar/")
routes = append(routes,"/user/edit/avatar/submit/") routes = append(routes,"/user/edit/avatar/submit/")
@ -868,7 +868,7 @@ func BenchmarkCustomRouterSerial(b *testing.B) {
w := httptest.NewRecorder() w := httptest.NewRecorder()
req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil)) req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil))
routes := make([]string, 0) routes := make([]string, 0)
routes = append(routes,"/test/") routes = append(routes,"/test/")
router := NewRouter() router := NewRouter()
router.HandleFunc("/test/", func(_ http.ResponseWriter,_ *http.Request){}) router.HandleFunc("/test/", func(_ http.ResponseWriter,_ *http.Request){})
@ -878,7 +878,7 @@ func BenchmarkCustomRouterSerial(b *testing.B) {
router.ServeHTTP(w,req) router.ServeHTTP(w,req)
} }
}) })
routes = append(routes,"/topic/") routes = append(routes,"/topic/")
routes = append(routes,"/forums/") routes = append(routes,"/forums/")
routes = append(routes,"/forum/") routes = append(routes,"/forum/")
@ -891,7 +891,7 @@ func BenchmarkCustomRouterSerial(b *testing.B) {
router.ServeHTTP(w,req) router.ServeHTTP(w,req)
} }
}) })
router = NewRouter() router = NewRouter()
routes = append(routes,"/panel/plugins/") routes = append(routes,"/panel/plugins/")
routes = append(routes,"/panel/groups/") routes = append(routes,"/panel/groups/")
@ -905,7 +905,7 @@ func BenchmarkCustomRouterSerial(b *testing.B) {
router.ServeHTTP(w,req) router.ServeHTTP(w,req)
} }
}) })
router = NewRouter() router = NewRouter()
routes = append(routes,"/panel/forums/create/submit/") routes = append(routes,"/panel/forums/create/submit/")
routes = append(routes,"/panel/forums/delete/") routes = append(routes,"/panel/forums/delete/")
@ -924,7 +924,7 @@ func BenchmarkCustomRouterSerial(b *testing.B) {
router.ServeHTTP(w,req) router.ServeHTTP(w,req)
} }
}) })
router = NewRouter() router = NewRouter()
routes = append(routes,"/panel/plugins/deactivate/") routes = append(routes,"/panel/plugins/deactivate/")
routes = append(routes,"/panel/plugins/install/") routes = append(routes,"/panel/plugins/install/")
@ -943,7 +943,7 @@ func BenchmarkCustomRouterSerial(b *testing.B) {
router.ServeHTTP(w,req) router.ServeHTTP(w,req)
} }
}) })
router = NewRouter() router = NewRouter()
routes = append(routes,"/panel/themes/create/") routes = append(routes,"/panel/themes/create/")
routes = append(routes,"/panel/themes/delete/") routes = append(routes,"/panel/themes/delete/")
@ -962,7 +962,7 @@ func BenchmarkCustomRouterSerial(b *testing.B) {
router.ServeHTTP(w,req) router.ServeHTTP(w,req)
} }
}) })
router = NewRouter() router = NewRouter()
routes = append(routes,"/report/") routes = append(routes,"/report/")
routes = append(routes,"/report/submit/") routes = append(routes,"/report/submit/")
@ -981,7 +981,7 @@ func BenchmarkCustomRouterSerial(b *testing.B) {
router.ServeHTTP(w,req) router.ServeHTTP(w,req)
} }
}) })
router = NewRouter() router = NewRouter()
routes = append(routes,"/topic/delete/submit/") routes = append(routes,"/topic/delete/submit/")
routes = append(routes,"/topic/stick/submit/") routes = append(routes,"/topic/stick/submit/")
@ -1000,7 +1000,7 @@ func BenchmarkCustomRouterSerial(b *testing.B) {
router.ServeHTTP(w,req) router.ServeHTTP(w,req)
} }
}) })
router = NewRouter() router = NewRouter()
routes = append(routes,"/user/edit/avatar/") routes = append(routes,"/user/edit/avatar/")
routes = append(routes,"/user/edit/avatar/submit/") routes = append(routes,"/user/edit/avatar/submit/")
@ -1217,11 +1217,11 @@ func TestStaticRoute(t *testing.T) {
if !plugins_inited { if !plugins_inited {
init_plugins() init_plugins()
} }
static_w := httptest.NewRecorder() static_w := httptest.NewRecorder()
static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil)) static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil))
static_handler := http.HandlerFunc(route_static) static_handler := http.HandlerFunc(route_static)
static_handler.ServeHTTP(static_w,static_req) static_handler.ServeHTTP(static_w,static_req)
if static_w.Code != 200 { if static_w.Code != 200 {
fmt.Println(static_w.Body) fmt.Println(static_w.Body)
@ -1237,7 +1237,7 @@ func TestStaticRoute(t *testing.T) {
if !plugins_inited { if !plugins_inited {
init_plugins() init_plugins()
} }
admin, err := users.CascadeGet(1) admin, err := users.CascadeGet(1)
if err != nil { if err != nil {
panic(err) panic(err)
@ -1245,17 +1245,17 @@ func TestStaticRoute(t *testing.T) {
if !admin.Is_Admin { if !admin.Is_Admin {
panic("UID1 is not an admin") panic("UID1 is not an admin")
} }
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year} admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year}
topic_w := httptest.NewRecorder() topic_w := httptest.NewRecorder()
topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil)) topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil))
topic_req_admin := topic_req topic_req_admin := topic_req
topic_req_admin.AddCookie(&admin_uid_cookie) topic_req_admin.AddCookie(&admin_uid_cookie)
topic_req_admin.AddCookie(&admin_session_cookie) topic_req_admin.AddCookie(&admin_session_cookie)
topic_handler := http.HandlerFunc(route_topic_id) topic_handler := http.HandlerFunc(route_topic_id)
topic_handler.ServeHTTP(topic_w,topic_req_admin) topic_handler.ServeHTTP(topic_w,topic_req_admin)
if topic_w.Code != 200 { if topic_w.Code != 200 {
fmt.Println(topic_w.Body) fmt.Println(topic_w.Body)
@ -1271,11 +1271,11 @@ func TestStaticRoute(t *testing.T) {
if !plugins_inited { if !plugins_inited {
init_plugins() init_plugins()
} }
topic_w := httptest.NewRecorder() topic_w := httptest.NewRecorder()
topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil)) topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil))
topic_handler := http.HandlerFunc(route_topic_id) topic_handler := http.HandlerFunc(route_topic_id)
topic_handler.ServeHTTP(topic_w,topic_req) topic_handler.ServeHTTP(topic_w,topic_req)
if topic_w.Code != 200 { if topic_w.Code != 200 {
fmt.Println(topic_w.Body) fmt.Println(topic_w.Body)
@ -1291,7 +1291,7 @@ func TestForumsAdminRoute(t *testing.T) {
if !plugins_inited { if !plugins_inited {
init_plugins() init_plugins()
} }
admin, err := users.CascadeGet(1) admin, err := users.CascadeGet(1)
if err != nil { if err != nil {
panic(err) panic(err)
@ -1301,14 +1301,14 @@ func TestForumsAdminRoute(t *testing.T) {
} }
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year} admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year}
forums_w := httptest.NewRecorder() forums_w := httptest.NewRecorder()
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil)) forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
forums_req_admin := forums_req forums_req_admin := forums_req
forums_req_admin.AddCookie(&admin_uid_cookie) forums_req_admin.AddCookie(&admin_uid_cookie)
forums_req_admin.AddCookie(&admin_session_cookie) forums_req_admin.AddCookie(&admin_session_cookie)
forums_handler := http.HandlerFunc(route_forums) forums_handler := http.HandlerFunc(route_forums)
forums_handler.ServeHTTP(forums_w,forums_req_admin) forums_handler.ServeHTTP(forums_w,forums_req_admin)
if forums_w.Code != 200 { if forums_w.Code != 200 {
fmt.Println(forums_w.Body) fmt.Println(forums_w.Body)
@ -1324,11 +1324,11 @@ func TestForumsGuestRoute(t *testing.T) {
if !plugins_inited { if !plugins_inited {
init_plugins() init_plugins()
} }
forums_w := httptest.NewRecorder() forums_w := httptest.NewRecorder()
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil)) forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
forums_handler := http.HandlerFunc(route_forums) forums_handler := http.HandlerFunc(route_forums)
forums_handler.ServeHTTP(forums_w,forums_req) forums_handler.ServeHTTP(forums_w,forums_req)
if forums_w.Code != 200 { if forums_w.Code != 200 {
fmt.Println(forums_w.Body) fmt.Println(forums_w.Body)
@ -1344,7 +1344,7 @@ func TestForumsGuestRoute(t *testing.T) {
if !plugins_inited { if !plugins_inited {
init_plugins() init_plugins()
} }
admin, err := users.CascadeGet(1) admin, err := users.CascadeGet(1)
if err != nil { if err != nil {
panic(err) panic(err)
@ -1354,14 +1354,14 @@ func TestForumsGuestRoute(t *testing.T) {
} }
admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year} admin_uid_cookie := http.Cookie{Name:"uid",Value:"1",Path:"/",MaxAge: year}
admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year} admin_session_cookie := http.Cookie{Name:"session",Value: admin.Session,Path:"/",MaxAge: year}
forum_w := httptest.NewRecorder() forum_w := httptest.NewRecorder()
forum_req := httptest.NewRequest("get","/forum/1",bytes.NewReader(nil)) forum_req := httptest.NewRequest("get","/forum/1",bytes.NewReader(nil))
forum_req_admin := forum_req forum_req_admin := forum_req
forum_req_admin.AddCookie(&admin_uid_cookie) forum_req_admin.AddCookie(&admin_uid_cookie)
forum_req_admin.AddCookie(&admin_session_cookie) forum_req_admin.AddCookie(&admin_session_cookie)
forum_handler := http.HandlerFunc(route_forum) forum_handler := http.HandlerFunc(route_forum)
forum_handler.ServeHTTP(forum_w,forum_req_admin) forum_handler.ServeHTTP(forum_w,forum_req_admin)
if forum_w.Code != 200 { if forum_w.Code != 200 {
fmt.Println(forum_w.Body) fmt.Println(forum_w.Body)
@ -1377,11 +1377,11 @@ func TestForumsGuestRoute(t *testing.T) {
if !plugins_inited { if !plugins_inited {
init_plugins() init_plugins()
} }
forum_w := httptest.NewRecorder() forum_w := httptest.NewRecorder()
forum_req := httptest.NewRequest("get","/forum/2",bytes.NewReader(nil)) forum_req := httptest.NewRequest("get","/forum/2",bytes.NewReader(nil))
forum_handler := http.HandlerFunc(route_forum) forum_handler := http.HandlerFunc(route_forum)
forum_handler.ServeHTTP(forum_w,forum_req) forum_handler.ServeHTTP(forum_w,forum_req)
if forum_w.Code != 200 { if forum_w.Code != 200 {
fmt.Println(forum_w.Body) fmt.Println(forum_w.Body)
@ -1408,19 +1408,19 @@ func TestForumsGuestRoute(t *testing.T) {
1,1,0,friend_invite,user,2` 1,1,0,friend_invite,user,2`
return testdb.RowsFromCSVString(cols,rows), nil return testdb.RowsFromCSVString(cols,rows), nil
}) })
alert_handler.ServeHTTP(alert_w,alert_req) alert_handler.ServeHTTP(alert_w,alert_req)
fmt.Println(alert_w.Body) fmt.Println(alert_w.Body)
if alert_w.Code != 200 { if alert_w.Code != 200 {
panic("HTTP Error!") panic("HTTP Error!")
} }
fmt.Println("No problems found in the alert handler!") fmt.Println("No problems found in the alert handler!")
db = db_prod db = db_prod
}*/ }*/
/*func TestRoute(t *testing.T) { /*func TestRoute(t *testing.T) {
}*/ }*/
func TestSplittyThing(t *testing.T) { func TestSplittyThing(t *testing.T) {
@ -1436,8 +1436,8 @@ func TestSplittyThing(t *testing.T) {
fmt.Println("Extra Data:", extra_data) fmt.Println("Extra Data:", extra_data)
fmt.Println("Path Bytes:", []byte(path)) fmt.Println("Path Bytes:", []byte(path))
fmt.Println("Extra Data Bytes:", []byte(extra_data)) fmt.Println("Extra Data Bytes:", []byte(extra_data))
fmt.Println("Splitty thing test") fmt.Println("Splitty thing test")
path = "/topics/" path = "/topics/"
extra_data = "" extra_data = ""

View File

@ -2,8 +2,6 @@ package main
import "sync" import "sync"
import "encoding/json" import "encoding/json"
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
var group_update_mutex sync.Mutex var group_update_mutex sync.Mutex
@ -35,10 +33,10 @@ var group_create_mutex sync.Mutex
func create_group(group_name string, tag string, is_admin bool, is_mod bool, is_banned bool) (int, error) { func create_group(group_name string, tag string, is_admin bool, is_mod bool, is_banned bool) (int, error) {
var gid int var gid int
err := group_entry_exists_stmt.QueryRow().Scan(&gid) err := group_entry_exists_stmt.QueryRow().Scan(&gid)
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
return 0, err return 0, err
} }
if err != sql.ErrNoRows { if err != ErrNoRows {
group_update_mutex.Lock() group_update_mutex.Lock()
_, err = update_group_rank_stmt.Exec(is_admin, is_mod, is_banned, gid) _, err = update_group_rank_stmt.Exec(is_admin, is_mod, is_banned, gid)
if err != nil { if err != nil {
@ -78,7 +76,11 @@ func create_group(group_name string, tag string, is_admin bool, is_mod bool, is_
group_create_mutex.Unlock() group_create_mutex.Unlock()
// Generate the forum permissions based on the presets... // Generate the forum permissions based on the presets...
fdata := forums fdata, err := fstore.GetAll()
if err != nil {
return 0, err
}
permupdate_mutex.Lock() permupdate_mutex.Lock()
for _, forum := range fdata { for _, forum := range fdata {
var thePreset string var thePreset string

21
main.go
View File

@ -44,9 +44,9 @@ var template_forums_handle func(ForumsPage,io.Writer) = nil
var template_profile_handle func(ProfilePage,io.Writer) = nil var template_profile_handle func(ProfilePage,io.Writer) = nil
var template_create_topic_handle func(CreateTopicPage,io.Writer) = nil var template_create_topic_handle func(CreateTopicPage,io.Writer) = nil
func compile_templates() { func compile_templates() error {
var c CTemplateSet var c CTemplateSet
user := User{62,"","compiler@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"0.0.0.0.0"} user := User{62,"fake-user","Fake User","compiler@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"0.0.0.0.0"}
headerVars := HeaderVars{ headerVars := HeaderVars{
NoticeList:[]string{"test"}, NoticeList:[]string{"test"},
Stylesheets:[]string{"panel"}, Stylesheets:[]string{"panel"},
@ -58,9 +58,9 @@ func compile_templates() {
log.Print("Compiling the templates") log.Print("Compiling the templates")
topic := TopicUser{1,"Blah","Hey there!",0,false,false,"Date","Date",0,"","127.0.0.1",0,1,"classname","","",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",default_group,"",no_css_tmpl,0,"","","","",58,false}
var replyList []Reply var replyList []Reply
replyList = append(replyList, Reply{0,0,"","Yo!",0,"",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",default_group,"",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1",false,1,"",""})
var varList map[string]VarItem = make(map[string]VarItem) var varList map[string]VarItem = make(map[string]VarItem)
tpage := TopicPage{"Title",user,headerVars,replyList,topic,1,1,extData} tpage := TopicPage{"Title",user,headerVars,replyList,topic,1,1,extData}
@ -72,6 +72,11 @@ func compile_templates() {
profile_tmpl := c.compile_template("profile.html","templates/","ProfilePage", ppage, varList) profile_tmpl := c.compile_template("profile.html","templates/","ProfilePage", ppage, varList)
var forumList []Forum var forumList []Forum
forums, err := fstore.GetAll()
if err != nil {
return err
}
for _, forum := range forums { for _, forum := range forums {
if forum.Active { if forum.Active {
forumList = append(forumList,forum) forumList = append(forumList,forum)
@ -82,13 +87,13 @@ func compile_templates() {
forums_tmpl := c.compile_template("forums.html","templates/","ForumsPage",forums_page,varList) forums_tmpl := c.compile_template("forums.html","templates/","ForumsPage",forums_page,varList)
var topicsList []TopicsRow var topicsList []TopicsRow
topicsList = append(topicsList,TopicsRow{1,"Topic Title","The topic content.",1,false,false,"Date","Date",1,"","127.0.0.1",0,1,"classname","Admin","","",0,"","","","",58,"General"}) 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"})
topics_page := TopicsPage{"Topic List",user,headerVars,topicsList,extData} topics_page := TopicsPage{"Topic List",user,headerVars,topicsList,extData}
topics_tmpl := c.compile_template("topics.html","templates/","TopicsPage",topics_page,varList) topics_tmpl := c.compile_template("topics.html","templates/","TopicsPage",topics_page,varList)
var topicList []TopicUser var topicList []TopicUser
topicList = append(topicList,TopicUser{1,"Topic Title","The topic content.",1,false,false,"Date","Date",1,"","127.0.0.1",0,1,"classname","","Admin",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",default_group,"","",0,"","","","",58,false})
forum_item := Forum{1,"General Forum","Where the general stuff happens",true,"all",0,"",0,"",0,""} forum_item := Forum{1,"general","General Forum","Where the general stuff happens",true,"all",0,"","",0,"",0,""}
forum_page := ForumPage{"General Forum",user,headerVars,topicList,forum_item,1,1,extData} 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) forum_tmpl := c.compile_template("forum.html","templates/","ForumPage",forum_page,varList)
@ -100,6 +105,8 @@ func compile_templates() {
go write_template("topics", topics_tmpl) go write_template("topics", topics_tmpl)
go write_template("forum", forum_tmpl) go write_template("forum", forum_tmpl)
go write_file("./template_list.go","package main\n\n" + c.FragOut) go write_file("./template_list.go","package main\n\n" + c.FragOut)
return nil
} }
func write_template(name string, content string) { func write_template(name string, content string) {

View File

@ -7,8 +7,6 @@ import (
"net" "net"
"net/http" "net/http"
"html" "html"
"database/sql"
_ "github.com/go-sql-driver/mysql"
) )
func route_edit_topic(w http.ResponseWriter, r *http.Request) { func route_edit_topic(w http.ResponseWriter, r *http.Request) {
@ -30,7 +28,7 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
} }
old_topic, err := topics.CascadeGet(tid) old_topic, err := topics.CascadeGet(tid)
if err == sql.ErrNoRows { if err == ErrNoRows {
PreErrorJSQ("The topic you tried to edit doesn't exist.",w,r,is_js) PreErrorJSQ("The topic you tried to edit doesn't exist.",w,r,is_js)
return return
} else if err != nil { } else if err != nil {
@ -96,7 +94,7 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
} }
err = topics.Load(tid) err = topics.Load(tid)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalErrorJSQ("This topic no longer exists!",w,r,user,is_js) LocalErrorJSQ("This topic no longer exists!",w,r,user,is_js)
return return
} else if err != nil { } else if err != nil {
@ -119,7 +117,7 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
} }
topic, err := topics.CascadeGet(tid) topic, err := topics.CascadeGet(tid)
if err == sql.ErrNoRows { if err == ErrNoRows {
PreError("The topic you tried to delete doesn't exist.",w,r) PreError("The topic you tried to delete doesn't exist.",w,r)
return return
} else if err != nil { } else if err != nil {
@ -170,13 +168,11 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
return return
} }
_, err = remove_topics_from_forum_stmt.Exec(1, topic.ParentID) err = fstore.DecrementTopicCount(topic.ParentID)
if err != nil { if err != nil && err != ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
forums[topic.ParentID].TopicCount -= 1
topics.Remove(tid) topics.Remove(tid)
} }
@ -188,7 +184,7 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) {
} }
topic, err := topics.CascadeGet(tid) topic, err := topics.CascadeGet(tid)
if err == sql.ErrNoRows { if err == ErrNoRows {
PreError("The topic you tried to pin doesn't exist.",w,r) PreError("The topic you tried to pin doesn't exist.",w,r)
return return
} else if err != nil { } else if err != nil {
@ -243,7 +239,7 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) {
} }
topic, err := topics.CascadeGet(tid) topic, err := topics.CascadeGet(tid)
if err == sql.ErrNoRows { if err == ErrNoRows {
PreError("The topic you tried to unpin doesn't exist.",w,r) PreError("The topic you tried to unpin doesn't exist.",w,r)
return return
} else if err != nil { } else if err != nil {
@ -324,7 +320,7 @@ func route_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
var fid int var fid int
err = get_topic_fid_stmt.QueryRow(tid).Scan(&fid) err = get_topic_fid_stmt.QueryRow(tid).Scan(&fid)
if err == sql.ErrNoRows { if err == ErrNoRows {
PreErrorJSQ("The parent topic doesn't exist.",w,r,is_js) PreErrorJSQ("The parent topic doesn't exist.",w,r,is_js)
return return
} else if err != nil { } else if err != nil {
@ -366,7 +362,7 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
} }
reply, err := get_reply(rid) reply, err := get_reply(rid)
if err == sql.ErrNoRows { if err == ErrNoRows {
PreErrorJSQ("The reply you tried to delete doesn't exist.",w,r,is_js) PreErrorJSQ("The reply you tried to delete doesn't exist.",w,r,is_js)
return return
} else if err != nil { } else if err != nil {
@ -376,7 +372,7 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
var fid int var fid int
err = get_topic_fid_stmt.QueryRow(reply.ParentID).Scan(&fid) err = get_topic_fid_stmt.QueryRow(reply.ParentID).Scan(&fid)
if err == sql.ErrNoRows { if err == ErrNoRows {
PreErrorJSQ("The parent topic doesn't exist.",w,r,is_js) PreErrorJSQ("The parent topic doesn't exist.",w,r,is_js)
return return
} else if err != nil { } else if err != nil {
@ -507,7 +503,7 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
var uid int var uid int
err = get_user_reply_uid_stmt.QueryRow(rid).Scan(&uid) err = get_user_reply_uid_stmt.QueryRow(rid).Scan(&uid)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalErrorJSQ("The reply you tried to delete doesn't exist.",w,r,user,is_js) LocalErrorJSQ("The reply you tried to delete doesn't exist.",w,r,user,is_js)
return return
} else if err != nil { } else if err != nil {
@ -552,7 +548,7 @@ func route_ban(w http.ResponseWriter, r *http.Request) {
var uname string var uname string
err = get_user_name_stmt.QueryRow(uid).Scan(&uname) err = get_user_name_stmt.QueryRow(uid).Scan(&uname)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("The user you're trying to ban no longer exists.",w,r,user) LocalError("The user you're trying to ban no longer exists.",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -594,7 +590,7 @@ func route_ban_submit(w http.ResponseWriter, r *http.Request) {
var group int var group int
var is_super_admin bool var is_super_admin bool
err = get_user_rank_stmt.QueryRow(uid).Scan(&group, &is_super_admin) err = get_user_rank_stmt.QueryRow(uid).Scan(&group, &is_super_admin)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("The user you're trying to ban no longer exists.",w,r,user) LocalError("The user you're trying to ban no longer exists.",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -663,7 +659,7 @@ func route_unban(w http.ResponseWriter, r *http.Request) {
var group int var group int
err = get_user_group_stmt.QueryRow(uid).Scan(&group) err = get_user_group_stmt.QueryRow(uid).Scan(&group)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("The user you're trying to unban no longer exists.",w,r,user) LocalError("The user you're trying to unban no longer exists.",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -694,7 +690,7 @@ func route_unban(w http.ResponseWriter, r *http.Request) {
} }
err = users.Load(uid) err = users.Load(uid)
if err != nil && err == sql.ErrNoRows { if err != nil && err == ErrNoRows {
LocalError("This user no longer exists!",w,r,user) LocalError("This user no longer exists!",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -727,7 +723,7 @@ func route_activate(w http.ResponseWriter, r *http.Request) {
var active bool var active bool
err = get_user_active_stmt.QueryRow(uid).Scan(&active) err = get_user_active_stmt.QueryRow(uid).Scan(&active)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("The account you're trying to activate no longer exists.",w,r,user) LocalError("The account you're trying to activate no longer exists.",w,r,user)
return return
} else if err != nil { } else if err != nil {

View File

@ -420,14 +420,14 @@ func parse_message(msg string/*, user User*/) string {
i += int_len i += int_len
topic, err := topics.CascadeGet(tid) topic, err := topics.CascadeGet(tid)
if err != nil || !forum_exists(topic.ParentID) { if err != nil || !fstore.Exists(topic.ParentID) {
outbytes = append(outbytes,invalid_topic...) outbytes = append(outbytes,invalid_topic...)
lastItem = i lastItem = i
continue continue
} }
outbytes = append(outbytes, url_open...) outbytes = append(outbytes, url_open...)
var url_bit []byte = []byte(build_topic_url(tid)) var url_bit []byte = []byte(build_topic_url("",tid))
outbytes = append(outbytes, url_bit...) outbytes = append(outbytes, url_bit...)
outbytes = append(outbytes, url_open2...) outbytes = append(outbytes, url_open2...)
var tid_bit []byte = []byte("#tid-" + strconv.Itoa(tid)) var tid_bit []byte = []byte("#tid-" + strconv.Itoa(tid))
@ -449,14 +449,14 @@ func parse_message(msg string/*, user User*/) string {
i += int_len i += int_len
topic, err := get_topic_by_reply(rid) topic, err := get_topic_by_reply(rid)
if err != nil || !forum_exists(topic.ParentID) { if err != nil || !fstore.Exists(topic.ParentID) {
outbytes = append(outbytes,invalid_topic...) outbytes = append(outbytes,invalid_topic...)
lastItem = i lastItem = i
continue continue
} }
outbytes = append(outbytes, url_open...) outbytes = append(outbytes, url_open...)
var url_bit []byte = []byte(build_topic_url(topic.ID)) var url_bit []byte = []byte(build_topic_url("",topic.ID))
outbytes = append(outbytes, url_bit...) outbytes = append(outbytes, url_bit...)
outbytes = append(outbytes, url_open2...) outbytes = append(outbytes, url_open2...)
var rid_bit []byte = []byte("#rid-" + strconv.Itoa(rid)) var rid_bit []byte = []byte("#rid-" + strconv.Itoa(rid))
@ -470,14 +470,14 @@ func parse_message(msg string/*, user User*/) string {
fid, int_len := coerce_int_bytes(msgbytes[start:]) fid, int_len := coerce_int_bytes(msgbytes[start:])
i += int_len i += int_len
if !forum_exists(fid) { if !fstore.Exists(fid) {
outbytes = append(outbytes,invalid_forum...) outbytes = append(outbytes,invalid_forum...)
lastItem = i lastItem = i
continue continue
} }
outbytes = append(outbytes, url_open...) outbytes = append(outbytes, url_open...)
var url_bit []byte = []byte(build_forum_url(fid)) var url_bit []byte = []byte(build_forum_url("",fid))
outbytes = append(outbytes, url_bit...) outbytes = append(outbytes, url_bit...)
outbytes = append(outbytes, url_open2...) outbytes = append(outbytes, url_open2...)
var fid_bit []byte = []byte("#fid-" + strconv.Itoa(fid)) var fid_bit []byte = []byte("#fid-" + strconv.Itoa(fid))
@ -503,7 +503,7 @@ func parse_message(msg string/*, user User*/) string {
} }
outbytes = append(outbytes, url_open...) outbytes = append(outbytes, url_open...)
var url_bit []byte = []byte(build_profile_url(uid)) var url_bit []byte = []byte(build_profile_url(menUser.Slug,uid))
outbytes = append(outbytes, url_bit...) outbytes = append(outbytes, url_bit...)
outbytes = append(outbytes, bytes_singlequote...) outbytes = append(outbytes, bytes_singlequote...)
outbytes = append(outbytes, url_mention...) outbytes = append(outbytes, url_mention...)

View File

@ -12,12 +12,10 @@ import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"html/template" "html/template"
"database/sql"
)
import _ "github.com/go-sql-driver/mysql" "github.com/shirou/gopsutil/cpu"
import "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/mem"
import "github.com/shirou/gopsutil/mem" )
func route_panel(w http.ResponseWriter, r *http.Request){ func route_panel(w http.ResponseWriter, r *http.Request){
user, headerVars, ok := PanelSessionCheck(w,r) user, headerVars, ok := PanelSessionCheck(w,r)
@ -78,7 +76,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
var postCount int var postCount int
err = todays_post_count_stmt.QueryRow().Scan(&postCount) err = todays_post_count_stmt.QueryRow().Scan(&postCount)
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
@ -95,7 +93,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
var topicCount int var topicCount int
err = todays_topic_count_stmt.QueryRow().Scan(&topicCount) err = todays_topic_count_stmt.QueryRow().Scan(&topicCount)
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
@ -112,7 +110,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
var reportCount int var reportCount int
err = todays_report_count_stmt.QueryRow().Scan(&reportCount) err = todays_report_count_stmt.QueryRow().Scan(&reportCount)
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
@ -120,7 +118,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
var newUserCount int var newUserCount int
err = todays_newuser_count_stmt.QueryRow().Scan(&newUserCount) err = todays_newuser_count_stmt.QueryRow().Scan(&newUserCount)
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
@ -200,6 +198,12 @@ func route_panel_forums(w http.ResponseWriter, r *http.Request){
} }
var forumList []interface{} var forumList []interface{}
forums, err := fstore.GetAll()
if err != nil {
InternalError(err,w,r)
return
}
for _, forum := range forums { for _, forum := range forums {
if forum.Name != "" { if forum.Name != "" {
fadmin := ForumAdmin{forum.ID,forum.Name,forum.Desc,forum.Active,forum.Preset,forum.TopicCount,preset_to_lang(forum.Preset)} fadmin := ForumAdmin{forum.ID,forum.Name,forum.Desc,forum.Active,forum.Preset,forum.TopicCount,preset_to_lang(forum.Preset)}
@ -210,7 +214,7 @@ func route_panel_forums(w http.ResponseWriter, r *http.Request){
} }
} }
pi := Page{"Forum Manager",user,headerVars,forumList,nil} pi := Page{"Forum Manager",user,headerVars,forumList,nil}
err := templates.ExecuteTemplate(w,"panel-forums.html",pi) err = templates.ExecuteTemplate(w,"panel-forums.html",pi)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
} }
@ -242,7 +246,7 @@ func route_panel_forums_create_submit(w http.ResponseWriter, r *http.Request){
factive := r.PostFormValue("forum-name") factive := r.PostFormValue("forum-name")
active := (factive == "on" || factive == "1" ) active := (factive == "on" || factive == "1" )
fid, err := create_forum(fname,fdesc,active,fpreset) fid, err := fstore.CreateForum(fname,fdesc,active,fpreset)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
@ -272,12 +276,16 @@ func route_panel_forums_delete(w http.ResponseWriter, r *http.Request, sfid stri
return return
} }
if !forum_exists(fid) { forum, err := fstore.CascadeGet(fid)
if err == ErrNoRows {
LocalError("The forum you're trying to delete doesn't exist.",w,r,user) LocalError("The forum you're trying to delete doesn't exist.",w,r,user)
return return
} else if err != nil {
InternalError(err,w,r)
return
} }
confirm_msg := "Are you sure you want to delete the '" + forums[fid].Name + "' forum?" confirm_msg := "Are you sure you want to delete the '" + forum.Name + "' forum?"
yousure := AreYouSure{"/panel/forums/delete/submit/" + strconv.Itoa(fid),confirm_msg} yousure := AreYouSure{"/panel/forums/delete/submit/" + strconv.Itoa(fid),confirm_msg}
pi := Page{"Delete Forum",user,headerVars,tList,yousure} pi := Page{"Delete Forum",user,headerVars,tList,yousure}
@ -303,12 +311,12 @@ func route_panel_forums_delete_submit(w http.ResponseWriter, r *http.Request, sf
LocalError("The provided Forum ID is not a valid number.",w,r,user) LocalError("The provided Forum ID is not a valid number.",w,r,user)
return return
} }
if !forum_exists(fid) { if !fstore.Exists(fid) {
LocalError("The forum you're trying to delete doesn't exist.",w,r,user) LocalError("The forum you're trying to delete doesn't exist.",w,r,user)
return return
} }
err = delete_forum(fid) err = fstore.CascadeDelete(fid)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
@ -331,12 +339,16 @@ func route_panel_forums_edit(w http.ResponseWriter, r *http.Request, sfid string
LocalError("The provided Forum ID is not a valid number.",w,r,user) LocalError("The provided Forum ID is not a valid number.",w,r,user)
return return
} }
if !forum_exists(fid) {
forum, err := fstore.CascadeGet(fid)
if err == ErrNoRows {
LocalError("The forum you're trying to edit doesn't exist.",w,r,user) LocalError("The forum you're trying to edit doesn't exist.",w,r,user)
return return
} else if err != nil {
InternalError(err,w,r)
return
} }
var forum Forum = forums[fid]
if forum.Preset == "" { if forum.Preset == "" {
forum.Preset = "custom" forum.Preset = "custom"
} }
@ -391,42 +403,48 @@ func route_panel_forums_edit_submit(w http.ResponseWriter, r *http.Request, sfid
forum_desc := r.PostFormValue("forum_desc") forum_desc := r.PostFormValue("forum_desc")
forum_preset := strip_invalid_preset(r.PostFormValue("forum_preset")) forum_preset := strip_invalid_preset(r.PostFormValue("forum_preset"))
forum_active := r.PostFormValue("forum_active") forum_active := r.PostFormValue("forum_active")
if !forum_exists(fid) {
forum, err := fstore.CascadeGet(fid)
if err == ErrNoRows {
LocalErrorJSQ("The forum you're trying to edit doesn't exist.",w,r,user,is_js) LocalErrorJSQ("The forum you're trying to edit doesn't exist.",w,r,user,is_js)
return return
} else if err != nil {
InternalErrorJSQ(err,w,r,is_js)
return
} }
if forum_name == "" { if forum_name == "" {
forum_name = forums[fid].Name forum_name = forum.Name
} }
var active bool var active bool
if forum_active == "" { if forum_active == "" {
active = forums[fid].Active active = forum.Active
} else if forum_active == "1" || forum_active == "Show" { } else if forum_active == "1" || forum_active == "Show" {
active = true active = true
} else { } else {
active = false active = false
} }
forum_update_mutex.Lock()
_, err = update_forum_stmt.Exec(forum_name,forum_desc,active,forum_preset,fid) _, err = update_forum_stmt.Exec(forum_name,forum_desc,active,forum_preset,fid)
if err != nil { if err != nil {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
if forum.Name != forum_name {
if forums[fid].Name != forum_name { forum.Name = forum_name
forums[fid].Name = forum_name
} }
if forums[fid].Desc != forum_desc { if forum.Desc != forum_desc {
forums[fid].Desc = forum_desc forum.Desc = forum_desc
} }
if forums[fid].Active != active { if forum.Active != active {
forums[fid].Active = active forum.Active = active
} }
if forums[fid].Preset != forum_preset { if forum.Preset != forum_preset {
forums[fid].Preset = forum_preset forum.Preset = forum_preset
} }
forum_update_mutex.Unlock()
permmap_to_query(preset_to_permmap(forum_preset),fid) permmap_to_query(preset_to_permmap(forum_preset),fid)
@ -475,6 +493,17 @@ func route_panel_forums_edit_perms_submit(w http.ResponseWriter, r *http.Request
perm_preset := strip_invalid_group_forum_preset(r.PostFormValue("perm_preset")) perm_preset := strip_invalid_group_forum_preset(r.PostFormValue("perm_preset"))
fperms, changed := group_forum_preset_to_forum_perms(perm_preset) fperms, changed := group_forum_preset_to_forum_perms(perm_preset)
forum, err := fstore.CascadeGet(fid)
if err == ErrNoRows {
LocalErrorJSQ("This forum doesn't exist",w,r,user,is_js)
return
} else if err != nil {
InternalErrorJSQ(err,w,r,is_js)
return
}
forum_update_mutex.Lock()
if changed { if changed {
permupdate_mutex.Lock() permupdate_mutex.Lock()
groups[gid].Forums[fid] = fperms groups[gid].Forums[fid] = fperms
@ -492,13 +521,14 @@ func route_panel_forums_edit_perms_submit(w http.ResponseWriter, r *http.Request
} }
permupdate_mutex.Unlock() permupdate_mutex.Unlock()
_, err = update_forum_stmt.Exec(forums[fid].Name,forums[fid].Desc,forums[fid].Active,"",fid) _, err = update_forum_stmt.Exec(forum.Name,forum.Desc,forum.Active,"",fid)
if err != nil { if err != nil {
InternalErrorJSQ(err,w,r,is_js) InternalErrorJSQ(err,w,r,is_js)
return return
} }
forums[fid].Preset = "" forum.Preset = ""
} }
forum_update_mutex.Unlock()
if is_js == "0" { if is_js == "0" {
http.Redirect(w,r,"/panel/forums/edit/" + strconv.Itoa(fid),http.StatusSeeOther) http.Redirect(w,r,"/panel/forums/edit/" + strconv.Itoa(fid),http.StatusSeeOther)
@ -573,7 +603,7 @@ func route_panel_setting(w http.ResponseWriter, r *http.Request, sname string){
setting := Setting{sname,"","",""} setting := Setting{sname,"","",""}
err := get_setting_stmt.QueryRow(setting.Name).Scan(&setting.Content,&setting.Type) err := get_setting_stmt.QueryRow(setting.Name).Scan(&setting.Content,&setting.Type)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("The setting you want to edit doesn't exist.",w,r,user) LocalError("The setting you want to edit doesn't exist.",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -633,7 +663,7 @@ func route_panel_setting_edit(w http.ResponseWriter, r *http.Request, sname stri
scontent := r.PostFormValue("setting-value") scontent := r.PostFormValue("setting-value")
err = get_full_setting_stmt.QueryRow(sname).Scan(&sname, &stype, &sconstraints) err = get_full_setting_stmt.QueryRow(sname).Scan(&sname, &stype, &sconstraints)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("The setting you want to edit doesn't exist.",w,r,user) LocalError("The setting you want to edit doesn't exist.",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -704,7 +734,7 @@ func route_panel_plugins_activate(w http.ResponseWriter, r *http.Request, uname
var active bool var active bool
err := is_plugin_active_stmt.QueryRow(uname).Scan(&active) err := is_plugin_active_stmt.QueryRow(uname).Scan(&active)
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
@ -717,7 +747,7 @@ func route_panel_plugins_activate(w http.ResponseWriter, r *http.Request, uname
} }
} }
has_plugin := err != sql.ErrNoRows has_plugin := err != ErrNoRows
if has_plugin { if has_plugin {
if active { if active {
LocalError("The plugin is already active",w,r,user) LocalError("The plugin is already active",w,r,user)
@ -766,7 +796,7 @@ func route_panel_plugins_deactivate(w http.ResponseWriter, r *http.Request, unam
var active bool var active bool
err := is_plugin_active_stmt.QueryRow(uname).Scan(&active) err := is_plugin_active_stmt.QueryRow(uname).Scan(&active)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("The plugin you're trying to deactivate isn't active",w,r,user) LocalError("The plugin you're trying to deactivate isn't active",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -860,7 +890,7 @@ func route_panel_users_edit(w http.ResponseWriter, r *http.Request,suid string){
} }
targetUser, err := users.CascadeGet(uid) targetUser, err := users.CascadeGet(uid)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("The user you're trying to edit doesn't exist.",w,r,user) LocalError("The user you're trying to edit doesn't exist.",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -912,7 +942,7 @@ func route_panel_users_edit_submit(w http.ResponseWriter, r *http.Request, suid
} }
targetUser, err := users.CascadeGet(uid) targetUser, err := users.CascadeGet(uid)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("The user you're trying to edit doesn't exist.",w,r,user) LocalError("The user you're trying to edit doesn't exist.",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -1468,12 +1498,12 @@ func route_panel_themes_default(w http.ResponseWriter, r *http.Request, uname st
var isDefault bool var isDefault bool
fmt.Println("uname",uname) fmt.Println("uname",uname)
err := is_theme_default_stmt.QueryRow(uname).Scan(&isDefault) err := is_theme_default_stmt.QueryRow(uname).Scan(&isDefault)
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
has_theme := err != sql.ErrNoRows has_theme := err != ErrNoRows
if has_theme { if has_theme {
fmt.Println("isDefault",isDefault) fmt.Println("isDefault",isDefault)
if isDefault { if isDefault {
@ -1544,64 +1574,64 @@ func route_panel_logs_mod(w http.ResponseWriter, r *http.Request){
actor, err := users.CascadeGet(actorID) actor, err := users.CascadeGet(actorID)
if err != nil { if err != nil {
actor = &User{Name:"Unknown"} actor = &User{Name:"Unknown",Slug:"unknown"}
} }
switch(action) { switch(action) {
case "lock": case "lock":
topic, err := topics.CascadeGet(elementID) topic, err := topics.CascadeGet(elementID)
if err != nil { if err != nil {
topic = &Topic{Title:"Unknown"} topic = &Topic{Title:"Unknown",Slug:"unknown"}
} }
action = "<a href='" + build_topic_url(elementID) + "'>" + topic.Title + "</a> was locked by <a href='" + build_profile_url(actorID) + "'>"+actor.Name+"</a>" action = "<a href='" + build_topic_url(topic.Slug,elementID) + "'>" + topic.Title + "</a> was locked by <a href='" + build_profile_url(actor.Slug,actorID) + "'>"+actor.Name+"</a>"
case "unlock": case "unlock":
topic, err := topics.CascadeGet(elementID) topic, err := topics.CascadeGet(elementID)
if err != nil { if err != nil {
topic = &Topic{Title:"Unknown"} topic = &Topic{Title:"Unknown",Slug:"unknown"}
} }
action = "<a href='" + build_topic_url(elementID) + "'>" + topic.Title + "</a> was reopened by <a href='" + build_profile_url(actorID) + "'>"+actor.Name+"</a>" action = "<a href='" + build_topic_url(topic.Slug,elementID) + "'>" + topic.Title + "</a> was reopened by <a href='" + build_profile_url(actor.Slug,actorID) + "'>"+actor.Name+"</a>"
case "stick": case "stick":
topic, err := topics.CascadeGet(elementID) topic, err := topics.CascadeGet(elementID)
if err != nil { if err != nil {
topic = &Topic{Title:"Unknown"} topic = &Topic{Title:"Unknown",Slug:"unknown"}
} }
action = "<a href='" + build_topic_url(elementID) + "'>" + topic.Title + "</a> was pinned by <a href='" + build_profile_url(actorID) + "'>"+actor.Name+"</a>" action = "<a href='" + build_topic_url(topic.Slug,elementID) + "'>" + topic.Title + "</a> was pinned by <a href='" + build_profile_url(actor.Slug,actorID) + "'>"+actor.Name+"</a>"
case "unstick": case "unstick":
topic, err := topics.CascadeGet(elementID) topic, err := topics.CascadeGet(elementID)
if err != nil { if err != nil {
topic = &Topic{Title:"Unknown"} topic = &Topic{Title:"Unknown",Slug:"unknown"}
} }
action = "<a href='" + build_topic_url(elementID) + "'>" + topic.Title + "</a> was unpinned by <a href='" + build_profile_url(actorID) + "'>"+actor.Name+"</a>" action = "<a href='" + build_topic_url(topic.Slug,elementID) + "'>" + topic.Title + "</a> was unpinned by <a href='" + build_profile_url(actor.Slug,actorID) + "'>"+actor.Name+"</a>"
case "delete": case "delete":
if elementType == "topic" { if elementType == "topic" {
action = "Topic #" + strconv.Itoa(elementID) + " was deleted by <a href='" + build_profile_url(actorID) + "'>"+actor.Name+"</a>" action = "Topic #" + strconv.Itoa(elementID) + " was deleted by <a href='" + build_profile_url(actor.Slug,actorID) + "'>"+actor.Name+"</a>"
} else { } else {
topic, err := get_topic_by_reply(elementID) topic, err := get_topic_by_reply(elementID)
if err != nil { if err != nil {
topic = &Topic{Title:"Unknown"} topic = &Topic{Title:"Unknown",Slug:"unknown"}
} }
action = "A reply in <a href='" + build_topic_url(elementID) + "'>" + topic.Title + "</a> was deleted by <a href='" + build_profile_url(actorID) + "'>"+actor.Name+"</a>" action = "A reply in <a href='" + build_topic_url(topic.Slug,topic.ID) + "'>" + topic.Title + "</a> was deleted by <a href='" + build_profile_url(actor.Slug,actorID) + "'>"+actor.Name+"</a>"
} }
case "ban": case "ban":
targetUser, err := users.CascadeGet(elementID) targetUser, err := users.CascadeGet(elementID)
if err != nil { if err != nil {
targetUser = &User{Name:"Unknown"} targetUser = &User{Name:"Unknown",Slug:"unknown"}
} }
action = "<a href='" + build_profile_url(elementID) + "'>" + targetUser.Name + "</a> was banned by <a href='" + build_profile_url(actorID) + "'>"+actor.Name+"</a>" action = "<a href='" + build_profile_url(targetUser.Slug,elementID) + "'>" + targetUser.Name + "</a> was banned by <a href='" + build_profile_url(actor.Slug,actorID) + "'>"+actor.Name+"</a>"
case "unban": case "unban":
targetUser, err := users.CascadeGet(elementID) targetUser, err := users.CascadeGet(elementID)
if err != nil { if err != nil {
targetUser = &User{Name:"Unknown"} targetUser = &User{Name:"Unknown",Slug:"unknown"}
} }
action = "<a href='" + build_profile_url(elementID) + "'>" + targetUser.Name + "</a> was unbanned by <a href='" + build_profile_url(actorID) + "'>"+actor.Name+"</a>" action = "<a href='" + build_profile_url(targetUser.Slug,elementID) + "'>" + targetUser.Name + "</a> was unbanned by <a href='" + build_profile_url(actor.Slug,actorID) + "'>"+actor.Name+"</a>"
case "activate": case "activate":
targetUser, err := users.CascadeGet(elementID) targetUser, err := users.CascadeGet(elementID)
if err != nil { if err != nil {
targetUser = &User{Name:"Unknown"} targetUser = &User{Name:"Unknown",Slug:"unknown"}
} }
action = "<a href='" + build_profile_url(elementID) + "'>" + targetUser.Name + "</a> was activated by <a href='" + build_profile_url(actorID) + "'>"+actor.Name+"</a>" action = "<a href='" + build_profile_url(targetUser.Slug,elementID) + "'>" + targetUser.Name + "</a> was activated by <a href='" + build_profile_url(actor.Slug,actorID) + "'>"+actor.Name+"</a>"
default: default:
action = "Unknown action '" + action + "' by <a href='" + build_profile_url(actorID) + "'>"+actor.Name+"</a>" action = "Unknown action '" + action + "' by <a href='" + build_profile_url(actor.Slug,actorID) + "'>"+actor.Name+"</a>"
} }
logs = append(logs, Log{Action:template.HTML(action),IPAddress:ipaddress,DoneAt:doneAt}) logs = append(logs, Log{Action:template.HTML(action),IPAddress:ipaddress,DoneAt:doneAt})
} }

View File

@ -306,6 +306,11 @@ func rebuild_forum_permissions(fid int) error {
if debug { if debug {
log.Print("Loading the forum permissions") log.Print("Loading the forum permissions")
} }
forums, err := fstore.GetAll()
if err != nil {
return err
}
rows, err := db.Query("select gid, permissions from forums_permissions where fid = ? order by gid asc", fid) rows, err := db.Query("select gid, permissions from forums_permissions where fid = ? order by gid asc", fid)
if err != nil { if err != nil {
return err return err
@ -373,6 +378,11 @@ func rebuild_forum_permissions(fid int) error {
} }
func build_forum_permissions() error { func build_forum_permissions() error {
forums, err := fstore.GetAll()
if err != nil {
return err
}
rows, err := get_forums_permissions_stmt.Query() rows, err := get_forums_permissions_stmt.Query()
if err != nil { if err != nil {
return err return err

View File

@ -9,6 +9,7 @@ type Reply struct /* Should probably rename this to ReplyUser and rename ReplySh
Content string Content string
ContentHtml string ContentHtml string
CreatedBy int CreatedBy int
UserSlug string
CreatedByName string CreatedByName string
Group int Group int
CreatedAt string CreatedAt string

143
routes.go
View File

@ -15,14 +15,11 @@ import (
"net/http" "net/http"
"html" "html"
"html/template" "html/template"
"database/sql"
"./query_gen/lib" "./query_gen/lib"
"golang.org/x/crypto/bcrypt"
) )
import _ "github.com/go-sql-driver/mysql"
import "golang.org/x/crypto/bcrypt"
// A blank list to fill out that parameter in Page for routes which don't use it // A blank list to fill out that parameter in Page for routes which don't use it
var tList []interface{} var tList []interface{}
var nList []string var nList []string
@ -66,7 +63,7 @@ func route_static(w http.ResponseWriter, r *http.Request){
os.Exit(0) os.Exit(0)
} }
// Deprecated: Test route to see which is faster // Deprecated: Test route to see which file serving method is faster
func route_fstatic(w http.ResponseWriter, r *http.Request){ func route_fstatic(w http.ResponseWriter, r *http.Request){
http.ServeFile(w,r,r.URL.Path) http.ServeFile(w,r,r.URL.Path)
}*/ }*/
@ -76,6 +73,8 @@ func route_overview(w http.ResponseWriter, r *http.Request){
if !ok { if !ok {
return return
} }
BuildWidgets("overview",nil,&headerVars)
pi := Page{"Overview",user,headerVars,tList,nil} pi := Page{"Overview",user,headerVars,tList,nil}
err := templates.ExecuteTemplate(w,"overview.html",pi) err := templates.ExecuteTemplate(w,"overview.html",pi)
if err != nil { if err != nil {
@ -88,11 +87,13 @@ func route_custom_page(w http.ResponseWriter, r *http.Request){
if !ok { if !ok {
return return
} }
name := r.URL.Path[len("/pages/"):] name := r.URL.Path[len("/pages/"):]
if templates.Lookup("page_" + name) == nil { if templates.Lookup("page_" + name) == nil {
NotFound(w,r) NotFound(w,r)
return return
} }
BuildWidgets("custom_page",name,&headerVars)
err := templates.ExecuteTemplate(w,"page_" + name,Page{"Page",user,headerVars,tList,nil}) err := templates.ExecuteTemplate(w,"page_" + name,Page{"Page",user,headerVars,tList,nil})
if err != nil { if err != nil {
@ -105,12 +106,13 @@ func route_topics(w http.ResponseWriter, r *http.Request){
if !ok { if !ok {
return return
} }
BuildWidgets("topics",nil,&headerVars)
var qlist string var qlist string
var fidList []interface{} var fidList []interface{}
group := groups[user.Group] group := groups[user.Group]
for _, fid := range group.CanSee { for _, fid := range group.CanSee {
if forums[fid].Name != "" { if fstore.DirtyGet(fid).Name != "" {
fidList = append(fidList,strconv.Itoa(fid)) fidList = append(fidList,strconv.Itoa(fid))
qlist += "?," qlist += "?,"
} }
@ -138,6 +140,9 @@ func route_topics(w http.ResponseWriter, r *http.Request){
return return
} }
topicItem.Slug = name_to_slug(topicItem.Title)
topicItem.UserSlug = name_to_slug(topicItem.CreatedByName)
if topicItem.Avatar != "" { if topicItem.Avatar != "" {
if topicItem.Avatar[0] == '.' { if topicItem.Avatar[0] == '.' {
topicItem.Avatar = "/uploads/avatar_" + strconv.Itoa(topicItem.CreatedBy) + topicItem.Avatar topicItem.Avatar = "/uploads/avatar_" + strconv.Itoa(topicItem.CreatedBy) + topicItem.Avatar
@ -147,7 +152,7 @@ func route_topics(w http.ResponseWriter, r *http.Request){
} }
if topicItem.ParentID >= 0 { if topicItem.ParentID >= 0 {
topicItem.ForumName = forums[topicItem.ParentID].Name topicItem.ForumName = fstore.DirtyGet(topicItem.ParentID).Name
} else { } else {
topicItem.ForumName = "" topicItem.ForumName = ""
} }
@ -212,9 +217,21 @@ func route_forum(w http.ResponseWriter, r *http.Request, sfid string){
return return
} }
// TO-DO: Fix this double-check
forum, err := fstore.CascadeGet(fid)
if err == ErrNoRows {
NotFound(w,r)
return
} else if err != nil {
InternalError(err,w,r)
return
}
BuildWidgets("view_forum",&forum,&headerVars)
// Calculate the offset // Calculate the offset
var offset int var offset int
last_page := int(forums[fid].TopicCount / items_per_page) + 1 last_page := int(forum.TopicCount / items_per_page) + 1
if page > 1 { if page > 1 {
offset = (items_per_page * page) - items_per_page offset = (items_per_page * page) - items_per_page
} else if page == -1 { } else if page == -1 {
@ -238,6 +255,9 @@ func route_forum(w http.ResponseWriter, r *http.Request, sfid string){
return return
} }
topicItem.Slug = name_to_slug(topicItem.Title)
topicItem.UserSlug = name_to_slug(topicItem.CreatedByName)
if topicItem.Avatar != "" { if topicItem.Avatar != "" {
if topicItem.Avatar[0] == '.' { if topicItem.Avatar[0] == '.' {
topicItem.Avatar = "/uploads/avatar_" + strconv.Itoa(topicItem.CreatedBy) + topicItem.Avatar topicItem.Avatar = "/uploads/avatar_" + strconv.Itoa(topicItem.CreatedBy) + topicItem.Avatar
@ -263,7 +283,7 @@ func route_forum(w http.ResponseWriter, r *http.Request, sfid string){
} }
rows.Close() rows.Close()
pi := ForumPage{forums[fid].Name,user,headerVars,topicList,forums[fid],page,last_page,extData} pi := ForumPage{forum.Name,user,headerVars,topicList,*forum,page,last_page,extData}
if template_forum_handle != nil { if template_forum_handle != nil {
template_forum_handle(pi,w) template_forum_handle(pi,w)
} else { } else {
@ -283,6 +303,7 @@ func route_forums(w http.ResponseWriter, r *http.Request){
if !ok { if !ok {
return return
} }
BuildWidgets("forums",nil,&headerVars)
var forumList []Forum var forumList []Forum
var err error var err error
@ -290,7 +311,7 @@ func route_forums(w http.ResponseWriter, r *http.Request){
//fmt.Println(group.CanSee) //fmt.Println(group.CanSee)
for _, fid := range group.CanSee { for _, fid := range group.CanSee {
//fmt.Println(forums[fid]) //fmt.Println(forums[fid])
var forum Forum = forums[fid] var forum Forum = *fstore.DirtyGet(fid)
if forum.Active && forum.Name != "" { if forum.Active && forum.Name != "" {
if forum.LastTopicID != 0 { if forum.LastTopicID != 0 {
forum.LastTopicTime, err = relative_time(forum.LastTopicTime) forum.LastTopicTime, err = relative_time(forum.LastTopicTime)
@ -326,7 +347,14 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
var replyList []Reply var replyList []Reply
page, _ = strconv.Atoi(r.FormValue("page")) page, _ = strconv.Atoi(r.FormValue("page"))
tid, err := strconv.Atoi(r.URL.Path[len("/topic/"):])
// SEO URLs...
halves := strings.Split(r.URL.Path[len("/topic/"):],".")
if len(halves) < 2 {
halves = append(halves,halves[0])
}
tid, err := strconv.Atoi(halves[1])
if err != nil { if err != nil {
PreError("The provided TopicID is not a valid number.",w,r) PreError("The provided TopicID is not a valid number.",w,r)
return return
@ -334,7 +362,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
// Get the topic... // Get the topic...
topic, err := get_topicuser(tid) topic, err := get_topicuser(tid)
if err == sql.ErrNoRows { if err == ErrNoRows {
NotFound(w,r) NotFound(w,r)
return return
} else if err != nil { } else if err != nil {
@ -353,6 +381,8 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
return return
} }
BuildWidgets("view_topic",&topic,&headerVars)
topic.Content = parse_message(topic.Content) topic.Content = parse_message(topic.Content)
topic.ContentLines = strings.Count(topic.Content,"\n") topic.ContentLines = strings.Count(topic.Content,"\n")
@ -395,7 +425,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
// Get the replies.. // 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, items_per_page)
if err == sql.ErrNoRows { 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) 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 return
} else if err != nil { } else if err != nil {
@ -411,6 +441,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
return return
} }
replyItem.UserSlug = name_to_slug(replyItem.CreatedByName)
replyItem.ParentID = topic.ID replyItem.ParentID = topic.ID
replyItem.ContentHtml = parse_message(replyItem.Content) replyItem.ContentHtml = parse_message(replyItem.Content)
replyItem.ContentLines = strings.Count(replyItem.Content,"\n") replyItem.ContentLines = strings.Count(replyItem.Content,"\n")
@ -451,16 +482,16 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
if replyItem.ActionType != "" { if replyItem.ActionType != "" {
switch(replyItem.ActionType) { switch(replyItem.ActionType) {
case "lock": case "lock":
replyItem.ActionType = "This topic has been locked by <a href='" + build_profile_url(replyItem.CreatedBy) + "'>" + replyItem.CreatedByName + "</a>" replyItem.ActionType = "This topic has been locked by <a href='" + build_profile_url(replyItem.UserSlug,replyItem.CreatedBy) + "'>" + replyItem.CreatedByName + "</a>"
replyItem.ActionIcon = "&#x1F512;&#xFE0E" replyItem.ActionIcon = "&#x1F512;&#xFE0E"
case "unlock": case "unlock":
replyItem.ActionType = "This topic has been reopened by <a href='" + build_profile_url(replyItem.CreatedBy) + "'>" + replyItem.CreatedByName + "</a>" replyItem.ActionType = "This topic has been reopened by <a href='" + build_profile_url(replyItem.UserSlug,replyItem.CreatedBy) + "'>" + replyItem.CreatedByName + "</a>"
replyItem.ActionIcon = "&#x1F513;&#xFE0E" replyItem.ActionIcon = "&#x1F513;&#xFE0E"
case "stick": case "stick":
replyItem.ActionType = "This topic has been pinned by <a href='" + build_profile_url(replyItem.CreatedBy) + "'>" + replyItem.CreatedByName + "</a>" replyItem.ActionType = "This topic has been pinned by <a href='" + build_profile_url(replyItem.UserSlug,replyItem.CreatedBy) + "'>" + replyItem.CreatedByName + "</a>"
replyItem.ActionIcon = "&#x1F4CC;&#xFE0E" replyItem.ActionIcon = "&#x1F4CC;&#xFE0E"
case "unstick": case "unstick":
replyItem.ActionType = "This topic has been unpinned by <a href='" + build_profile_url(replyItem.CreatedBy) + "'>" + replyItem.CreatedByName + "</a>" replyItem.ActionType = "This topic has been unpinned by <a href='" + build_profile_url(replyItem.UserSlug,replyItem.CreatedBy) + "'>" + replyItem.CreatedByName + "</a>"
replyItem.ActionIcon = "&#x1F4CC;&#xFE0E" replyItem.ActionIcon = "&#x1F4CC;&#xFE0E"
default: default:
replyItem.ActionType = replyItem.ActionType + " has happened" replyItem.ActionType = replyItem.ActionType + " has happened"
@ -508,7 +539,13 @@ func route_profile(w http.ResponseWriter, r *http.Request){
var replyCss template.CSS var replyCss template.CSS
var replyList []Reply var replyList []Reply
pid, err := strconv.Atoi(r.URL.Path[len("/user/"):]) // SEO URLs...
halves := strings.Split(r.URL.Path[len("/user/"):],".")
if len(halves) < 2 {
halves = append(halves,halves[0])
}
pid, err := strconv.Atoi(halves[1])
if err != nil { if err != nil {
LocalError("The provided User ID is not a valid number.",w,r,user) LocalError("The provided User ID is not a valid number.",w,r,user)
return return
@ -521,7 +558,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
} else { } else {
// Fetch the user data // Fetch the user data
puser, err = users.CascadeGet(pid) puser, err = users.CascadeGet(pid)
if err == sql.ErrNoRows { if err == ErrNoRows {
NotFound(w,r) NotFound(w,r)
return return
} else if err != nil { } else if err != nil {
@ -570,7 +607,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
replyLiked := false replyLiked := false
replyLikeCount := 0 replyLikeCount := 0
replyList = append(replyList, Reply{rid,puser.ID,replyContent,parse_message(replyContent),replyCreatedBy,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,replyCss,replyLines,replyTag,"","","",0,"",replyLiked,replyLikeCount,"",""})
} }
err = rows.Err() err = rows.Err()
if err != nil { if err != nil {
@ -612,8 +649,9 @@ func route_topic_create(w http.ResponseWriter, r *http.Request, sfid string){
var forumList []Forum var forumList []Forum
group := groups[user.Group] group := groups[user.Group]
for _, fid := range group.CanSee { for _, fid := range group.CanSee {
if forums[fid].Active && forums[fid].Name != "" { forum := fstore.DirtyGet(fid)
forumList = append(forumList, forums[fid]) if forum.Active && forum.Name != "" {
forumList = append(forumList, *forum)
} }
} }
@ -671,23 +709,11 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
return return
} }
_, err = add_topics_to_forum_stmt.Exec(1,fid) err = fstore.IncrementTopicCount(fid)
if err != nil { if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
forums[fid].TopicCount -= 1
_, err = update_forum_cache_stmt.Exec(topic_name,lastId,user.Name,user.ID,fid)
if err != nil {
InternalError(err,w,r)
return
}
forums[fid].LastTopic = topic_name
forums[fid].LastTopicID = int(lastId)
forums[fid].LastReplyer = user.Name
forums[fid].LastReplyerID = user.ID
forums[fid].LastTopicTime = ""
_, err = add_subscription_stmt.Exec(user.ID,lastId,"topic") _, err = add_subscription_stmt.Exec(user.ID,lastId,"topic")
if err != nil { if err != nil {
@ -701,6 +727,11 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
err = fstore.UpdateLastTopic(topic_name,int(lastId),user.Name,user.ID,"",fid)
if err != nil && err != ErrNoRows {
InternalError(err,w,r)
}
} }
func route_create_reply(w http.ResponseWriter, r *http.Request) { func route_create_reply(w http.ResponseWriter, r *http.Request) {
@ -716,7 +747,7 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
} }
topic, err := topics.CascadeGet(tid) topic, err := topics.CascadeGet(tid)
if err == sql.ErrNoRows { if err == ErrNoRows {
PreError("Couldn't find the parent topic",w,r) PreError("Couldn't find the parent topic",w,r)
return return
} else if err != nil { } else if err != nil {
@ -782,7 +813,7 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
// Reload the topic... // Reload the topic...
err = topics.Load(tid) err = topics.Load(tid)
if err != nil && err == sql.ErrNoRows { if err != nil && err == ErrNoRows {
LocalError("The destination no longer exists",w,r,user) LocalError("The destination no longer exists",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -812,7 +843,7 @@ func route_like_topic(w http.ResponseWriter, r *http.Request) {
} }
topic, err := topics.CascadeGet(tid) topic, err := topics.CascadeGet(tid)
if err == sql.ErrNoRows { if err == ErrNoRows {
PreError("The requested topic doesn't exist.",w,r) PreError("The requested topic doesn't exist.",w,r)
return return
} else if err != nil { } else if err != nil {
@ -835,16 +866,16 @@ func route_like_topic(w http.ResponseWriter, r *http.Request) {
} }
err = has_liked_topic_stmt.QueryRow(user.ID,tid).Scan(&tid) err = has_liked_topic_stmt.QueryRow(user.ID,tid).Scan(&tid)
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
} else if err != sql.ErrNoRows { } else if err != ErrNoRows {
LocalError("You already liked this!",w,r,user) LocalError("You already liked this!",w,r,user)
return return
} }
_, err = users.CascadeGet(topic.CreatedBy) _, err = users.CascadeGet(topic.CreatedBy)
if err != nil && err == sql.ErrNoRows { if err != nil && err == ErrNoRows {
LocalError("The target user doesn't exist",w,r,user) LocalError("The target user doesn't exist",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -887,7 +918,7 @@ func route_like_topic(w http.ResponseWriter, r *http.Request) {
// Reload the topic... // Reload the topic...
err = topics.Load(tid) err = topics.Load(tid)
if err != nil && err == sql.ErrNoRows { if err != nil && err == ErrNoRows {
LocalError("The liked topic no longer exists",w,r,user) LocalError("The liked topic no longer exists",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -912,7 +943,7 @@ func route_reply_like_submit(w http.ResponseWriter, r *http.Request) {
} }
reply, err := get_reply(rid) reply, err := get_reply(rid)
if err == sql.ErrNoRows { if err == ErrNoRows {
PreError("You can't like something which doesn't exist!",w,r) PreError("You can't like something which doesn't exist!",w,r)
return return
} else if err != nil { } else if err != nil {
@ -922,7 +953,7 @@ func route_reply_like_submit(w http.ResponseWriter, r *http.Request) {
var fid int var fid int
err = get_topic_fid_stmt.QueryRow(reply.ParentID).Scan(&fid) err = get_topic_fid_stmt.QueryRow(reply.ParentID).Scan(&fid)
if err == sql.ErrNoRows { if err == ErrNoRows {
PreError("The parent topic doesn't exist.",w,r) PreError("The parent topic doesn't exist.",w,r)
return return
} else if err != nil { } else if err != nil {
@ -945,16 +976,16 @@ func route_reply_like_submit(w http.ResponseWriter, r *http.Request) {
} }
err = has_liked_reply_stmt.QueryRow(user.ID, rid).Scan(&rid) err = has_liked_reply_stmt.QueryRow(user.ID, rid).Scan(&rid)
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
} else if err != sql.ErrNoRows { } else if err != ErrNoRows {
LocalError("You already liked this!",w,r,user) LocalError("You already liked this!",w,r,user)
return return
} }
_, err = users.CascadeGet(reply.CreatedBy) _, err = users.CascadeGet(reply.CreatedBy)
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
LocalError("The target user doesn't exist",w,r,user) LocalError("The target user doesn't exist",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -1033,7 +1064,7 @@ func route_profile_reply_create(w http.ResponseWriter, r *http.Request) {
var user_name string var user_name string
err = get_user_name_stmt.QueryRow(uid).Scan(&user_name) err = get_user_name_stmt.QueryRow(uid).Scan(&user_name)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("The profile you're trying to post on doesn't exist.",w,r,user) LocalError("The profile you're trying to post on doesn't exist.",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -1080,7 +1111,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request, sitem_id string
var title, content string var title, content string
if item_type == "reply" { if item_type == "reply" {
reply, err := get_reply(item_id) reply, err := get_reply(item_id)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("We were unable to find the reported post",w,r,user) LocalError("We were unable to find the reported post",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -1089,7 +1120,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request, sitem_id string
} }
topic, err := topics.CascadeGet(reply.ParentID) topic, err := topics.CascadeGet(reply.ParentID)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("We weren't able to find the topic the reported post is supposed to be in",w,r,user) LocalError("We weren't able to find the topic the reported post is supposed to be in",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -1101,7 +1132,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request, sitem_id string
content = reply.Content + "\n\nOriginal Post: #rid-" + strconv.Itoa(item_id) content = reply.Content + "\n\nOriginal Post: #rid-" + strconv.Itoa(item_id)
} else if item_type == "user-reply" { } else if item_type == "user-reply" {
user_reply, err := get_user_reply(item_id) user_reply, err := get_user_reply(item_id)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("We weren't able to find the reported post",w,r,user) LocalError("We weren't able to find the reported post",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -1110,7 +1141,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request, sitem_id string
} }
err = get_user_name_stmt.QueryRow(user_reply.ParentID).Scan(&title) err = get_user_name_stmt.QueryRow(user_reply.ParentID).Scan(&title)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("We weren't able to find the profile the reported post is supposed to be on",w,r,user) LocalError("We weren't able to find the profile the reported post is supposed to be on",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -1121,7 +1152,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request, sitem_id string
content = user_reply.Content + "\n\nOriginal Post: @" + strconv.Itoa(user_reply.ParentID) content = user_reply.Content + "\n\nOriginal Post: @" + strconv.Itoa(user_reply.ParentID)
} else if item_type == "topic" { } else if item_type == "topic" {
err = get_topic_basic_stmt.QueryRow(item_id).Scan(&title,&content) err = get_topic_basic_stmt.QueryRow(item_id).Scan(&title,&content)
if err == sql.ErrNoRows { if err == ErrNoRows {
NotFound(w,r) NotFound(w,r)
return return
} else if err != nil { } else if err != nil {
@ -1142,7 +1173,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request, sitem_id string
var count int var count int
rows, err := report_exists_stmt.Query(item_type + "_" + strconv.Itoa(item_id)) rows, err := report_exists_stmt.Query(item_type + "_" + strconv.Itoa(item_id))
if err != nil && err != sql.ErrNoRows { if err != nil && err != ErrNoRows {
InternalError(err,w,r) InternalError(err,w,r)
return return
} }
@ -1220,7 +1251,7 @@ func route_account_own_edit_critical_submit(w http.ResponseWriter, r *http.Reque
confirm_password := r.PostFormValue("account-confirm-password") confirm_password := r.PostFormValue("account-confirm-password")
err = get_password_stmt.QueryRow(user.ID).Scan(&real_password, &salt) err = get_password_stmt.QueryRow(user.ID).Scan(&real_password, &salt)
if err == sql.ErrNoRows { if err == ErrNoRows {
LocalError("Your account no longer exists.",w,r,user) LocalError("Your account no longer exists.",w,r,user)
return return
} else if err != nil { } else if err != nil {
@ -1747,7 +1778,7 @@ func route_api(w http.ResponseWriter, r *http.Request) {
var msgCount int var msgCount int
err = get_activity_count_by_watcher_stmt.QueryRow(user.ID).Scan(&msgCount) err = get_activity_count_by_watcher_stmt.QueryRow(user.ID).Scan(&msgCount)
if err == sql.ErrNoRows { if err == ErrNoRows {
PreError("Couldn't find the parent topic",w,r) PreError("Couldn't find the parent topic",w,r)
return return
} else if err != nil { } else if err != nil {

View File

@ -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. */ /* 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 // +build !no_templategen
package main package main
import "io"
import "strconv" import "strconv"
import "io"
func init() { func init() {
template_forum_handle = template_forum template_forum_handle = template_forum
@ -38,18 +38,20 @@ w.Write(header_8)
w.Write(menu_0) w.Write(menu_0)
if tmpl_forum_vars.CurrentUser.Loggedin { if tmpl_forum_vars.CurrentUser.Loggedin {
w.Write(menu_1) w.Write(menu_1)
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.CurrentUser.ID))) w.Write([]byte(tmpl_forum_vars.CurrentUser.Slug))
w.Write(menu_2) w.Write(menu_2)
if tmpl_forum_vars.CurrentUser.Is_Super_Mod { w.Write([]byte(strconv.Itoa(tmpl_forum_vars.CurrentUser.ID)))
w.Write(menu_3) w.Write(menu_3)
} if tmpl_forum_vars.CurrentUser.Is_Super_Mod {
w.Write(menu_4) w.Write(menu_4)
w.Write([]byte(tmpl_forum_vars.CurrentUser.Session))
w.Write(menu_5)
} else {
w.Write(menu_6)
} }
w.Write(menu_5)
w.Write([]byte(tmpl_forum_vars.CurrentUser.Session))
w.Write(menu_6)
} else {
w.Write(menu_7) w.Write(menu_7)
}
w.Write(menu_8)
w.Write(header_9) w.Write(header_9)
if tmpl_forum_vars.Header.Widgets.RightSidebar != "" { if tmpl_forum_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_10) w.Write(header_10)
@ -113,29 +115,33 @@ w.Write([]byte(strconv.Itoa(item.PostCount)))
w.Write(forum_20) w.Write(forum_20)
w.Write([]byte(item.LastReplyAt)) w.Write([]byte(item.LastReplyAt))
w.Write(forum_21) w.Write(forum_21)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(item.Slug))
w.Write(forum_22) w.Write(forum_22)
w.Write([]byte(item.Title)) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(forum_23) w.Write(forum_23)
w.Write([]byte(strconv.Itoa(item.CreatedBy))) w.Write([]byte(item.Title))
w.Write(forum_24) w.Write(forum_24)
w.Write([]byte(item.CreatedByName)) w.Write([]byte(item.UserSlug))
w.Write(forum_25) w.Write(forum_25)
if item.Is_Closed { w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(forum_26) w.Write(forum_26)
} w.Write([]byte(item.CreatedByName))
w.Write(forum_27) w.Write(forum_27)
if item.Is_Closed {
w.Write(forum_28)
}
w.Write(forum_29)
} }
} else { } else {
w.Write(forum_28)
if tmpl_forum_vars.CurrentUser.Perms.CreateTopic {
w.Write(forum_29)
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
w.Write(forum_30) w.Write(forum_30)
} if tmpl_forum_vars.CurrentUser.Perms.CreateTopic {
w.Write(forum_31) w.Write(forum_31)
} w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
w.Write(forum_32) w.Write(forum_32)
}
w.Write(forum_33)
}
w.Write(forum_34)
w.Write(footer_0) w.Write(footer_0)
if tmpl_forum_vars.Header.Widgets.RightSidebar != "" { if tmpl_forum_vars.Header.Widgets.RightSidebar != "" {
w.Write(footer_1) w.Write(footer_1)

View File

@ -38,18 +38,20 @@ w.Write(header_8)
w.Write(menu_0) w.Write(menu_0)
if tmpl_forums_vars.CurrentUser.Loggedin { if tmpl_forums_vars.CurrentUser.Loggedin {
w.Write(menu_1) w.Write(menu_1)
w.Write([]byte(strconv.Itoa(tmpl_forums_vars.CurrentUser.ID))) w.Write([]byte(tmpl_forums_vars.CurrentUser.Slug))
w.Write(menu_2) w.Write(menu_2)
if tmpl_forums_vars.CurrentUser.Is_Super_Mod { w.Write([]byte(strconv.Itoa(tmpl_forums_vars.CurrentUser.ID)))
w.Write(menu_3) w.Write(menu_3)
} if tmpl_forums_vars.CurrentUser.Is_Super_Mod {
w.Write(menu_4) w.Write(menu_4)
w.Write([]byte(tmpl_forums_vars.CurrentUser.Session))
w.Write(menu_5)
} else {
w.Write(menu_6)
} }
w.Write(menu_5)
w.Write([]byte(tmpl_forums_vars.CurrentUser.Session))
w.Write(menu_6)
} else {
w.Write(menu_7) w.Write(menu_7)
}
w.Write(menu_8)
w.Write(header_9) w.Write(header_9)
if tmpl_forums_vars.Header.Widgets.RightSidebar != "" { if tmpl_forums_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_10) w.Write(header_10)
@ -72,43 +74,51 @@ w.Write(forums_2)
w.Write(forums_3) w.Write(forums_3)
if item.Desc != "" { if item.Desc != "" {
w.Write(forums_4) w.Write(forums_4)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(item.Slug))
w.Write(forums_5) w.Write(forums_5)
w.Write([]byte(item.Name)) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(forums_6) w.Write(forums_6)
w.Write([]byte(item.Desc)) w.Write([]byte(item.Name))
w.Write(forums_7) w.Write(forums_7)
} else { w.Write([]byte(item.Desc))
if item.LastTopicTime != "" {
w.Write(forums_8) w.Write(forums_8)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(forums_9)
w.Write([]byte(item.Name))
w.Write(forums_10)
} else { } else {
w.Write(forums_11)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(forums_12)
w.Write([]byte(item.Name))
w.Write(forums_13)
}
}
w.Write(forums_14)
w.Write([]byte(strconv.Itoa(item.LastTopicID)))
w.Write(forums_15)
w.Write([]byte(item.LastTopic))
w.Write(forums_16)
if item.LastTopicTime != "" { if item.LastTopicTime != "" {
w.Write(forums_17) w.Write(forums_9)
w.Write([]byte(item.LastTopicTime)) w.Write([]byte(item.Slug))
w.Write(forums_18) w.Write(forums_10)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(forums_11)
w.Write([]byte(item.Name))
w.Write(forums_12)
} else {
w.Write(forums_13)
w.Write([]byte(item.Slug))
w.Write(forums_14)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(forums_15)
w.Write([]byte(item.Name))
w.Write(forums_16)
} }
}
w.Write(forums_17)
w.Write([]byte(item.LastTopicSlug))
w.Write(forums_18)
w.Write([]byte(strconv.Itoa(item.LastTopicID)))
w.Write(forums_19) w.Write(forums_19)
w.Write([]byte(item.LastTopic))
w.Write(forums_20)
if item.LastTopicTime != "" {
w.Write(forums_21)
w.Write([]byte(item.LastTopicTime))
w.Write(forums_22)
}
w.Write(forums_23)
} }
} else { } else {
w.Write(forums_20) w.Write(forums_24)
} }
w.Write(forums_21) w.Write(forums_25)
w.Write(footer_0) w.Write(footer_0)
if tmpl_forums_vars.Header.Widgets.RightSidebar != "" { if tmpl_forums_vars.Header.Widgets.RightSidebar != "" {
w.Write(footer_1) w.Write(footer_1)

View File

@ -40,18 +40,19 @@ var menu_0 []byte = []byte(`<div class="nav">
var menu_1 []byte = []byte(` var menu_1 []byte = []byte(`
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li> <li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_profile"><a href="/user/`) <li class="menu_left menu_profile"><a href="/user/`)
var menu_2 []byte = []byte(`">Profile</a></li> var menu_2 []byte = []byte(`.`)
var menu_3 []byte = []byte(`">Profile</a></li>
`) `)
var menu_3 []byte = []byte(`<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>`) var menu_4 []byte = []byte(`<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>`)
var menu_4 []byte = []byte(` var menu_5 []byte = []byte(`
<li class="menu_left menu_logout"><a href="/accounts/logout/?session=`) <li class="menu_left menu_logout"><a href="/accounts/logout/?session=`)
var menu_5 []byte = []byte(`">Logout</a></li> var menu_6 []byte = []byte(`">Logout</a></li>
`) `)
var menu_6 []byte = []byte(` var menu_7 []byte = []byte(`
<li class="menu_left menu_register"><a href="/accounts/create/">Register</a></li> <li class="menu_left menu_register"><a href="/accounts/create/">Register</a></li>
<li class="menu_left menu_login"><a href="/accounts/login/">Login</a></li> <li class="menu_left menu_login"><a href="/accounts/login/">Login</a></li>
`) `)
var menu_7 []byte = []byte(` var menu_8 []byte = []byte(`
<li id="general_alerts" class="menu_right menu_alerts"> <li id="general_alerts" class="menu_right menu_alerts">
<div class="alert_bell">🔔</div> <div class="alert_bell">🔔</div>
<div class="alert_counter"></div> <div class="alert_counter"></div>
@ -91,7 +92,7 @@ var topic_10 []byte = []byte(` style="background-color:#FFFFEA;"`)
var topic_11 []byte = []byte(` style="background-color:#eaeaea;"`) var topic_11 []byte = []byte(` style="background-color:#eaeaea;"`)
var topic_12 []byte = []byte(`> var topic_12 []byte = []byte(`>
<a class='topic_name hide_on_edit'>`) <a class='topic_name hide_on_edit'>`)
var topic_13 []byte = []byte(`</a> var topic_13 []byte = []byte(`</a>
`) `)
var topic_14 []byte = []byte(`<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='Status: Closed' style="font-weight:normal;float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>`) var topic_14 []byte = []byte(`<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='Status: Closed' style="font-weight:normal;float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>`)
var topic_15 []byte = []byte(` var topic_15 []byte = []byte(`
@ -120,105 +121,103 @@ var topic_24 []byte = []byte(`">
var topic_25 []byte = []byte(`</p> var topic_25 []byte = []byte(`</p>
<textarea name="topic_content" class="show_on_edit topic_content_input">`) <textarea name="topic_content" class="show_on_edit topic_content_input">`)
var topic_26 []byte = []byte(`</textarea> var topic_26 []byte = []byte(`</textarea>
<span class="controls"> <span class="controls">
<a href="/user/`) <a href="/user/`)
var topic_27 []byte = []byte(`" class="username real_username">`) var topic_27 []byte = []byte(`.`)
var topic_28 []byte = []byte(`</a>&nbsp;&nbsp; var topic_28 []byte = []byte(`" class="username real_username">`)
var topic_29 []byte = []byte(`</a>&nbsp;&nbsp;
`) `)
var topic_29 []byte = []byte(`<a href="/topic/like/submit/`) var topic_30 []byte = []byte(`<a href="/topic/like/submit/`)
var topic_30 []byte = []byte(`" class="mod_button" title="Love it" style="color:#202020;"> var topic_31 []byte = []byte(`" class="mod_button" title="Love it" style="color:#202020;">
<button class="username like_label" style="`) <button class="username like_label" style="`)
var topic_31 []byte = []byte(`background-color:/*#eaffea*/#D6FFD6;`) var topic_32 []byte = []byte(`background-color:/*#eaffea*/#D6FFD6;`)
var topic_32 []byte = []byte(`"></button></a>`) var topic_33 []byte = []byte(`"></button></a>`)
var topic_33 []byte = []byte(`<a href='/topic/edit/`) var topic_34 []byte = []byte(`<a href='/topic/edit/`)
var topic_34 []byte = []byte(`' class="mod_button open_edit" style="font-weight:normal;" title="Edit Topic"><button class="username edit_label"></button></a>`) var topic_35 []byte = []byte(`' class="mod_button open_edit" style="font-weight:normal;" title="Edit Topic"><button class="username edit_label"></button></a>`)
var topic_35 []byte = []byte(`<a href='/topic/delete/submit/`) var topic_36 []byte = []byte(`<a href='/topic/delete/submit/`)
var topic_36 []byte = []byte(`' class="mod_button" style="font-weight:normal;" title="Delete Topic"><button class="username trash_label"></button></a>`) var topic_37 []byte = []byte(`' class="mod_button" style="font-weight:normal;" title="Delete Topic"><button class="username trash_label"></button></a>`)
var topic_37 []byte = []byte(`<a class="mod_button" href='/topic/unstick/submit/`) var topic_38 []byte = []byte(`<a class="mod_button" href='/topic/unstick/submit/`)
var topic_38 []byte = []byte(`' style="font-weight:normal;" title="Unpin Topic"><button class="username unpin_label"></button></a>`) var topic_39 []byte = []byte(`' style="font-weight:normal;" title="Unpin Topic"><button class="username unpin_label"></button></a>`)
var topic_39 []byte = []byte(`<a href='/topic/stick/submit/`) var topic_40 []byte = []byte(`<a href='/topic/stick/submit/`)
var topic_40 []byte = []byte(`' class="mod_button" style="font-weight:normal;" title="Pin Topic"><button class="username pin_label"></button></a>`) var topic_41 []byte = []byte(`' class="mod_button" style="font-weight:normal;" title="Pin Topic"><button class="username pin_label"></button></a>`)
var topic_41 []byte = []byte(` var topic_42 []byte = []byte(`
<a class="mod_button" href="/report/submit/`) <a class="mod_button" href="/report/submit/`)
var topic_42 []byte = []byte(`?session=`) var topic_43 []byte = []byte(`?session=`)
var topic_43 []byte = []byte(`&type=topic" class="mod_button report_item" style="font-weight:normal;" title="Flag Topic"><button class="username flag_label"></button></a> var topic_44 []byte = []byte(`&type=topic" class="mod_button report_item" style="font-weight:normal;" title="Flag Topic"><button class="username flag_label"></button></a>
`) `)
var topic_44 []byte = []byte(`<a class="username hide_on_micro like_count">`) var topic_45 []byte = []byte(`<a class="username hide_on_micro like_count">`)
var topic_45 []byte = []byte(`</a><a class="username hide_on_micro like_count_label" title="Like Count"></a>`) var topic_46 []byte = []byte(`</a><a class="username hide_on_micro like_count_label" title="Like Count"></a>`)
var topic_46 []byte = []byte(`<a class="username hide_on_micro" style="float:right;color:#505050;font-size:16px;">`) var topic_47 []byte = []byte(`<a class="username hide_on_micro" style="float:right;color:#505050;font-size:16px;">`)
var topic_47 []byte = []byte(`</a>`) var topic_48 []byte = []byte(`</a>`)
var topic_48 []byte = []byte(`<a class="username hide_on_micro level">`) var topic_49 []byte = []byte(`<a class="username hide_on_micro level">`)
var topic_49 []byte = []byte(`</a><a class="username hide_on_micro level_label" style="color:#505050;float:right;opacity:0.85;" title="Level"></a>`) var topic_50 []byte = []byte(`</a><a class="username hide_on_micro level_label" style="color:#505050;float:right;opacity:0.85;" title="Level"></a>`)
var topic_50 []byte = []byte(` var topic_51 []byte = []byte(`
</span> </span>
</div> </div>
</div> </div>
<div class="rowblock post_container" style="overflow: hidden;">`) <div class="rowblock post_container" style="overflow: hidden;">`)
var topic_51 []byte = []byte(` var topic_52 []byte = []byte(`
<div class="rowitem passive deletable_block editable_parent post_item action_item"> <div class="rowitem passive deletable_block editable_parent post_item action_item">
<span class="action_icon" style="font-size: 18px;padding-right: 5px;">`) <span class="action_icon" style="font-size: 18px;padding-right: 5px;">`)
var topic_52 []byte = []byte(`</span>
<span>`)
var topic_53 []byte = []byte(`</span> var topic_53 []byte = []byte(`</span>
<span>`)
var topic_54 []byte = []byte(`</span>
</div> </div>
`) `)
var topic_54 []byte = []byte(` var topic_55 []byte = []byte(`
<div class="rowitem passive deletable_block editable_parent post_item" style="`) <div class="rowitem passive deletable_block editable_parent post_item" style="`)
var topic_55 []byte = []byte(`background-image:url(`) var topic_56 []byte = []byte(`background-image:url(`)
var topic_56 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `) var topic_57 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `)
var topic_57 []byte = []byte(`-1`) var topic_58 []byte = []byte(`-1`)
var topic_58 []byte = []byte(`0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;`) var topic_59 []byte = []byte(`0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;`)
var topic_59 []byte = []byte(`"> var topic_60 []byte = []byte(`">
<p class="editable_block user_content" style="margin:0;padding:0;">`) <p class="editable_block user_content" style="margin:0;padding:0;">`)
var topic_60 []byte = []byte(`</p> var topic_61 []byte = []byte(`</p>
<span class="controls"> <span class="controls">
<a href="/user/`) <a href="/user/`)
var topic_61 []byte = []byte(`" class="username real_username">`) var topic_62 []byte = []byte(`.`)
var topic_62 []byte = []byte(`</a>&nbsp;&nbsp; var topic_63 []byte = []byte(`" class="username real_username">`)
var topic_64 []byte = []byte(`</a>&nbsp;&nbsp;
`) `)
var topic_63 []byte = []byte(`<a href="/reply/like/submit/`) var topic_65 []byte = []byte(`<a href="/reply/like/submit/`)
var topic_64 []byte = []byte(`" class="mod_button" title="Love it" style="color:#202020;"><button class="username like_label" style="`) var topic_66 []byte = []byte(`" class="mod_button" title="Love it" style="color:#202020;"><button class="username like_label" style="`)
var topic_65 []byte = []byte(`background-color:/*#eaffea*/#D6FFD6;`) var topic_67 []byte = []byte(`background-color:/*#eaffea*/#D6FFD6;`)
var topic_66 []byte = []byte(`"></button></a>`) var topic_68 []byte = []byte(`"></button></a>`)
var topic_67 []byte = []byte(`<a href="/reply/edit/submit/`) var topic_69 []byte = []byte(`<a href="/reply/edit/submit/`)
var topic_68 []byte = []byte(`" class="mod_button" title="Edit Reply"><button class="username edit_item edit_label"></button></a>`) var topic_70 []byte = []byte(`" class="mod_button" title="Edit Reply"><button class="username edit_item edit_label"></button></a>`)
var topic_69 []byte = []byte(`<a href="/reply/delete/submit/`) var topic_71 []byte = []byte(`<a href="/reply/delete/submit/`)
var topic_70 []byte = []byte(`" class="mod_button" title="Delete Reply"><button class="username delete_item trash_label"></button></a>`) var topic_72 []byte = []byte(`" class="mod_button" title="Delete Reply"><button class="username delete_item trash_label"></button></a>`)
var topic_71 []byte = []byte(` var topic_73 []byte = []byte(`
<a class="mod_button" href="/report/submit/`) <a class="mod_button" href="/report/submit/`)
var topic_72 []byte = []byte(`?session=`) var topic_74 []byte = []byte(`?session=`)
var topic_73 []byte = []byte(`&type=reply" class="mod_button report_item" title="Flag Reply"><button class="username report_item flag_label"></button></a> var topic_75 []byte = []byte(`&type=reply" class="mod_button report_item" title="Flag Reply"><button class="username report_item flag_label"></button></a>
`) `)
var topic_74 []byte = []byte(`<a class="username hide_on_micro like_count">`) var topic_76 []byte = []byte(`<a class="username hide_on_micro like_count">`)
var topic_75 []byte = []byte(`</a><a class="username hide_on_micro like_count_label" title="Like Count"></a>`) var topic_77 []byte = []byte(`</a><a class="username hide_on_micro like_count_label" title="Like Count"></a>`)
var topic_76 []byte = []byte(`<a class="username hide_on_micro" style="float: right;color:#505050;font-size:16px;">`) var topic_78 []byte = []byte(`<a class="username hide_on_micro" style="float: right;color:#505050;font-size:16px;">`)
var topic_77 []byte = []byte(`</a>`) var topic_79 []byte = []byte(`</a>`)
var topic_78 []byte = []byte(`<a class="username hide_on_micro level">`) var topic_80 []byte = []byte(`<a class="username hide_on_micro level">`)
var topic_79 []byte = []byte(`</a><a class="username hide_on_micro level_label" style="color:#505050;float:right;opacity:0.85;" title="Level">`) var topic_81 []byte = []byte(`</a><a class="username hide_on_micro level_label" style="color:#505050;float:right;opacity:0.85;" title="Level">`)
var topic_80 []byte = []byte(`</a> var topic_82 []byte = []byte(`</a>
</span> </span>
</div> </div>
`) `)
var topic_81 []byte = []byte(`</div> var topic_83 []byte = []byte(`</div>
`) `)
var topic_82 []byte = []byte(` var topic_84 []byte = []byte(`
<div class="rowblock"> <div class="rowblock">
<form action="/reply/create/" method="post"> <form action="/reply/create/" method="post">
<input name="tid" value='`) <input name="tid" value='`)
var topic_83 []byte = []byte(`' type="hidden" /> var topic_85 []byte = []byte(`' type="hidden" />
<div class="formrow"> <div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div> <div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div> </div>
@ -284,116 +283,118 @@ var topic_alt_19 []byte = []byte(`
<div class="avatar_item" style="background-image: url(`) <div class="avatar_item" style="background-image: url(`)
var topic_alt_20 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div> var topic_alt_20 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div>
<a href="/user/`) <a href="/user/`)
var topic_alt_21 []byte = []byte(`" class="the_name">`) var topic_alt_21 []byte = []byte(`.`)
var topic_alt_22 []byte = []byte(`</a> var topic_alt_22 []byte = []byte(`" class="the_name">`)
var topic_alt_23 []byte = []byte(`</a>
`) `)
var topic_alt_23 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">`) var topic_alt_24 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">`)
var topic_alt_24 []byte = []byte(`</div><div class="tag_post"></div></div>`) var topic_alt_25 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_25 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level `) var topic_alt_26 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level `)
var topic_alt_26 []byte = []byte(`</div><div class="tag_post"></div></div>`) var topic_alt_27 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_27 []byte = []byte(` var topic_alt_28 []byte = []byte(`
</div> </div>
<div class="content_container"> <div class="content_container">
<div class="hide_on_edit topic_content user_content">`) <div class="hide_on_edit topic_content user_content">`)
var topic_alt_28 []byte = []byte(`</div> var topic_alt_29 []byte = []byte(`</div>
<textarea name="topic_content" class="show_on_edit topic_content_input">`) <textarea name="topic_content" class="show_on_edit topic_content_input">`)
var topic_alt_29 []byte = []byte(`</textarea> var topic_alt_30 []byte = []byte(`</textarea>
<div class="button_container"> <div class="button_container">
`) `)
var topic_alt_30 []byte = []byte(`<a href="/topic/like/submit/`) var topic_alt_31 []byte = []byte(`<a href="/topic/like/submit/`)
var topic_alt_31 []byte = []byte(`" class="action_button">+1</a>`) var topic_alt_32 []byte = []byte(`" class="action_button">+1</a>`)
var topic_alt_32 []byte = []byte(`<a href="/topic/edit/`) var topic_alt_33 []byte = []byte(`<a href="/topic/edit/`)
var topic_alt_33 []byte = []byte(`" class="action_button open_edit">Edit</a>`) var topic_alt_34 []byte = []byte(`" class="action_button open_edit">Edit</a>`)
var topic_alt_34 []byte = []byte(`<a href="/topic/delete/submit/`) var topic_alt_35 []byte = []byte(`<a href="/topic/delete/submit/`)
var topic_alt_35 []byte = []byte(`" class="action_button delete_item">Delete</a>`) var topic_alt_36 []byte = []byte(`" class="action_button delete_item">Delete</a>`)
var topic_alt_36 []byte = []byte(`<a href='/topic/unstick/submit/`) var topic_alt_37 []byte = []byte(`<a href='/topic/unstick/submit/`)
var topic_alt_37 []byte = []byte(`' class="action_button">Unpin</a>`) var topic_alt_38 []byte = []byte(`' class="action_button">Unpin</a>`)
var topic_alt_38 []byte = []byte(`<a href='/topic/stick/submit/`) var topic_alt_39 []byte = []byte(`<a href='/topic/stick/submit/`)
var topic_alt_39 []byte = []byte(`' class="action_button">Pin</a>`) var topic_alt_40 []byte = []byte(`' class="action_button">Pin</a>`)
var topic_alt_40 []byte = []byte(` var topic_alt_41 []byte = []byte(`
<a href="/report/submit/`) <a href="/report/submit/`)
var topic_alt_41 []byte = []byte(`?session=`) var topic_alt_42 []byte = []byte(`?session=`)
var topic_alt_42 []byte = []byte(`&type=topic" class="action_button report_item">Report</a> var topic_alt_43 []byte = []byte(`&type=topic" class="action_button report_item">Report</a>
`) `)
var topic_alt_43 []byte = []byte(`<a href="#" title="IP Address" class="action_button action_button_right ip_item hide_on_mobile">`) var topic_alt_44 []byte = []byte(`<a href="#" title="IP Address" class="action_button action_button_right ip_item hide_on_mobile">`)
var topic_alt_44 []byte = []byte(`</a>`) var topic_alt_45 []byte = []byte(`</a>`)
var topic_alt_45 []byte = []byte(` var topic_alt_46 []byte = []byte(`
<a class="action_button action_button_right hide_on_mobile">`) <a class="action_button action_button_right hide_on_mobile">`)
var topic_alt_46 []byte = []byte(`</a> var topic_alt_47 []byte = []byte(`</a>
`) `)
var topic_alt_47 []byte = []byte(`<a class="action_button action_button_right hide_on_micro">`) var topic_alt_48 []byte = []byte(`<a class="action_button action_button_right hide_on_micro">`)
var topic_alt_48 []byte = []byte(` up</a>`) var topic_alt_49 []byte = []byte(` up</a>`)
var topic_alt_49 []byte = []byte(` var topic_alt_50 []byte = []byte(`
</div> </div>
</div><div style="clear:both;"></div> </div><div style="clear:both;"></div>
</div> </div>
`) `)
var topic_alt_50 []byte = []byte(` var topic_alt_51 []byte = []byte(`
<div class="rowitem passive deletable_block editable_parent post_item `) <div class="rowitem passive deletable_block editable_parent post_item `)
var topic_alt_51 []byte = []byte(`action_item`) var topic_alt_52 []byte = []byte(`action_item`)
var topic_alt_52 []byte = []byte(`"> var topic_alt_53 []byte = []byte(`">
<div class="userinfo"> <div class="userinfo">
<div class="avatar_item" style="background-image: url(`) <div class="avatar_item" style="background-image: url(`)
var topic_alt_53 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div> var topic_alt_54 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div>
<a href="/user/`) <a href="/user/`)
var topic_alt_54 []byte = []byte(`" class="the_name">`) var topic_alt_55 []byte = []byte(`.`)
var topic_alt_55 []byte = []byte(`</a> var topic_alt_56 []byte = []byte(`" class="the_name">`)
var topic_alt_57 []byte = []byte(`</a>
`) `)
var topic_alt_56 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">`) var topic_alt_58 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">`)
var topic_alt_57 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_58 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level `)
var topic_alt_59 []byte = []byte(`</div><div class="tag_post"></div></div>`) var topic_alt_59 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_60 []byte = []byte(` var topic_alt_60 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level `)
var topic_alt_61 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_62 []byte = []byte(`
</div> </div>
<div class="content_container" `) <div class="content_container" `)
var topic_alt_61 []byte = []byte(`style="margin-left: 0px;"`) var topic_alt_63 []byte = []byte(`style="margin-left: 0px;"`)
var topic_alt_62 []byte = []byte(`> var topic_alt_64 []byte = []byte(`>
`) `)
var topic_alt_63 []byte = []byte(` var topic_alt_65 []byte = []byte(`
<span class="action_icon" style="font-size: 18px;padding-right: 5px;">`) <span class="action_icon" style="font-size: 18px;padding-right: 5px;">`)
var topic_alt_64 []byte = []byte(`</span> var topic_alt_66 []byte = []byte(`</span>
<span>`) <span>`)
var topic_alt_65 []byte = []byte(`</span> var topic_alt_67 []byte = []byte(`</span>
`) `)
var topic_alt_66 []byte = []byte(` var topic_alt_68 []byte = []byte(`
<div class="editable_block user_content">`) <div class="editable_block user_content">`)
var topic_alt_67 []byte = []byte(`</div> var topic_alt_69 []byte = []byte(`</div>
<div class="button_container"> <div class="button_container">
`) `)
var topic_alt_68 []byte = []byte(`<a href="/reply/like/submit/`) var topic_alt_70 []byte = []byte(`<a href="/reply/like/submit/`)
var topic_alt_69 []byte = []byte(`" class="action_button">+1</a>`) var topic_alt_71 []byte = []byte(`" class="action_button">+1</a>`)
var topic_alt_70 []byte = []byte(`<a href="/reply/edit/submit/`) var topic_alt_72 []byte = []byte(`<a href="/reply/edit/submit/`)
var topic_alt_71 []byte = []byte(`" class="action_button edit_item">Edit</a>`) var topic_alt_73 []byte = []byte(`" class="action_button edit_item">Edit</a>`)
var topic_alt_72 []byte = []byte(`<a href="/reply/delete/submit/`) var topic_alt_74 []byte = []byte(`<a href="/reply/delete/submit/`)
var topic_alt_73 []byte = []byte(`" class="action_button delete_item">Delete</a>`) var topic_alt_75 []byte = []byte(`" class="action_button delete_item">Delete</a>`)
var topic_alt_74 []byte = []byte(` var topic_alt_76 []byte = []byte(`
<a href="/report/submit/`) <a href="/report/submit/`)
var topic_alt_75 []byte = []byte(`?session=`) var topic_alt_77 []byte = []byte(`?session=`)
var topic_alt_76 []byte = []byte(`&type=reply" class="action_button report_item">Report</a> var topic_alt_78 []byte = []byte(`&type=reply" class="action_button report_item">Report</a>
`) `)
var topic_alt_77 []byte = []byte(`<a href="#" title="IP Address" class="action_button action_button_right ip_item hide_on_mobile">`) var topic_alt_79 []byte = []byte(`<a href="#" title="IP Address" class="action_button action_button_right ip_item hide_on_mobile">`)
var topic_alt_78 []byte = []byte(`</a>`) var topic_alt_80 []byte = []byte(`</a>`)
var topic_alt_79 []byte = []byte(` var topic_alt_81 []byte = []byte(`
<a class="action_button action_button_right hide_on_mobile">`) <a class="action_button action_button_right hide_on_mobile">`)
var topic_alt_80 []byte = []byte(`</a> var topic_alt_82 []byte = []byte(`</a>
`) `)
var topic_alt_81 []byte = []byte(`<a class="action_button action_button_right hide_on_micro">`) var topic_alt_83 []byte = []byte(`<a class="action_button action_button_right hide_on_micro">`)
var topic_alt_82 []byte = []byte(` up</a>`) var topic_alt_84 []byte = []byte(` up</a>`)
var topic_alt_83 []byte = []byte(` var topic_alt_85 []byte = []byte(`
</div> </div>
`) `)
var topic_alt_84 []byte = []byte(` var topic_alt_86 []byte = []byte(`
</div> </div>
<div style="clear:both;"></div> <div style="clear:both;"></div>
</div> </div>
`) `)
var topic_alt_85 []byte = []byte(`</div> var topic_alt_87 []byte = []byte(`</div>
`) `)
var topic_alt_86 []byte = []byte(` var topic_alt_88 []byte = []byte(`
<div class="rowblock" style="border-top: none;"> <div class="rowblock" style="border-top: none;">
<form action="/reply/create/" method="post"> <form action="/reply/create/" method="post">
<input name="tid" value='`) <input name="tid" value='`)
var topic_alt_87 []byte = []byte(`' type="hidden" /> var topic_alt_89 []byte = []byte(`' type="hidden" />
<div class="formrow"> <div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div> <div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div> </div>
@ -454,35 +455,36 @@ var profile_22 []byte = []byte(`">
<span class="editable_block user_content simple">`) <span class="editable_block user_content simple">`)
var profile_23 []byte = []byte(`</span><br /><br /> var profile_23 []byte = []byte(`</span><br /><br />
<a href="/user/`) <a href="/user/`)
var profile_24 []byte = []byte(`" class="real_username username">`) var profile_24 []byte = []byte(`.`)
var profile_25 []byte = []byte(`</a>&nbsp;&nbsp; var profile_25 []byte = []byte(`" class="real_username username">`)
var profile_26 []byte = []byte(`</a>&nbsp;&nbsp;
`) `)
var profile_26 []byte = []byte(`<a href="/profile/reply/edit/submit/`) var profile_27 []byte = []byte(`<a href="/profile/reply/edit/submit/`)
var profile_27 []byte = []byte(`" class="mod_button" title="Edit Item"><button class="username edit_item edit_label"></button></a> var profile_28 []byte = []byte(`" class="mod_button" title="Edit Item"><button class="username edit_item edit_label"></button></a>
<a href="/profile/reply/delete/submit/`) <a href="/profile/reply/delete/submit/`)
var profile_28 []byte = []byte(`" class="mod_button" title="Delete Item"><button class="username delete_item trash_label"></button></a>`) var profile_29 []byte = []byte(`" class="mod_button" title="Delete Item"><button class="username delete_item trash_label"></button></a>`)
var profile_29 []byte = []byte(` var profile_30 []byte = []byte(`
<a class="mod_button" href="/report/submit/`) <a class="mod_button" href="/report/submit/`)
var profile_30 []byte = []byte(`?session=`) var profile_31 []byte = []byte(`?session=`)
var profile_31 []byte = []byte(`&type=user-reply"><button class="username report_item flag_label"></button></a> var profile_32 []byte = []byte(`&type=user-reply"><button class="username report_item flag_label"></button></a>
`) `)
var profile_32 []byte = []byte(`<a class="username hide_on_mobile" style="float: right;">`) var profile_33 []byte = []byte(`<a class="username hide_on_mobile" style="float: right;">`)
var profile_33 []byte = []byte(`</a>`) var profile_34 []byte = []byte(`</a>`)
var profile_34 []byte = []byte(` var profile_35 []byte = []byte(`
</div> </div>
`) `)
var profile_35 []byte = []byte(`</div> var profile_36 []byte = []byte(`</div>
<div class="colblock_right" style="border-top: none;width: calc(95% - 210px);"> <div class="colblock_right" style="border-top: none;width: calc(95% - 210px);">
`) `)
var profile_36 []byte = []byte(` var profile_37 []byte = []byte(`
<form action="/profile/reply/create/" method="post"> <form action="/profile/reply/create/" method="post">
<input name="uid" value='`) <input name="uid" value='`)
var profile_37 []byte = []byte(`' type="hidden" /> var profile_38 []byte = []byte(`' type="hidden" />
<div class="formrow"> <div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div> <div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div> </div>
@ -491,7 +493,7 @@ var profile_37 []byte = []byte(`' type="hidden" />
</div> </div>
</form> </form>
`) `)
var profile_38 []byte = []byte(` var profile_39 []byte = []byte(`
</div> </div>
`) `)
@ -507,37 +509,41 @@ var forums_3 []byte = []byte(`">
`) `)
var forums_4 []byte = []byte(`<span style="float: left;"> var forums_4 []byte = []byte(`<span style="float: left;">
<a href="/forum/`) <a href="/forum/`)
var forums_5 []byte = []byte(`" style="">`) var forums_5 []byte = []byte(`.`)
var forums_6 []byte = []byte(`</a> var forums_6 []byte = []byte(`" style="">`)
var forums_7 []byte = []byte(`</a>
<br /><span class="rowsmall">`) <br /><span class="rowsmall">`)
var forums_7 []byte = []byte(`</span> var forums_8 []byte = []byte(`</span>
</span>`) </span>`)
var forums_8 []byte = []byte(`<span style="float: left;padding-top: 8px;font-size: 18px;"> var forums_9 []byte = []byte(`<span style="float: left;padding-top: 8px;font-size: 18px;">
<a href="/forum/`) <a href="/forum/`)
var forums_9 []byte = []byte(`">`) var forums_10 []byte = []byte(`.`)
var forums_10 []byte = []byte(`</a> var forums_11 []byte = []byte(`">`)
var forums_12 []byte = []byte(`</a>
</span>`) </span>`)
var forums_11 []byte = []byte(`<span style="float: left;"> var forums_13 []byte = []byte(`<span style="float: left;">
<a href="/forum/`) <a href="/forum/`)
var forums_12 []byte = []byte(`">`) var forums_14 []byte = []byte(`.`)
var forums_13 []byte = []byte(`</a> var forums_15 []byte = []byte(`">`)
var forums_16 []byte = []byte(`</a>
</span>`) </span>`)
var forums_14 []byte = []byte(` var forums_17 []byte = []byte(`
<span style="float: right;"> <span style="float: right;">
<a href="/topic/`) <a href="/topic/`)
var forums_15 []byte = []byte(`" style="float: right;font-size: 14px;">`) var forums_18 []byte = []byte(`.`)
var forums_16 []byte = []byte(`</a> var forums_19 []byte = []byte(`" style="float: right;font-size: 14px;">`)
var forums_20 []byte = []byte(`</a>
`) `)
var forums_17 []byte = []byte(`<br /><span class="rowsmall">`) var forums_21 []byte = []byte(`<br /><span class="rowsmall">`)
var forums_18 []byte = []byte(`</span>`) var forums_22 []byte = []byte(`</span>`)
var forums_19 []byte = []byte(` var forums_23 []byte = []byte(`
</span> </span>
<div style="clear: both;"></div> <div style="clear: both;"></div>
</div> </div>
`) `)
var forums_20 []byte = []byte(`<div class="rowitem passive">You don't have access to any forums.</div>`) var forums_24 []byte = []byte(`<div class="rowitem passive">You don't have access to any forums.</div>`)
var forums_21 []byte = []byte(` var forums_25 []byte = []byte(`
</div> </div>
`) `)
var topics_0 []byte = []byte(` var topics_0 []byte = []byte(`
@ -560,25 +566,27 @@ var topics_8 []byte = []byte(`</span>
</span> </span>
<span> <span>
<a class="rowtopic" href="/topic/`) <a class="rowtopic" href="/topic/`)
var topics_9 []byte = []byte(`">`) var topics_9 []byte = []byte(`.`)
var topics_10 []byte = []byte(`</a> `) var topics_10 []byte = []byte(`">`)
var topics_11 []byte = []byte(`<a class="rowsmall" href="/forum/`) var topics_11 []byte = []byte(`</a> `)
var topics_12 []byte = []byte(`">`) var topics_12 []byte = []byte(`<a class="rowsmall" href="/forum/`)
var topics_13 []byte = []byte(`</a>`) var topics_13 []byte = []byte(`">`)
var topics_14 []byte = []byte(` var topics_14 []byte = []byte(`</a>`)
var topics_15 []byte = []byte(`
<br /><a class="rowsmall" href="/user/`) <br /><a class="rowsmall" href="/user/`)
var topics_15 []byte = []byte(`">Starter: `) var topics_16 []byte = []byte(`.`)
var topics_16 []byte = []byte(`</a> var topics_17 []byte = []byte(`">Starter: `)
var topics_18 []byte = []byte(`</a>
`) `)
var topics_17 []byte = []byte(`<span class="rowsmall topic_status_e topic_status_closed" title="Status: Closed"> | &#x1F512;&#xFE0E`) var topics_19 []byte = []byte(`<span class="rowsmall topic_status_e topic_status_closed" title="Status: Closed"> | &#x1F512;&#xFE0E`)
var topics_18 []byte = []byte(`</span> var topics_20 []byte = []byte(`</span>
</span> </span>
</div> </div>
`) `)
var topics_19 []byte = []byte(`<div class="rowitem passive">There aren't any topics yet.`) var topics_21 []byte = []byte(`<div class="rowitem passive">There aren't any topics yet.`)
var topics_20 []byte = []byte(` <a href="/topics/create/">Start one?</a>`) var topics_22 []byte = []byte(` <a href="/topics/create/">Start one?</a>`)
var topics_21 []byte = []byte(`</div>`) var topics_23 []byte = []byte(`</div>`)
var topics_22 []byte = []byte(` var topics_24 []byte = []byte(`
</div> </div>
`) `)
var forum_0 []byte = []byte(`<div id="prevFloat" class="prev_button"><a class="prev_link" href="/forum/`) var forum_0 []byte = []byte(`<div id="prevFloat" class="prev_button"><a class="prev_link" href="/forum/`)
@ -617,21 +625,23 @@ var forum_21 []byte = []byte(`</span>
</span> </span>
<span> <span>
<a class="rowtopic" href="/topic/`) <a class="rowtopic" href="/topic/`)
var forum_22 []byte = []byte(`">`) var forum_22 []byte = []byte(`.`)
var forum_23 []byte = []byte(`</a> var forum_23 []byte = []byte(`">`)
var forum_24 []byte = []byte(`</a>
<br /><a class="rowsmall" href="/user/`) <br /><a class="rowsmall" href="/user/`)
var forum_24 []byte = []byte(`">Starter: `) var forum_25 []byte = []byte(`.`)
var forum_25 []byte = []byte(`</a> var forum_26 []byte = []byte(`">Starter: `)
var forum_27 []byte = []byte(`</a>
`) `)
var forum_26 []byte = []byte(`<span class="rowsmall topic_status_e topic_status_closed" title="Status: Closed"> | &#x1F512;&#xFE0E`) var forum_28 []byte = []byte(`<span class="rowsmall topic_status_e topic_status_closed" title="Status: Closed"> | &#x1F512;&#xFE0E`)
var forum_27 []byte = []byte(`</span> var forum_29 []byte = []byte(`</span>
</span> </span>
</div> </div>
`) `)
var forum_28 []byte = []byte(`<div class="rowitem passive">There aren't any topics in this forum yet.`) var forum_30 []byte = []byte(`<div class="rowitem passive">There aren't any topics in this forum yet.`)
var forum_29 []byte = []byte(` <a href="/topics/create/`) var forum_31 []byte = []byte(` <a href="/topics/create/`)
var forum_30 []byte = []byte(`">Start one?</a>`) var forum_32 []byte = []byte(`">Start one?</a>`)
var forum_31 []byte = []byte(`</div>`) var forum_33 []byte = []byte(`</div>`)
var forum_32 []byte = []byte(` var forum_34 []byte = []byte(`
</div> </div>
`) `)

View File

@ -38,18 +38,20 @@ w.Write(header_8)
w.Write(menu_0) w.Write(menu_0)
if tmpl_profile_vars.CurrentUser.Loggedin { if tmpl_profile_vars.CurrentUser.Loggedin {
w.Write(menu_1) w.Write(menu_1)
w.Write([]byte(strconv.Itoa(tmpl_profile_vars.CurrentUser.ID))) w.Write([]byte(tmpl_profile_vars.CurrentUser.Slug))
w.Write(menu_2) w.Write(menu_2)
if tmpl_profile_vars.CurrentUser.Is_Super_Mod { w.Write([]byte(strconv.Itoa(tmpl_profile_vars.CurrentUser.ID)))
w.Write(menu_3) w.Write(menu_3)
} if tmpl_profile_vars.CurrentUser.Is_Super_Mod {
w.Write(menu_4) w.Write(menu_4)
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
w.Write(menu_5)
} else {
w.Write(menu_6)
} }
w.Write(menu_5)
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
w.Write(menu_6)
} else {
w.Write(menu_7) w.Write(menu_7)
}
w.Write(menu_8)
w.Write(header_9) w.Write(header_9)
if tmpl_profile_vars.Header.Widgets.RightSidebar != "" { if tmpl_profile_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_10) w.Write(header_10)
@ -111,37 +113,39 @@ w.Write([]byte(string(item.Css)))
w.Write(profile_22) w.Write(profile_22)
w.Write([]byte(item.ContentHtml)) w.Write([]byte(item.ContentHtml))
w.Write(profile_23) w.Write(profile_23)
w.Write([]byte(strconv.Itoa(item.CreatedBy))) w.Write([]byte(item.UserSlug))
w.Write(profile_24) w.Write(profile_24)
w.Write([]byte(item.CreatedByName)) w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(profile_25) w.Write(profile_25)
if tmpl_profile_vars.CurrentUser.Is_Mod { w.Write([]byte(item.CreatedByName))
w.Write(profile_26) w.Write(profile_26)
w.Write([]byte(strconv.Itoa(item.ID))) if tmpl_profile_vars.CurrentUser.Is_Mod {
w.Write(profile_27) w.Write(profile_27)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(profile_28) w.Write(profile_28)
}
w.Write(profile_29)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(profile_30) w.Write(profile_29)
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
w.Write(profile_31)
if item.Tag != "" {
w.Write(profile_32)
w.Write([]byte(item.Tag))
w.Write(profile_33)
} }
w.Write(profile_30)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(profile_31)
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
w.Write(profile_32)
if item.Tag != "" {
w.Write(profile_33)
w.Write([]byte(item.Tag))
w.Write(profile_34) w.Write(profile_34)
} }
}
w.Write(profile_35) w.Write(profile_35)
if !tmpl_profile_vars.CurrentUser.Is_Banned {
w.Write(profile_36)
w.Write([]byte(strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID)))
w.Write(profile_37)
} }
}
w.Write(profile_36)
if !tmpl_profile_vars.CurrentUser.Is_Banned {
w.Write(profile_37)
w.Write([]byte(strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID)))
w.Write(profile_38) w.Write(profile_38)
}
w.Write(profile_39)
w.Write(footer_0) w.Write(footer_0)
if tmpl_profile_vars.Header.Widgets.RightSidebar != "" { if tmpl_profile_vars.Header.Widgets.RightSidebar != "" {
w.Write(footer_1) w.Write(footer_1)

View File

@ -38,18 +38,20 @@ w.Write(header_8)
w.Write(menu_0) w.Write(menu_0)
if tmpl_topic_vars.CurrentUser.Loggedin { if tmpl_topic_vars.CurrentUser.Loggedin {
w.Write(menu_1) w.Write(menu_1)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.CurrentUser.ID))) w.Write([]byte(tmpl_topic_vars.CurrentUser.Slug))
w.Write(menu_2) w.Write(menu_2)
if tmpl_topic_vars.CurrentUser.Is_Super_Mod { w.Write([]byte(strconv.Itoa(tmpl_topic_vars.CurrentUser.ID)))
w.Write(menu_3) w.Write(menu_3)
} if tmpl_topic_vars.CurrentUser.Is_Super_Mod {
w.Write(menu_4) w.Write(menu_4)
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
w.Write(menu_5)
} else {
w.Write(menu_6)
} }
w.Write(menu_5)
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
w.Write(menu_6)
} else {
w.Write(menu_7) w.Write(menu_7)
}
w.Write(menu_8)
w.Write(header_9) w.Write(header_9)
if tmpl_topic_vars.Header.Widgets.RightSidebar != "" { if tmpl_topic_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_10) w.Write(header_10)
@ -121,134 +123,138 @@ w.Write([]byte(tmpl_topic_vars.Topic.Content))
w.Write(topic_25) w.Write(topic_25)
w.Write([]byte(tmpl_topic_vars.Topic.Content)) w.Write([]byte(tmpl_topic_vars.Topic.Content))
w.Write(topic_26) w.Write(topic_26)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.CreatedBy))) w.Write([]byte(tmpl_topic_vars.Topic.UserSlug))
w.Write(topic_27) w.Write(topic_27)
w.Write([]byte(tmpl_topic_vars.Topic.CreatedByName)) w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.CreatedBy)))
w.Write(topic_28) w.Write(topic_28)
if tmpl_topic_vars.CurrentUser.Perms.LikeItem { w.Write([]byte(tmpl_topic_vars.Topic.CreatedByName))
w.Write(topic_29) w.Write(topic_29)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID))) if tmpl_topic_vars.CurrentUser.Perms.LikeItem {
w.Write(topic_30) w.Write(topic_30)
if tmpl_topic_vars.Topic.Liked { w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_31) w.Write(topic_31)
} if tmpl_topic_vars.Topic.Liked {
w.Write(topic_32) w.Write(topic_32)
} }
if tmpl_topic_vars.CurrentUser.Perms.EditTopic {
w.Write(topic_33) w.Write(topic_33)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID))) }
if tmpl_topic_vars.CurrentUser.Perms.EditTopic {
w.Write(topic_34) w.Write(topic_34)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_35)
} }
if tmpl_topic_vars.CurrentUser.Perms.DeleteTopic { if tmpl_topic_vars.CurrentUser.Perms.DeleteTopic {
w.Write(topic_35)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_36) w.Write(topic_36)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_37)
} }
if tmpl_topic_vars.CurrentUser.Perms.PinTopic { if tmpl_topic_vars.CurrentUser.Perms.PinTopic {
if tmpl_topic_vars.Topic.Sticky { if tmpl_topic_vars.Topic.Sticky {
w.Write(topic_37)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_38) w.Write(topic_38)
} else { w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_39) w.Write(topic_39)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID))) } else {
w.Write(topic_40) w.Write(topic_40)
}
}
w.Write(topic_41)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID))) w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_41)
}
}
w.Write(topic_42) w.Write(topic_42)
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session)) w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_43) w.Write(topic_43)
if tmpl_topic_vars.Topic.LikeCount > 0 { w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
w.Write(topic_44) w.Write(topic_44)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.LikeCount))) if tmpl_topic_vars.Topic.LikeCount > 0 {
w.Write(topic_45) w.Write(topic_45)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.LikeCount)))
w.Write(topic_46)
} }
if tmpl_topic_vars.Topic.Tag != "" { if tmpl_topic_vars.Topic.Tag != "" {
w.Write(topic_46)
w.Write([]byte(tmpl_topic_vars.Topic.Tag))
w.Write(topic_47) w.Write(topic_47)
} else { w.Write([]byte(tmpl_topic_vars.Topic.Tag))
w.Write(topic_48) w.Write(topic_48)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.Level))) } else {
w.Write(topic_49) w.Write(topic_49)
} w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.Level)))
w.Write(topic_50) w.Write(topic_50)
}
w.Write(topic_51)
if len(tmpl_topic_vars.ItemList) != 0 { if len(tmpl_topic_vars.ItemList) != 0 {
for _, item := range tmpl_topic_vars.ItemList { for _, item := range tmpl_topic_vars.ItemList {
if item.ActionType != "" { if item.ActionType != "" {
w.Write(topic_51)
w.Write([]byte(item.ActionIcon))
w.Write(topic_52) w.Write(topic_52)
w.Write([]byte(item.ActionType)) w.Write([]byte(item.ActionIcon))
w.Write(topic_53) w.Write(topic_53)
} else { w.Write([]byte(item.ActionType))
w.Write(topic_54) w.Write(topic_54)
if item.Avatar != "" { } else {
w.Write(topic_55) w.Write(topic_55)
w.Write([]byte(item.Avatar)) if item.Avatar != "" {
w.Write(topic_56) w.Write(topic_56)
if item.ContentLines <= 5 { w.Write([]byte(item.Avatar))
w.Write(topic_57) w.Write(topic_57)
} if item.ContentLines <= 5 {
w.Write(topic_58) w.Write(topic_58)
w.Write([]byte(string(item.Css)))
} }
w.Write(topic_59) w.Write(topic_59)
w.Write([]byte(item.ContentHtml)) w.Write([]byte(string(item.Css)))
}
w.Write(topic_60) w.Write(topic_60)
w.Write([]byte(strconv.Itoa(item.CreatedBy))) w.Write([]byte(item.ContentHtml))
w.Write(topic_61) w.Write(topic_61)
w.Write([]byte(item.CreatedByName)) w.Write([]byte(item.UserSlug))
w.Write(topic_62) w.Write(topic_62)
if tmpl_topic_vars.CurrentUser.Perms.LikeItem { w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(topic_63) w.Write(topic_63)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(item.CreatedByName))
w.Write(topic_64) w.Write(topic_64)
if item.Liked { if tmpl_topic_vars.CurrentUser.Perms.LikeItem {
w.Write(topic_65) w.Write(topic_65)
}
w.Write(topic_66)
}
if tmpl_topic_vars.CurrentUser.Perms.EditReply {
w.Write(topic_67)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_66)
if item.Liked {
w.Write(topic_67)
}
w.Write(topic_68) w.Write(topic_68)
} }
if tmpl_topic_vars.CurrentUser.Perms.DeleteReply { if tmpl_topic_vars.CurrentUser.Perms.EditReply {
w.Write(topic_69) w.Write(topic_69)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_70) w.Write(topic_70)
} }
if tmpl_topic_vars.CurrentUser.Perms.DeleteReply {
w.Write(topic_71) w.Write(topic_71)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_72) w.Write(topic_72)
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session)) }
w.Write(topic_73) w.Write(topic_73)
if item.LikeCount > 0 { w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_74) w.Write(topic_74)
w.Write([]byte(strconv.Itoa(item.LikeCount))) w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
w.Write(topic_75) w.Write(topic_75)
if item.LikeCount > 0 {
w.Write(topic_76)
w.Write([]byte(strconv.Itoa(item.LikeCount)))
w.Write(topic_77)
} }
if item.Tag != "" { if item.Tag != "" {
w.Write(topic_76)
w.Write([]byte(item.Tag))
w.Write(topic_77)
} else {
w.Write(topic_78) w.Write(topic_78)
w.Write([]byte(strconv.Itoa(item.Level))) w.Write([]byte(item.Tag))
w.Write(topic_79) w.Write(topic_79)
} } else {
w.Write(topic_80) w.Write(topic_80)
} w.Write([]byte(strconv.Itoa(item.Level)))
}
}
w.Write(topic_81) w.Write(topic_81)
if tmpl_topic_vars.CurrentUser.Perms.CreateReply { }
w.Write(topic_82) w.Write(topic_82)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID))) }
}
}
w.Write(topic_83) w.Write(topic_83)
if tmpl_topic_vars.CurrentUser.Perms.CreateReply {
w.Write(topic_84)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_85)
} }
w.Write(footer_0) w.Write(footer_0)
if tmpl_topic_vars.Header.Widgets.RightSidebar != "" { if tmpl_topic_vars.Header.Widgets.RightSidebar != "" {

View File

@ -38,18 +38,20 @@ w.Write(header_8)
w.Write(menu_0) w.Write(menu_0)
if tmpl_topic_alt_vars.CurrentUser.Loggedin { if tmpl_topic_alt_vars.CurrentUser.Loggedin {
w.Write(menu_1) w.Write(menu_1)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.CurrentUser.ID))) w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Slug))
w.Write(menu_2) w.Write(menu_2)
if tmpl_topic_alt_vars.CurrentUser.Is_Super_Mod { w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.CurrentUser.ID)))
w.Write(menu_3) w.Write(menu_3)
} if tmpl_topic_alt_vars.CurrentUser.Is_Super_Mod {
w.Write(menu_4) w.Write(menu_4)
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
w.Write(menu_5)
} else {
w.Write(menu_6)
} }
w.Write(menu_5)
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
w.Write(menu_6)
} else {
w.Write(menu_7) w.Write(menu_7)
}
w.Write(menu_8)
w.Write(header_9) w.Write(header_9)
if tmpl_topic_alt_vars.Header.Widgets.RightSidebar != "" { if tmpl_topic_alt_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_10) w.Write(header_10)
@ -108,153 +110,157 @@ w.Write(topic_alt_18)
w.Write(topic_alt_19) w.Write(topic_alt_19)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Avatar)) w.Write([]byte(tmpl_topic_alt_vars.Topic.Avatar))
w.Write(topic_alt_20) w.Write(topic_alt_20)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.CreatedBy))) w.Write([]byte(tmpl_topic_alt_vars.Topic.UserSlug))
w.Write(topic_alt_21) w.Write(topic_alt_21)
w.Write([]byte(tmpl_topic_alt_vars.Topic.CreatedByName)) w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.CreatedBy)))
w.Write(topic_alt_22) w.Write(topic_alt_22)
if tmpl_topic_alt_vars.Topic.Tag != "" { w.Write([]byte(tmpl_topic_alt_vars.Topic.CreatedByName))
w.Write(topic_alt_23) w.Write(topic_alt_23)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Tag)) if tmpl_topic_alt_vars.Topic.Tag != "" {
w.Write(topic_alt_24) w.Write(topic_alt_24)
} else { w.Write([]byte(tmpl_topic_alt_vars.Topic.Tag))
w.Write(topic_alt_25) w.Write(topic_alt_25)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.Level))) } else {
w.Write(topic_alt_26) w.Write(topic_alt_26)
} w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.Level)))
w.Write(topic_alt_27) w.Write(topic_alt_27)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Content)) }
w.Write(topic_alt_28) w.Write(topic_alt_28)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Content)) w.Write([]byte(tmpl_topic_alt_vars.Topic.Content))
w.Write(topic_alt_29) w.Write(topic_alt_29)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Content))
w.Write(topic_alt_30)
if tmpl_topic_alt_vars.CurrentUser.Loggedin { if tmpl_topic_alt_vars.CurrentUser.Loggedin {
if tmpl_topic_alt_vars.CurrentUser.Perms.LikeItem { if tmpl_topic_alt_vars.CurrentUser.Perms.LikeItem {
w.Write(topic_alt_30)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_31) w.Write(topic_alt_31)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_32)
} }
if tmpl_topic_alt_vars.CurrentUser.Perms.EditTopic { if tmpl_topic_alt_vars.CurrentUser.Perms.EditTopic {
w.Write(topic_alt_32)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_33) w.Write(topic_alt_33)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_34)
} }
if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteTopic { if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteTopic {
w.Write(topic_alt_34)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_35) w.Write(topic_alt_35)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_36)
} }
if tmpl_topic_alt_vars.CurrentUser.Perms.PinTopic { if tmpl_topic_alt_vars.CurrentUser.Perms.PinTopic {
if tmpl_topic_alt_vars.Topic.Sticky { if tmpl_topic_alt_vars.Topic.Sticky {
w.Write(topic_alt_36)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_37) w.Write(topic_alt_37)
} else { w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_38) w.Write(topic_alt_38)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID))) } else {
w.Write(topic_alt_39) w.Write(topic_alt_39)
}
}
w.Write(topic_alt_40)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID))) w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_40)
}
}
w.Write(topic_alt_41) w.Write(topic_alt_41)
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session)) w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_42) w.Write(topic_alt_42)
if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs { w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
w.Write(topic_alt_43) w.Write(topic_alt_43)
w.Write([]byte(tmpl_topic_alt_vars.Topic.IpAddress)) if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs {
w.Write(topic_alt_44) w.Write(topic_alt_44)
} w.Write([]byte(tmpl_topic_alt_vars.Topic.IpAddress))
}
w.Write(topic_alt_45) w.Write(topic_alt_45)
w.Write([]byte(tmpl_topic_alt_vars.Topic.CreatedAt))
w.Write(topic_alt_46)
if tmpl_topic_alt_vars.Topic.LikeCount > 0 {
w.Write(topic_alt_47)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.LikeCount)))
w.Write(topic_alt_48)
} }
}
w.Write(topic_alt_46)
w.Write([]byte(tmpl_topic_alt_vars.Topic.CreatedAt))
w.Write(topic_alt_47)
if tmpl_topic_alt_vars.Topic.LikeCount > 0 {
w.Write(topic_alt_48)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.LikeCount)))
w.Write(topic_alt_49) w.Write(topic_alt_49)
}
w.Write(topic_alt_50)
if len(tmpl_topic_alt_vars.ItemList) != 0 { if len(tmpl_topic_alt_vars.ItemList) != 0 {
for _, item := range tmpl_topic_alt_vars.ItemList { for _, item := range tmpl_topic_alt_vars.ItemList {
w.Write(topic_alt_50)
if item.ActionType != "" {
w.Write(topic_alt_51) w.Write(topic_alt_51)
}
w.Write(topic_alt_52)
w.Write([]byte(item.Avatar))
w.Write(topic_alt_53)
w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(topic_alt_54)
w.Write([]byte(item.CreatedByName))
w.Write(topic_alt_55)
if item.Tag != "" {
w.Write(topic_alt_56)
w.Write([]byte(item.Tag))
w.Write(topic_alt_57)
} else {
w.Write(topic_alt_58)
w.Write([]byte(strconv.Itoa(item.Level)))
w.Write(topic_alt_59)
}
w.Write(topic_alt_60)
if item.ActionType != "" { if item.ActionType != "" {
w.Write(topic_alt_52)
}
w.Write(topic_alt_53)
w.Write([]byte(item.Avatar))
w.Write(topic_alt_54)
w.Write([]byte(item.UserSlug))
w.Write(topic_alt_55)
w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(topic_alt_56)
w.Write([]byte(item.CreatedByName))
w.Write(topic_alt_57)
if item.Tag != "" {
w.Write(topic_alt_58)
w.Write([]byte(item.Tag))
w.Write(topic_alt_59)
} else {
w.Write(topic_alt_60)
w.Write([]byte(strconv.Itoa(item.Level)))
w.Write(topic_alt_61) w.Write(topic_alt_61)
} }
w.Write(topic_alt_62) w.Write(topic_alt_62)
if item.ActionType != "" { if item.ActionType != "" {
w.Write(topic_alt_63) w.Write(topic_alt_63)
w.Write([]byte(item.ActionIcon)) }
w.Write(topic_alt_64) w.Write(topic_alt_64)
w.Write([]byte(item.ActionType)) if item.ActionType != "" {
w.Write(topic_alt_65) w.Write(topic_alt_65)
} else { w.Write([]byte(item.ActionIcon))
w.Write(topic_alt_66) w.Write(topic_alt_66)
w.Write([]byte(item.ContentHtml)) w.Write([]byte(item.ActionType))
w.Write(topic_alt_67) w.Write(topic_alt_67)
} else {
w.Write(topic_alt_68)
w.Write([]byte(item.ContentHtml))
w.Write(topic_alt_69)
if tmpl_topic_alt_vars.CurrentUser.Loggedin { if tmpl_topic_alt_vars.CurrentUser.Loggedin {
if tmpl_topic_alt_vars.CurrentUser.Perms.LikeItem { if tmpl_topic_alt_vars.CurrentUser.Perms.LikeItem {
w.Write(topic_alt_68)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_alt_69)
}
if tmpl_topic_alt_vars.CurrentUser.Perms.EditReply {
w.Write(topic_alt_70) w.Write(topic_alt_70)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_alt_71) w.Write(topic_alt_71)
} }
if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteReply { if tmpl_topic_alt_vars.CurrentUser.Perms.EditReply {
w.Write(topic_alt_72) w.Write(topic_alt_72)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_alt_73) w.Write(topic_alt_73)
} }
if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteReply {
w.Write(topic_alt_74) w.Write(topic_alt_74)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_alt_75) w.Write(topic_alt_75)
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session)) }
w.Write(topic_alt_76) w.Write(topic_alt_76)
if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs { w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_alt_77) w.Write(topic_alt_77)
w.Write([]byte(item.IpAddress)) w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
w.Write(topic_alt_78) w.Write(topic_alt_78)
} if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs {
}
w.Write(topic_alt_79) w.Write(topic_alt_79)
w.Write([]byte(item.CreatedAt)) w.Write([]byte(item.IpAddress))
w.Write(topic_alt_80) w.Write(topic_alt_80)
if item.LikeCount > 0 { }
}
w.Write(topic_alt_81) w.Write(topic_alt_81)
w.Write([]byte(strconv.Itoa(item.LikeCount))) w.Write([]byte(item.CreatedAt))
w.Write(topic_alt_82) w.Write(topic_alt_82)
} if item.LikeCount > 0 {
w.Write(topic_alt_83) w.Write(topic_alt_83)
} w.Write([]byte(strconv.Itoa(item.LikeCount)))
w.Write(topic_alt_84) w.Write(topic_alt_84)
} }
}
w.Write(topic_alt_85) w.Write(topic_alt_85)
if tmpl_topic_alt_vars.CurrentUser.Perms.CreateReply { }
w.Write(topic_alt_86) w.Write(topic_alt_86)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID))) }
}
w.Write(topic_alt_87) w.Write(topic_alt_87)
if tmpl_topic_alt_vars.CurrentUser.Perms.CreateReply {
w.Write(topic_alt_88)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_89)
} }
w.Write(footer_0) w.Write(footer_0)
if tmpl_topic_alt_vars.Header.Widgets.RightSidebar != "" { if tmpl_topic_alt_vars.Header.Widgets.RightSidebar != "" {

View File

@ -38,18 +38,20 @@ w.Write(header_8)
w.Write(menu_0) w.Write(menu_0)
if tmpl_topics_vars.CurrentUser.Loggedin { if tmpl_topics_vars.CurrentUser.Loggedin {
w.Write(menu_1) w.Write(menu_1)
w.Write([]byte(strconv.Itoa(tmpl_topics_vars.CurrentUser.ID))) w.Write([]byte(tmpl_topics_vars.CurrentUser.Slug))
w.Write(menu_2) w.Write(menu_2)
if tmpl_topics_vars.CurrentUser.Is_Super_Mod { w.Write([]byte(strconv.Itoa(tmpl_topics_vars.CurrentUser.ID)))
w.Write(menu_3) w.Write(menu_3)
} if tmpl_topics_vars.CurrentUser.Is_Super_Mod {
w.Write(menu_4) w.Write(menu_4)
w.Write([]byte(tmpl_topics_vars.CurrentUser.Session))
w.Write(menu_5)
} else {
w.Write(menu_6)
} }
w.Write(menu_5)
w.Write([]byte(tmpl_topics_vars.CurrentUser.Session))
w.Write(menu_6)
} else {
w.Write(menu_7) w.Write(menu_7)
}
w.Write(menu_8)
w.Write(header_9) w.Write(header_9)
if tmpl_topics_vars.Header.Widgets.RightSidebar != "" { if tmpl_topics_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_10) w.Write(header_10)
@ -83,35 +85,39 @@ w.Write([]byte(strconv.Itoa(item.PostCount)))
w.Write(topics_7) w.Write(topics_7)
w.Write([]byte(item.LastReplyAt)) w.Write([]byte(item.LastReplyAt))
w.Write(topics_8) w.Write(topics_8)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(item.Slug))
w.Write(topics_9) w.Write(topics_9)
w.Write([]byte(item.Title)) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topics_10) w.Write(topics_10)
if item.ForumName != "" { w.Write([]byte(item.Title))
w.Write(topics_11) w.Write(topics_11)
w.Write([]byte(strconv.Itoa(item.ParentID))) if item.ForumName != "" {
w.Write(topics_12) w.Write(topics_12)
w.Write([]byte(item.ForumName)) w.Write([]byte(strconv.Itoa(item.ParentID)))
w.Write(topics_13) w.Write(topics_13)
} w.Write([]byte(item.ForumName))
w.Write(topics_14) w.Write(topics_14)
w.Write([]byte(strconv.Itoa(item.CreatedBy))) }
w.Write(topics_15) w.Write(topics_15)
w.Write([]byte(item.CreatedByName)) w.Write([]byte(item.UserSlug))
w.Write(topics_16) w.Write(topics_16)
if item.Is_Closed { w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(topics_17) w.Write(topics_17)
} w.Write([]byte(item.CreatedByName))
w.Write(topics_18) w.Write(topics_18)
} if item.Is_Closed {
} else {
w.Write(topics_19) w.Write(topics_19)
if tmpl_topics_vars.CurrentUser.Perms.CreateTopic { }
w.Write(topics_20) w.Write(topics_20)
} }
} else {
w.Write(topics_21) w.Write(topics_21)
} if tmpl_topics_vars.CurrentUser.Perms.CreateTopic {
w.Write(topics_22) w.Write(topics_22)
}
w.Write(topics_23)
}
w.Write(topics_24)
w.Write(footer_0) w.Write(footer_0)
if tmpl_topics_vars.Header.Widgets.RightSidebar != "" { if tmpl_topics_vars.Header.Widgets.RightSidebar != "" {
w.Write(footer_1) w.Write(footer_1)

View File

@ -15,8 +15,8 @@
<span class="lastReplyAt">{{.LastReplyAt}}</span> <span class="lastReplyAt">{{.LastReplyAt}}</span>
</span> </span>
<span> <span>
<a class="rowtopic" href="/topic/{{.ID}}">{{.Title}}</a> <a class="rowtopic" href="/topic/{{.Slug}}.{{.ID}}">{{.Title}}</a>
<br /><a class="rowsmall" href="/user/{{.CreatedBy}}">Starter: {{.CreatedByName}}</a> <br /><a class="rowsmall" href="/user/{{.UserSlug}}.{{.CreatedBy}}">Starter: {{.CreatedByName}}</a>
{{if .Is_Closed}}<span class="rowsmall topic_status_e topic_status_closed" title="Status: Closed"> | &#x1F512;&#xFE0E{{end}}</span> {{if .Is_Closed}}<span class="rowsmall topic_status_e topic_status_closed" title="Status: Closed"> | &#x1F512;&#xFE0E{{end}}</span>
</span> </span>
</div> </div>

View File

@ -5,16 +5,16 @@
<div class="rowblock"> <div class="rowblock">
{{range .ItemList}}<div class="rowitem {{if (.Desc) or (.LastTopicTime)}}datarow{{end}}"> {{range .ItemList}}<div class="rowitem {{if (.Desc) or (.LastTopicTime)}}datarow{{end}}">
{{if .Desc}}<span style="float: left;"> {{if .Desc}}<span style="float: left;">
<a href="/forum/{{.ID}}" style="">{{.Name}}</a> <a href="/forum/{{.Slug}}.{{.ID}}" style="">{{.Name}}</a>
<br /><span class="rowsmall">{{.Desc}}</span> <br /><span class="rowsmall">{{.Desc}}</span>
</span>{{else if .LastTopicTime}}<span style="float: left;padding-top: 8px;font-size: 18px;"> </span>{{else if .LastTopicTime}}<span style="float: left;padding-top: 8px;font-size: 18px;">
<a href="/forum/{{.ID}}">{{.Name}}</a> <a href="/forum/{{.Slug}}.{{.ID}}">{{.Name}}</a>
</span>{{else}}<span style="float: left;"> </span>{{else}}<span style="float: left;">
<a href="/forum/{{.ID}}">{{.Name}}</a> <a href="/forum/{{.Slug}}.{{.ID}}">{{.Name}}</a>
</span>{{end}} </span>{{end}}
<span style="float: right;"> <span style="float: right;">
<a href="/topic/{{.LastTopicID}}" style="float: right;font-size: 14px;">{{.LastTopic}}</a> <a href="/topic/{{.LastTopicSlug}}.{{.LastTopicID}}" style="float: right;font-size: 14px;">{{.LastTopic}}</a>
{{if .LastTopicTime}}<br /><span class="rowsmall">{{.LastTopicTime}}</span>{{end}} {{if .LastTopicTime}}<br /><span class="rowsmall">{{.LastTopicTime}}</span>{{end}}
</span> </span>
<div style="clear: both;"></div> <div style="clear: both;"></div>

View File

@ -8,7 +8,7 @@
<li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li> <li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li>
{{if .CurrentUser.Loggedin}} {{if .CurrentUser.Loggedin}}
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li> <li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_profile"><a href="/user/{{.CurrentUser.ID}}">Profile</a></li> <li class="menu_left menu_profile"><a href="/user/{{.CurrentUser.Slug}}.{{.CurrentUser.ID}}">Profile</a></li>
{{if .CurrentUser.Is_Super_Mod}}<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>{{end}} {{if .CurrentUser.Is_Super_Mod}}<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>{{end}}
<li class="menu_left menu_logout"><a href="/accounts/logout/?session={{.CurrentUser.Session}}">Logout</a></li> <li class="menu_left menu_logout"><a href="/accounts/logout/?session={{.CurrentUser.Session}}">Logout</a></li>
{{else}} {{else}}

View File

@ -7,7 +7,7 @@
</div> </div>
<div id="panel_groups" class="colstack_item"> <div id="panel_groups" class="colstack_item">
{{range .ItemList}} {{range .ItemList}}
<div class="rowitem editable_parent"> <div class="rowitem panel_compactrow editable_parent">
<a href="/panel/groups/edit/{{.ID}}" class="panel_upshift">{{.Name}}</a> <a href="/panel/groups/edit/{{.ID}}" class="panel_upshift">{{.Name}}</a>
<span class="panel_floater"> <span class="panel_floater">
{{if .RankClass}}<a class="panel_tag panel_rank_tag panel_rank_tag_{{.RankClass}}" title="{{.Rank}}"></a> {{if .RankClass}}<a class="panel_tag panel_rank_tag panel_rank_tag_{{.RankClass}}" title="{{.Rank}}"></a>

View File

@ -16,12 +16,15 @@
</div> </div>
<div id="panel_modlogs" class="colstack_item"> <div id="panel_modlogs" class="colstack_item">
{{range .Logs}} {{range .Logs}}
<div class="rowitem" style="font-weight: normal;text-transform: none;"> <div class="rowitem panel_compactrow" style="font-weight: normal;text-transform: none;">
<a style="font-size: 17px;">{{.Action}}</a><br /> <span style="float: left;">
<small style="margin-left: 2px;">IP: {{.IPAddress}}</small> <span>{{.Action}}</span><br />
<span style="float: right;"> <small style="margin-left: 2px;font-size: 12px;">{{.IPAddress}}</small>
<span style="font-size: 16px;">{{.DoneAt}}</span>
</span> </span>
<span style="float: right;">
<span style="font-size: 14px;">{{.DoneAt}}</span>
</span>
<div style="clear: both;"></div>
</div> </div>
{{end}} {{end}}
</div> </div>

View File

@ -6,9 +6,9 @@
</div> </div>
<div id="panel_settings" class="colstack_item"> <div id="panel_settings" class="colstack_item">
{{range $key, $value := .Something}} {{range $key, $value := .Something}}
<div class="rowitem editable_parent"> <div class="rowitem panel_compactrow editable_parent">
<a href="/panel/settings/edit/{{$key}}" class="editable_block panel_upshift">{{$key}}</a> <a href="/panel/settings/edit/{{$key}}" class="editable_block panel_upshift">{{$key}}</a>
<a style="float: right;">{{$value}}</a> <a class="panel_compacttext" style="float: right;">{{$value}}</a>
</div> </div>
{{end}} {{end}}
</div> </div>

View File

@ -10,7 +10,7 @@
<div class="rowitem editable_parent" style="font-weight: normal;text-transform: none;"> <div class="rowitem editable_parent" style="font-weight: normal;text-transform: none;">
<a {{if $.CurrentUser.Perms.EditUser}}href="/panel/users/edit/{{.ID}}?session={{$.CurrentUser.Session}} "{{end}}class="editable_block">{{.Name}}</a> <a {{if $.CurrentUser.Perms.EditUser}}href="/panel/users/edit/{{.ID}}?session={{$.CurrentUser.Session}} "{{end}}class="editable_block">{{.Name}}</a>
<a href="/user/{{.ID}}" class="tag-mini">Profile</a> <a href="/user/{{.ID}}" class="tag-mini">Profile</a>
{{if .Tag}}<span class="panel_tag" style="margin-left 4px;{{if (.Is_Super_Mod) and (.Active)}}float: right;{{end}}">{{.Tag}}</span>{{end}} {{if (.Tag) and (.Is_Super_Mod)}}<span style="float: right;"><span class="panel_tag" style="margin-left 4px;">{{.Tag}}</span></span>{{end}}
<span class="panel_floater"> <span class="panel_floater">
{{if .Is_Banned}}<a href="/users/unban/{{.ID}}?session={{$.CurrentUser.Session}}" class="panel_tag panel_right_button">Unban</a>{{else if not .Is_Super_Mod}}<a href="/users/ban/{{.ID}}?session={{$.CurrentUser.Session}}" class="panel_tag panel_right_button">Ban</a>{{end}} {{if .Is_Banned}}<a href="/users/unban/{{.ID}}?session={{$.CurrentUser.Session}}" class="panel_tag panel_right_button">Unban</a>{{else if not .Is_Super_Mod}}<a href="/users/ban/{{.ID}}?session={{$.CurrentUser.Session}}" class="panel_tag panel_right_button">Ban</a>{{end}}

View File

@ -25,7 +25,7 @@
<div id="profile_comments" class="colblock_right" style="overflow: hidden;border-top: none;width:calc(95% - 210px);">{{range .ItemList}} <div id="profile_comments" class="colblock_right" style="overflow: hidden;border-top: none;width:calc(95% - 210px);">{{range .ItemList}}
<div class="rowitem passive deletable_block editable_parent simple" style="{{if .Avatar}}background-image: url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Css}}{{end}}"> <div class="rowitem passive deletable_block editable_parent simple" style="{{if .Avatar}}background-image: url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Css}}{{end}}">
<span class="editable_block user_content simple">{{.ContentHtml}}</span><br /><br /> <span class="editable_block user_content simple">{{.ContentHtml}}</span><br /><br />
<a href="/user/{{.CreatedBy}}" class="real_username username">{{.CreatedByName}}</a>&nbsp;&nbsp; <a href="/user/{{.UserSlug}}.{{.CreatedBy}}" class="real_username username">{{.CreatedByName}}</a>&nbsp;&nbsp;
{{if $.CurrentUser.Is_Mod}}<a href="/profile/reply/edit/submit/{{.ID}}" class="mod_button" title="Edit Item"><button class="username edit_item edit_label"></button></a> {{if $.CurrentUser.Is_Mod}}<a href="/profile/reply/edit/submit/{{.ID}}" class="mod_button" title="Edit Item"><button class="username edit_item edit_label"></button></a>

View File

@ -10,7 +10,7 @@
<div class="rowblock topic_block"> <div class="rowblock topic_block">
<form action='/topic/edit/submit/{{.Topic.ID}}' method="post"> <form action='/topic/edit/submit/{{.Topic.ID}}' method="post">
<div class="rowitem rowhead topic_item"{{if .Topic.Sticky}} style="background-color:#FFFFEA;"{{else if .Topic.Is_Closed}} style="background-color:#eaeaea;"{{end}}> <div class="rowitem rowhead topic_item"{{if .Topic.Sticky}} style="background-color:#FFFFEA;"{{else if .Topic.Is_Closed}} style="background-color:#eaeaea;"{{end}}>
<a class='topic_name hide_on_edit'>{{.Topic.Title}}</a> <a class='topic_name hide_on_edit'>{{.Topic.Title}}</a>
{{if .Topic.Is_Closed}}<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='Status: Closed' style="font-weight:normal;float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>{{end}} {{if .Topic.Is_Closed}}<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='Status: Closed' style="font-weight:normal;float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>{{end}}
{{if .CurrentUser.Perms.EditTopic}} {{if .CurrentUser.Perms.EditTopic}}
<input class='show_on_edit topic_name_input' name="topic_name" value='{{.Topic.Title}}' type="text" /> <input class='show_on_edit topic_name_input' name="topic_name" value='{{.Topic.Title}}' type="text" />
@ -27,26 +27,24 @@
<div class="rowitem passive editable_parent post_item" style="border-bottom: none;{{if .Topic.Avatar}}background-image:url({{.Topic.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;{{.Topic.Css}}{{end}}"> <div class="rowitem passive editable_parent post_item" style="border-bottom: none;{{if .Topic.Avatar}}background-image:url({{.Topic.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;{{.Topic.Css}}{{end}}">
<p class="hide_on_edit topic_content user_content" style="margin:0;padding:0;">{{.Topic.Content}}</p> <p class="hide_on_edit topic_content user_content" style="margin:0;padding:0;">{{.Topic.Content}}</p>
<textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea> <textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea>
<span class="controls"> <span class="controls">
<a href="/user/{{.Topic.CreatedBy}}" class="username real_username">{{.Topic.CreatedByName}}</a>&nbsp;&nbsp; <a href="/user/{{.Topic.UserSlug}}.{{.Topic.CreatedBy}}" class="username real_username">{{.Topic.CreatedByName}}</a>&nbsp;&nbsp;
{{if .CurrentUser.Perms.LikeItem}}<a href="/topic/like/submit/{{.Topic.ID}}" class="mod_button" title="Love it" style="color:#202020;"> {{if .CurrentUser.Perms.LikeItem}}<a href="/topic/like/submit/{{.Topic.ID}}" class="mod_button" title="Love it" style="color:#202020;">
<button class="username like_label" style="{{if .Topic.Liked}}background-color:/*#eaffea*/#D6FFD6;{{end}}"></button></a>{{end}} <button class="username like_label" style="{{if .Topic.Liked}}background-color:/*#eaffea*/#D6FFD6;{{end}}"></button></a>{{end}}
{{if .CurrentUser.Perms.EditTopic}}<a href='/topic/edit/{{.Topic.ID}}' class="mod_button open_edit" style="font-weight:normal;" title="Edit Topic"><button class="username edit_label"></button></a>{{end}} {{if .CurrentUser.Perms.EditTopic}}<a href='/topic/edit/{{.Topic.ID}}' class="mod_button open_edit" style="font-weight:normal;" title="Edit Topic"><button class="username edit_label"></button></a>{{end}}
{{if .CurrentUser.Perms.DeleteTopic}}<a href='/topic/delete/submit/{{.Topic.ID}}' class="mod_button" style="font-weight:normal;" title="Delete Topic"><button class="username trash_label"></button></a>{{end}} {{if .CurrentUser.Perms.DeleteTopic}}<a href='/topic/delete/submit/{{.Topic.ID}}' class="mod_button" style="font-weight:normal;" title="Delete Topic"><button class="username trash_label"></button></a>{{end}}
{{if .CurrentUser.Perms.PinTopic}}{{if .Topic.Sticky}}<a class="mod_button" href='/topic/unstick/submit/{{.Topic.ID}}' style="font-weight:normal;" title="Unpin Topic"><button class="username unpin_label"></button></a>{{else}}<a href='/topic/stick/submit/{{.Topic.ID}}' class="mod_button" style="font-weight:normal;" title="Pin Topic"><button class="username pin_label"></button></a>{{end}}{{end}} {{if .CurrentUser.Perms.PinTopic}}{{if .Topic.Sticky}}<a class="mod_button" href='/topic/unstick/submit/{{.Topic.ID}}' style="font-weight:normal;" title="Unpin Topic"><button class="username unpin_label"></button></a>{{else}}<a href='/topic/stick/submit/{{.Topic.ID}}' class="mod_button" style="font-weight:normal;" title="Pin Topic"><button class="username pin_label"></button></a>{{end}}{{end}}
<a class="mod_button" href="/report/submit/{{.Topic.ID}}?session={{.CurrentUser.Session}}&type=topic" class="mod_button report_item" style="font-weight:normal;" title="Flag Topic"><button class="username flag_label"></button></a> <a class="mod_button" href="/report/submit/{{.Topic.ID}}?session={{.CurrentUser.Session}}&type=topic" class="mod_button report_item" style="font-weight:normal;" title="Flag Topic"><button class="username flag_label"></button></a>
{{if .Topic.LikeCount}}<a class="username hide_on_micro like_count">{{.Topic.LikeCount}}</a><a class="username hide_on_micro like_count_label" title="Like Count"></a>{{end}} {{if .Topic.LikeCount}}<a class="username hide_on_micro like_count">{{.Topic.LikeCount}}</a><a class="username hide_on_micro like_count_label" title="Like Count"></a>{{end}}
{{if .Topic.Tag}}<a class="username hide_on_micro" style="float:right;color:#505050;font-size:16px;">{{.Topic.Tag}}</a>{{else}}<a class="username hide_on_micro level">{{.Topic.Level}}</a><a class="username hide_on_micro level_label" style="color:#505050;float:right;opacity:0.85;" title="Level"></a>{{end}} {{if .Topic.Tag}}<a class="username hide_on_micro" style="float:right;color:#505050;font-size:16px;">{{.Topic.Tag}}</a>{{else}}<a class="username hide_on_micro level">{{.Topic.Level}}</a><a class="username hide_on_micro level_label" style="color:#505050;float:right;opacity:0.85;" title="Level"></a>{{end}}
</span> </span>
</div> </div>
</div> </div>
@ -58,23 +56,21 @@
{{else}} {{else}}
<div class="rowitem passive deletable_block editable_parent post_item" style="{{if .Avatar}}background-image:url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;{{.Css}}{{end}}"> <div class="rowitem passive deletable_block editable_parent post_item" style="{{if .Avatar}}background-image:url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat, repeat-y;background-size:128px;padding-left:136px;{{.Css}}{{end}}">
<p class="editable_block user_content" style="margin:0;padding:0;">{{.ContentHtml}}</p> <p class="editable_block user_content" style="margin:0;padding:0;">{{.ContentHtml}}</p>
<span class="controls"> <span class="controls">
<a href="/user/{{.CreatedBy}}" class="username real_username">{{.CreatedByName}}</a>&nbsp;&nbsp; <a href="/user/{{.UserSlug}}.{{.CreatedBy}}" class="username real_username">{{.CreatedByName}}</a>&nbsp;&nbsp;
{{if $.CurrentUser.Perms.LikeItem}}<a href="/reply/like/submit/{{.ID}}" class="mod_button" title="Love it" style="color:#202020;"><button class="username like_label" style="{{if .Liked}}background-color:/*#eaffea*/#D6FFD6;{{end}}"></button></a>{{end}} {{if $.CurrentUser.Perms.LikeItem}}<a href="/reply/like/submit/{{.ID}}" class="mod_button" title="Love it" style="color:#202020;"><button class="username like_label" style="{{if .Liked}}background-color:/*#eaffea*/#D6FFD6;{{end}}"></button></a>{{end}}
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="mod_button" title="Edit Reply"><button class="username edit_item edit_label"></button></a>{{end}} {{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="mod_button" title="Edit Reply"><button class="username edit_item edit_label"></button></a>{{end}}
{{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" class="mod_button" title="Delete Reply"><button class="username delete_item trash_label"></button></a>{{end}} {{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" class="mod_button" title="Delete Reply"><button class="username delete_item trash_label"></button></a>{{end}}
<a class="mod_button" href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" class="mod_button report_item" title="Flag Reply"><button class="username report_item flag_label"></button></a> <a class="mod_button" href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" class="mod_button report_item" title="Flag Reply"><button class="username report_item flag_label"></button></a>
{{if .LikeCount}}<a class="username hide_on_micro like_count">{{.LikeCount}}</a><a class="username hide_on_micro like_count_label" title="Like Count"></a>{{end}} {{if .LikeCount}}<a class="username hide_on_micro like_count">{{.LikeCount}}</a><a class="username hide_on_micro like_count_label" title="Like Count"></a>{{end}}
{{if .Tag}}<a class="username hide_on_micro" style="float: right;color:#505050;font-size:16px;">{{.Tag}}</a>{{else}}<a class="username hide_on_micro level">{{.Level}}</a><a class="username hide_on_micro level_label" style="color:#505050;float:right;opacity:0.85;" title="Level">{{end}}</a> {{if .Tag}}<a class="username hide_on_micro" style="float: right;color:#505050;font-size:16px;">{{.Tag}}</a>{{else}}<a class="username hide_on_micro level">{{.Level}}</a><a class="username hide_on_micro level_label" style="color:#505050;float:right;opacity:0.85;" title="Level">{{end}}</a>
</span> </span>
</div> </div>
{{end}}{{end}}</div> {{end}}{{end}}</div>
@ -92,4 +88,4 @@
</form> </form>
</div> </div>
{{end}} {{end}}
{{template "footer.html" . }} {{template "footer.html" . }}

View File

@ -25,7 +25,7 @@
<div class="rowitem passive deletable_block editable_parent post_item" style="background-color: #eaeaea;padding-top: 4px;padding-left: 5px;clear: both;border-bottom: none;padding-right: 4px;padding-bottom: 2px;"> <div class="rowitem passive deletable_block editable_parent post_item" style="background-color: #eaeaea;padding-top: 4px;padding-left: 5px;clear: both;border-bottom: none;padding-right: 4px;padding-bottom: 2px;">
<div class="userinfo"> <div class="userinfo">
<div class="avatar_item" style="background-image: url({{.Topic.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div> <div class="avatar_item" style="background-image: url({{.Topic.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div>
<a href="/user/{{.Topic.CreatedBy}}" class="the_name">{{.Topic.CreatedByName}}</a> <a href="/user/{{.Topic.UserSlug}}.{{.Topic.CreatedBy}}" class="the_name">{{.Topic.CreatedByName}}</a>
{{if .Topic.Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.Topic.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level {{.Topic.Level}}</div><div class="tag_post"></div></div>{{end}} {{if .Topic.Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.Topic.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level {{.Topic.Level}}</div><div class="tag_post"></div></div>{{end}}
</div> </div>
<div class="content_container"> <div class="content_container">
@ -50,7 +50,7 @@
<div class="rowitem passive deletable_block editable_parent post_item {{if .ActionType}}action_item{{end}}"> <div class="rowitem passive deletable_block editable_parent post_item {{if .ActionType}}action_item{{end}}">
<div class="userinfo"> <div class="userinfo">
<div class="avatar_item" style="background-image: url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div> <div class="avatar_item" style="background-image: url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div>
<a href="/user/{{.CreatedBy}}" class="the_name">{{.CreatedByName}}</a> <a href="/user/{{.UserSlug}}.{{.CreatedBy}}" class="the_name">{{.CreatedByName}}</a>
{{if .Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level {{.Level}}</div><div class="tag_post"></div></div>{{end}} {{if .Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level {{.Level}}</div><div class="tag_post"></div></div>{{end}}
</div> </div>
<div class="content_container" {{if .ActionType}}style="margin-left: 0px;"{{end}}> <div class="content_container" {{if .ActionType}}style="margin-left: 0px;"{{end}}>

View File

@ -9,8 +9,8 @@
<span class="lastReplyAt">{{.LastReplyAt}}</span> <span class="lastReplyAt">{{.LastReplyAt}}</span>
</span> </span>
<span> <span>
<a class="rowtopic" href="/topic/{{.ID}}">{{.Title}}</a> {{if .ForumName}}<a class="rowsmall" href="/forum/{{.ParentID}}">{{.ForumName}}</a>{{end}} <a class="rowtopic" href="/topic/{{.Slug}}.{{.ID}}">{{.Title}}</a> {{if .ForumName}}<a class="rowsmall" href="/forum/{{.ParentID}}">{{.ForumName}}</a>{{end}}
<br /><a class="rowsmall" href="/user/{{.CreatedBy}}">Starter: {{.CreatedByName}}</a> <br /><a class="rowsmall" href="/user/{{.UserSlug}}.{{.CreatedBy}}">Starter: {{.CreatedByName}}</a>
{{if .Is_Closed}}<span class="rowsmall topic_status_e topic_status_closed" title="Status: Closed"> | &#x1F512;&#xFE0E{{end}}</span> {{if .Is_Closed}}<span class="rowsmall topic_status_e topic_status_closed" title="Status: Closed"> | &#x1F512;&#xFE0E{{end}}</span>
</span> </span>
</div> </div>

View File

@ -410,12 +410,21 @@ button .big { padding: 6px; }*/
padding-bottom: 2px; padding-bottom: 2px;
color: #505050 !important; /* 80,80,80 */ color: #505050 !important; /* 80,80,80 */
background-color: #FFFFFF; background-color: #FFFFFF;
border-style: dotted; border-style: solid;
border-color: #505050; /* 232,232,232. All three RGB colours being the same seems to create a shade of gray */ border-color: rgb(180,180,180);
border-width: 1px; border-width: 1px;
font-size: 15px; font-size: 15px;
} }
.simple > .real_username {
color: #404040;
font-size: 16px;
padding-left: 5px;
padding-right: 5px;
padding-top: 3px;
padding-bottom: 3px;
}
.postQuote { .postQuote {
padding: 5px; padding: 5px;
border: 1px solid rgb(200,200,200); border: 1px solid rgb(200,200,200);

View File

@ -399,12 +399,21 @@ button .big { padding: 6px; }*/
padding-bottom: 2px; padding-bottom: 2px;
color: #505050 !important; /* 80,80,80 */ color: #505050 !important; /* 80,80,80 */
background-color: #FFFFFF; background-color: #FFFFFF;
border-style: dotted; border-style: solid;
border-color: #505050; /* 232,232,232. All three RGB colours being the same seems to create a shade of gray */ border-color: rgb(180,180,180);
border-width: 1px; border-width: 1px;
font-size: 15px; font-size: 15px;
} }
.simple > .real_username {
color: #404040;
font-size: 16px;
padding-left: 5px;
padding-right: 5px;
padding-top: 3px;
padding-bottom: 3px;
}
.postQuote { .postQuote {
border-radius: 4px; border-radius: 4px;
padding: 5px; padding: 5px;
@ -588,7 +597,9 @@ blockquote p {
.mod_button { margin-right: 4px; } .mod_button { margin-right: 4px; }
.post_item:not(.simple) { background-color: #eaeaea; } .post_item:not(.simple) {
background-color: #eaeaea;
}
.post_item { .post_item {
padding-top: 4px; padding-top: 4px;
padding-left: 7px !important; padding-left: 7px !important;

View File

@ -333,8 +333,8 @@ button {
padding-bottom: 2px; padding-bottom: 2px;
color: #505050; /* 80,80,80 */ color: #505050; /* 80,80,80 */
background-color: #FFFFFF; background-color: #FFFFFF;
border-style: dotted; border-style: solid;
border-color: #505050; /* 232,232,232. All three RGB colours being the same seems to create a shade of gray */ border-color: #ccc;
border-width: 1px; border-width: 1px;
font-size: 15px; font-size: 15px;
} }
@ -432,12 +432,27 @@ button.username {
.trash_label:before { content: "🗑️"; } .trash_label:before { content: "🗑️"; }
.flag_label:before { content: "🚩"; } .flag_label:before { content: "🚩"; }
.mod_button { margin-right: 4px; } .mod_button {
.simple > .real_username { color: #404040; font-size: 17px; } margin-right: 4px;
.simple > .user_content { background: none; } }
.simple > .real_username {
color: #404040;
font-size: 16px;
padding-left: 5px;
padding-right: 5px;
padding-top: 3px;
padding-bottom: 3px;
}
.simple > .user_content {
background: none;
}
.simple { background-color: white; } .simple {
.post_item:not(.simple) { background-color: #eaeaea; } background-color: white;
}
.post_item:not(.simple) {
background-color: #eaeaea;
}
.post_item { .post_item {
padding-top: 4px; padding-top: 4px;
padding-left: 5px; padding-left: 5px;

View File

@ -145,7 +145,7 @@ li a {
display: none; display: none;
} }
.rowsmall { .rowsmall {
font-size:12px; font-size: 12px;
} }
.colblock_left { .colblock_left {
@ -324,16 +324,33 @@ button {
padding-bottom: 2px; padding-bottom: 2px;
color: #505050; /* 80,80,80 */ color: #505050; /* 80,80,80 */
background-color: #FFFFFF; background-color: #FFFFFF;
border-style: dotted; border-style: solid;
border-color: #505050; /* 232,232,232. All three RGB colours being the same seems to create a shade of gray */ border-color: #ccc;
border-width: 1px; border-width: 1px;
font-size: 15px; font-size: 15px;
} }
button.username { position: relative; top: -0.25px; } button.username {
.username.level { color: #303030; } position: relative;
.username.real_username { color: #404040; font-size: 17px; } top: -0.25px;
.username.real_username:hover { color: black; } }
.post_item > .username { margin-top: 20px; display: inline-block; } .username.level {
color: #303030;
}
.username.real_username {
color: #404040;
font-size: 16px;
padding-left: 5px;
padding-right: 5px;
padding-top: 3px;
padding-bottom: 3px;
}
.username.real_username:hover {
color: black;
}
.post_item > .username {
margin-top: 20px;
display: inline-block;
}
.post_item > .mod_button > button { .post_item > .mod_button > button {
font-size: 15px; font-size: 15px;

View File

@ -7,19 +7,38 @@
padding-right: 3px; padding-right: 3px;
padding-top: 1.5px; padding-top: 1.5px;
padding-bottom: 0px; padding-bottom: 0px;
color: #505050; /* 80,80,80 */ color: #505050 !important; /* 80,80,80 */
background-color: #FFFFFF; background-color: #FFFFFF;
border-style: dotted; border-style: solid;
border-color: #505050; /* 232,232,232. All three RGB colours being the same seems to create a shade of gray */ border-color: #ccc;
border-width: 1px; border-width: 1px;
font-size: 10px; font-size: 10px;
} }
.panel_compactrow .panel_tag {
font-size: 14px;
}
.panel_compactrow {
padding-left: 10px;
padding-top: 10px;
padding-bottom: 10px;
padding-right: 10px;
}
.panel_compacttext {
font-size: 14px;
}
.panel_upshift { .panel_upshift {
font-size: 18px; font-size: 18px;
position: relative; position: relative;
top: -2px; top: -2px;
} }
.panel_compactrow .panel_upshift {
font-size: 16px;
position: static;
}
.panel_upshift:visited { color: black; } .panel_upshift:visited { color: black; }
/*.panel_tag_upshift { /*.panel_tag_upshift {
margin-left: 2px; margin-left: 2px;

View File

@ -6,6 +6,7 @@ import "html/template"
type Topic struct type Topic struct
{ {
ID int ID int
Slug string
Title string Title string
Content string Content string
CreatedBy int CreatedBy int
@ -26,6 +27,7 @@ type Topic struct
type TopicUser struct type TopicUser struct
{ {
ID int ID int
Slug string
Title string Title string
Content string Content string
CreatedBy int CreatedBy int
@ -42,6 +44,7 @@ type TopicUser struct
ClassName string ClassName string
Data string // Used for report metadata Data string // Used for report metadata
UserSlug string
CreatedByName string CreatedByName string
Group int Group int
Avatar string Avatar string
@ -58,6 +61,7 @@ type TopicUser struct
type TopicsRow struct type TopicsRow struct
{ {
ID int ID int
Slug string
Title string Title string
Content string Content string
CreatedBy int CreatedBy int
@ -73,6 +77,7 @@ type TopicsRow struct
LikeCount int LikeCount int
ClassName string ClassName string
UserSlug string
CreatedByName string CreatedByName string
Avatar string Avatar string
Css template.CSS Css template.CSS
@ -115,8 +120,10 @@ func get_topicuser(tid int) (TopicUser,error) {
tu := TopicUser{ID:tid} tu := TopicUser{ID:tid}
err := get_topic_user_stmt.QueryRow(tid).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) err := get_topic_user_stmt.QueryRow(tid).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)
tu.Slug = name_to_slug(tu.Title)
tu.UserSlug = name_to_slug(tu.CreatedByName)
the_topic := Topic{ID:tu.ID, Title:tu.Title, Content:tu.Content, CreatedBy:tu.CreatedBy, Is_Closed:tu.Is_Closed, Sticky:tu.Sticky, CreatedAt:tu.CreatedAt, LastReplyAt:tu.LastReplyAt, ParentID:tu.ParentID, IpAddress:tu.IpAddress, PostCount:tu.PostCount, LikeCount:tu.LikeCount} the_topic := Topic{ID:tu.ID, Slug:tu.Slug, Title:tu.Title, Content:tu.Content, CreatedBy:tu.CreatedBy, Is_Closed:tu.Is_Closed, Sticky:tu.Sticky, CreatedAt:tu.CreatedAt, LastReplyAt:tu.LastReplyAt, ParentID:tu.ParentID, IpAddress:tu.IpAddress, PostCount:tu.PostCount, LikeCount:tu.LikeCount}
//fmt.Printf("%+v\n", the_topic) //fmt.Printf("%+v\n", the_topic)
tu.Tag = groups[tu.Group].Tag tu.Tag = groups[tu.Group].Tag
topics.Add(&the_topic) topics.Add(&the_topic)
@ -124,6 +131,7 @@ func get_topicuser(tid int) (TopicUser,error) {
} }
func copy_topic_to_topicuser(topic *Topic, user *User) (tu TopicUser) { func copy_topic_to_topicuser(topic *Topic, user *User) (tu TopicUser) {
tu.UserSlug = user.Slug
tu.CreatedByName = user.Name tu.CreatedByName = user.Name
tu.Group = user.Group tu.Group = user.Group
tu.Avatar = user.Avatar tu.Avatar = user.Avatar
@ -132,6 +140,7 @@ func copy_topic_to_topicuser(topic *Topic, user *User) (tu TopicUser) {
tu.Level = user.Level tu.Level = user.Level
tu.ID = topic.ID tu.ID = topic.ID
tu.Slug = topic.Slug
tu.Title = topic.Title tu.Title = topic.Title
tu.Content = topic.Content tu.Content = topic.Content
tu.CreatedBy = topic.CreatedBy tu.CreatedBy = topic.CreatedBy
@ -144,15 +153,20 @@ func copy_topic_to_topicuser(topic *Topic, user *User) (tu TopicUser) {
tu.PostCount = topic.PostCount tu.PostCount = topic.PostCount
tu.LikeCount = topic.LikeCount tu.LikeCount = topic.LikeCount
tu.Data = topic.Data tu.Data = topic.Data
return tu return tu
} }
func get_topic_by_reply(rid int) (*Topic, error) { func get_topic_by_reply(rid int) (*Topic, error) {
topic := Topic{ID:0} topic := Topic{ID:0}
err := get_topic_by_reply_stmt.QueryRow(rid).Scan(&topic.ID, &topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data) err := get_topic_by_reply_stmt.QueryRow(rid).Scan(&topic.ID, &topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
topic.Slug = name_to_slug(topic.Title)
return &topic, err return &topic, err
} }
func build_topic_url(tid int) string { func build_topic_url(slug string, tid int) string {
return "/topic/" + strconv.Itoa(tid) if slug == "" {
return "/topic/" + strconv.Itoa(tid)
}
return "/topic/" + slug + "." + strconv.Itoa(tid)
} }

View File

@ -50,7 +50,7 @@ func (sts *MemoryTopicStore) Get(id int) (*Topic, error) {
if ok { if ok {
return item, nil return item, nil
} }
return item, sql.ErrNoRows return item, ErrNoRows
} }
func (sts *MemoryTopicStore) GetUnsafe(id int) (*Topic, error) { func (sts *MemoryTopicStore) GetUnsafe(id int) (*Topic, error) {
@ -58,7 +58,7 @@ func (sts *MemoryTopicStore) GetUnsafe(id int) (*Topic, error) {
if ok { if ok {
return item, nil return item, nil
} }
return item, sql.ErrNoRows return item, ErrNoRows
} }
func (sts *MemoryTopicStore) CascadeGet(id int) (*Topic, error) { func (sts *MemoryTopicStore) CascadeGet(id int) (*Topic, error) {
@ -72,6 +72,7 @@ func (sts *MemoryTopicStore) CascadeGet(id int) (*Topic, error) {
topic = &Topic{ID:id} topic = &Topic{ID:id}
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data) err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
if err == nil { if err == nil {
topic.Slug = name_to_slug(topic.Title)
sts.Add(topic) sts.Add(topic)
} }
return topic, err return topic, err
@ -80,6 +81,7 @@ func (sts *MemoryTopicStore) CascadeGet(id int) (*Topic, error) {
func (sts *MemoryTopicStore) BypassGet(id int) (*Topic, error) { func (sts *MemoryTopicStore) BypassGet(id int) (*Topic, error) {
topic := &Topic{ID:id} topic := &Topic{ID:id}
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data) err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
topic.Slug = name_to_slug(topic.Title)
return topic, err return topic, err
} }
@ -87,6 +89,7 @@ func (sts *MemoryTopicStore) Load(id int) error {
topic := &Topic{ID:id} topic := &Topic{ID:id}
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data) err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
if err == nil { if err == nil {
topic.Slug = name_to_slug(topic.Title)
sts.Set(topic) sts.Set(topic)
} else { } else {
sts.Remove(id) sts.Remove(id)
@ -176,30 +179,35 @@ func NewSqlTopicStore() *SqlTopicStore {
func (sts *SqlTopicStore) Get(id int) (*Topic, error) { func (sts *SqlTopicStore) Get(id int) (*Topic, error) {
topic := Topic{ID:id} topic := Topic{ID:id}
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data) err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
topic.Slug = name_to_slug(topic.Title)
return &topic, err return &topic, err
} }
func (sts *SqlTopicStore) GetUnsafe(id int) (*Topic, error) { func (sts *SqlTopicStore) GetUnsafe(id int) (*Topic, error) {
topic := Topic{ID:id} topic := Topic{ID:id}
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data) err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
topic.Slug = name_to_slug(topic.Title)
return &topic, err return &topic, err
} }
func (sts *SqlTopicStore) CascadeGet(id int) (*Topic, error) { func (sts *SqlTopicStore) CascadeGet(id int) (*Topic, error) {
topic := Topic{ID:id} topic := Topic{ID:id}
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data) err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
topic.Slug = name_to_slug(topic.Title)
return &topic, err return &topic, err
} }
func (sts *SqlTopicStore) BypassGet(id int) (*Topic, error) { func (sts *SqlTopicStore) BypassGet(id int) (*Topic, error) {
topic := &Topic{ID:id} topic := &Topic{ID:id}
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data) err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
topic.Slug = name_to_slug(topic.Title)
return topic, err return topic, err
} }
func (sts *SqlTopicStore) Load(id int) error { func (sts *SqlTopicStore) Load(id int) error {
topic := Topic{ID:id} topic := Topic{ID:id}
err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data) err := sts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.LikeCount, &topic.Data)
topic.Slug = name_to_slug(topic.Title)
return err return err
} }

50
user.go
View File

@ -7,9 +7,8 @@ import (
"net" "net"
"net/http" "net/http"
"html/template" "html/template"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"database/sql"
_ "github.com/go-sql-driver/mysql"
) )
var guest_user User = User{ID:0,Group:6,Perms:GuestPerms} var guest_user User = User{ID:0,Group:6,Perms:GuestPerms}
@ -20,6 +19,7 @@ var SimplePanelSessionCheck func(http.ResponseWriter, *http.Request) (User,bool)
type User struct type User struct
{ {
ID int ID int
Slug string
Name string Name string
Email string Email string
Group int Group int
@ -40,7 +40,6 @@ type User struct
Level int Level int
Score int Score int
Last_IP string Last_IP string
//WS_Conn interface{}
} }
type Email struct type Email struct
@ -86,9 +85,27 @@ func SendValidationEmail(username string, email string, token string) bool {
return SendEmail(email, subject, msg) return SendEmail(email, subject, msg)
} }
// TO-DO: Support for left sidebars and sidebars on both sides
func BuildWidgets(zone string, data interface{}, headerVars *HeaderVars) {
//fmt.Println("themes[defaultTheme].Sidebars",themes[defaultTheme].Sidebars)
if themes[defaultTheme].Sidebars == "right" {
if len(docks.RightSidebar) != 0 {
var sbody string
for _, widget := range docks.RightSidebar {
if widget.Enabled {
if widget.Location == "global" || widget.Location == zone {
sbody += widget.Body
}
}
}
headerVars.Widgets.RightSidebar = template.HTML(sbody)
}
}
}
func SimpleForumSessionCheck(w http.ResponseWriter, r *http.Request, fid int) (user User, success bool) { func SimpleForumSessionCheck(w http.ResponseWriter, r *http.Request, fid int) (user User, success bool) {
user, success = SimpleSessionCheck(w,r) user, success = SimpleSessionCheck(w,r)
if !forum_exists(fid) { if !fstore.Exists(fid) {
PreError("The target forum doesn't exist.",w,r) PreError("The target forum doesn't exist.",w,r)
return user, false return user, false
} }
@ -117,7 +134,7 @@ func SimpleForumSessionCheck(w http.ResponseWriter, r *http.Request, fid int) (u
func ForumSessionCheck(w http.ResponseWriter, r *http.Request, fid int) (user User, headerVars HeaderVars, success bool) { func ForumSessionCheck(w http.ResponseWriter, r *http.Request, fid int) (user User, headerVars HeaderVars, success bool) {
user, headerVars, success = SessionCheck(w,r) user, headerVars, success = SessionCheck(w,r)
if !forum_exists(fid) { if !fstore.Exists(fid) {
NotFound(w,r) NotFound(w,r)
return user, headerVars, false return user, headerVars, false
} }
@ -206,20 +223,6 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, headerVars
} }
} }
// TO-DO: Support for left sidebars and sidebars on both sides
//fmt.Println("themes[defaultTheme].Sidebars",themes[defaultTheme].Sidebars)
if themes[defaultTheme].Sidebars == "right" {
if len(docks.RightSidebar) != 0 {
var sbody string
for _, widget := range docks.RightSidebar {
if widget.Enabled && widget.Location == "global" {
sbody += widget.Body
}
}
headerVars.Widgets.RightSidebar = template.HTML(sbody)
}
}
return user, headerVars, success return user, headerVars, success
} }
@ -240,7 +243,7 @@ func _simple_session_check(w http.ResponseWriter, r *http.Request) (User,bool) {
// Is this session valid..? // Is this session valid..?
user, err := users.CascadeGet(uid) user, err := users.CascadeGet(uid)
if err == sql.ErrNoRows { if err == ErrNoRows {
return guest_user, true return guest_user, true
} else if err != nil { } else if err != nil {
InternalError(err,w,r) InternalError(err,w,r)
@ -374,6 +377,9 @@ func init_user_perms(user *User) {
} }
} }
func build_profile_url(uid int) string { func build_profile_url(slug string, uid int) string {
return "/user/" + strconv.Itoa(uid) if slug == "" {
return "/user/" + strconv.Itoa(uid)
}
return "/user/" + slug + "." + strconv.Itoa(uid)
} }

View File

@ -6,6 +6,7 @@ import "errors"
import "strings" import "strings"
import "strconv" import "strconv"
import "database/sql" import "database/sql"
import "./query_gen/lib" import "./query_gen/lib"
import "golang.org/x/crypto/bcrypt" import "golang.org/x/crypto/bcrypt"
@ -21,8 +22,6 @@ type UserStore interface {
Set(item *User) error Set(item *User) error
Add(item *User) error Add(item *User) error
AddUnsafe(item *User) error AddUnsafe(item *User) error
//SetConn(conn interface{}) error
//GetConn() interface{}
Remove(id int) error Remove(id int) error
RemoveUnsafe(id int) error RemoveUnsafe(id int) error
CreateUser(username string, password string, email string, group int, active int) (int, error) CreateUser(username string, password string, email string, group int, active int) (int, error)
@ -74,7 +73,7 @@ func (sus *MemoryUserStore) Get(id int) (*User, error) {
if ok { if ok {
return item, nil return item, nil
} }
return item, sql.ErrNoRows return item, ErrNoRows
} }
func (sus *MemoryUserStore) GetUnsafe(id int) (*User, error) { func (sus *MemoryUserStore) GetUnsafe(id int) (*User, error) {
@ -82,7 +81,7 @@ func (sus *MemoryUserStore) GetUnsafe(id int) (*User, error) {
if ok { if ok {
return item, nil return item, nil
} }
return item, sql.ErrNoRows return item, ErrNoRows
} }
func (sus *MemoryUserStore) CascadeGet(id int) (*User, error) { func (sus *MemoryUserStore) CascadeGet(id int) (*User, error) {
@ -103,6 +102,7 @@ func (sus *MemoryUserStore) CascadeGet(id int) (*User, error) {
} else { } else {
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
} }
user.Slug = name_to_slug(user.Name)
user.Tag = groups[user.Group].Tag user.Tag = groups[user.Group].Tag
init_user_perms(user) init_user_perms(user)
if err == nil { if err == nil {
@ -122,6 +122,7 @@ func (sus *MemoryUserStore) BypassGet(id int) (*User, error) {
} else { } else {
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
} }
user.Slug = name_to_slug(user.Name)
user.Tag = groups[user.Group].Tag user.Tag = groups[user.Group].Tag
init_user_perms(user) init_user_perms(user)
return user, err return user, err
@ -142,6 +143,7 @@ func (sus *MemoryUserStore) Load(id int) error {
} else { } else {
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
} }
user.Slug = name_to_slug(user.Name)
user.Tag = groups[user.Group].Tag user.Tag = groups[user.Group].Tag
init_user_perms(user) init_user_perms(user)
sus.Set(user) sus.Set(user)
@ -202,7 +204,7 @@ func (sus *MemoryUserStore) RemoveUnsafe(id int) error {
func (sus *MemoryUserStore) CreateUser(username string, password string, email string, group int, active int) (int, error) { func (sus *MemoryUserStore) CreateUser(username string, password string, email string, group int, active int) (int, error) {
// Is this username already taken..? // Is this username already taken..?
err := sus.username_exists.QueryRow(username).Scan(&username) err := sus.username_exists.QueryRow(username).Scan(&username)
if err != sql.ErrNoRows { if err != ErrNoRows {
return 0, err_account_exists return 0, err_account_exists
} }
@ -279,6 +281,7 @@ func (sus *SqlUserStore) Get(id int) (*User, error) {
} else { } else {
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
} }
user.Slug = name_to_slug(user.Name)
user.Tag = groups[user.Group].Tag user.Tag = groups[user.Group].Tag
init_user_perms(&user) init_user_perms(&user)
return &user, err return &user, err
@ -295,6 +298,7 @@ func (sus *SqlUserStore) GetUnsafe(id int) (*User, error) {
} else { } else {
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
} }
user.Slug = name_to_slug(user.Name)
user.Tag = groups[user.Group].Tag user.Tag = groups[user.Group].Tag
init_user_perms(&user) init_user_perms(&user)
return &user, err return &user, err
@ -311,6 +315,7 @@ func (sus *SqlUserStore) CascadeGet(id int) (*User, error) {
} else { } else {
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
} }
user.Slug = name_to_slug(user.Name)
user.Tag = groups[user.Group].Tag user.Tag = groups[user.Group].Tag
init_user_perms(&user) init_user_perms(&user)
return &user, err return &user, err
@ -327,6 +332,7 @@ func (sus *SqlUserStore) BypassGet(id int) (*User, error) {
} else { } else {
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
} }
user.Slug = name_to_slug(user.Name)
user.Tag = groups[user.Group].Tag user.Tag = groups[user.Group].Tag
init_user_perms(&user) init_user_perms(&user)
return &user, err return &user, err
@ -342,7 +348,7 @@ func (sus *SqlUserStore) Load(id int) error {
func (sus *SqlUserStore) CreateUser(username string, password string, email string, group int, active int) (int, error) { func (sus *SqlUserStore) CreateUser(username string, password string, email string, group int, active int) (int, error) {
// Is this username already taken..? // Is this username already taken..?
err := sus.username_exists.QueryRow(username).Scan(&username) err := sus.username_exists.QueryRow(username).Scan(&username)
if err != sql.ErrNoRows { if err != ErrNoRows {
return 0, err_account_exists return 0, err_account_exists
} }
@ -365,7 +371,7 @@ func (sus *SqlUserStore) CreateUser(username string, password string, email stri
return int(lastId), err return int(lastId), err
} }
// Placeholder methods, the actual queries are done elsewhere // Placeholder methods, as we're not don't need to do any cache management with this implementation ofr the UserStore
func (sus *SqlUserStore) Set(item *User) error { func (sus *SqlUserStore) Set(item *User) error {
return nil return nil
} }

View File

@ -123,6 +123,26 @@ func convert_friendly_unit(num int) (int,string) {
} }
} }
func name_to_slug(name string) (slug string) {
name = strings.TrimSpace(name)
name = strings.Replace(name," "," ",-1)
for _, char := range name {
if unicode.IsLower(char) || unicode.IsNumber(char) {
slug += string(char)
} else if unicode.IsUpper(char) {
slug += string(unicode.ToLower(char))
} else if unicode.IsSpace(char) {
slug += "-"
}
}
if slug == "" {
slug = "untitled"
}
return slug
}
func SendEmail(email string, subject string, msg string) (res bool) { func SendEmail(email string, subject string, msg string) (res bool) {
// This hook is useful for plugin_sendmail or for testing tools. Possibly to hook it into some sort of mail server? // This hook is useful for plugin_sendmail or for testing tools. Possibly to hook it into some sort of mail server?
if vhooks["email_send_intercept"] != nil { if vhooks["email_send_intercept"] != nil {
@ -316,13 +336,6 @@ func getLevels(maxLevel int) []float64 {
return out return out
} }
func fill_forum_id_gap(biggerID int, smallerID int) {
dummy := Forum{ID:0,Name:"",Active:false,Preset:"all"}
for i := smallerID; i > biggerID; i++ {
forums = append(forums, dummy)
}
}
func fill_group_id_gap(biggerID int, smallerID int) { func fill_group_id_gap(biggerID int, smallerID int) {
dummy := Group{ID:0, Name:""} dummy := Group{ID:0, Name:""}
for i := smallerID; i > biggerID; i++ { for i := smallerID; i > biggerID; i++ {