Dramatically improved Gosora's speed by two to four times.

Admins and mods can now see the IP Addresses of users.
The last IP Address of a user is now tracked.
The IP Addresses a user used to create replies and topics are now tracked.
Dramatically improved the speed of templates with the new Fragment System. More optimisations to come!
Decreased the memory usage of compiled templates with the new Fragment System.
build.bat now provides more information on what it's doing.
Added the `go generate` command to the .bat files in preparation for the future.
We're currently in the process of overhauling the benchmark system to run tests in parallel rather than serially. More news on that later.
We're also looking into the best way of integrating pprof with the benchmarks for detailed profiling.
The internal and notfound errors are now static pages.
Internal Error pages are now served properly.
Optimised most of the errors.
Added an internal flag for checking if the plugins have been initialised yet. Mainly for tests.
Decoupled the global initialisation code from the tests.
Removed URL Tags from Tempra Simple. We're pondering over how to re-introduce this in a less intrusive way.
Template file writing is now multi-threaded.
The number of maximum open connections is now explicitly set.
Removed the Name field from the page struct.
Turned some of the most frequently hit queries into prepared statements.
Added the [rand] BBCode.
Converted the NoticeList map into a slice.
Added the missing_tag error type to the [url] tag.
error_notfound is now used for when the router can't find a route.
Fixed a bug in the custom page route where both the page AND the error is served when the page doesn't exist.
Removed some deferrals.
Reduced the number of allocations on the topic page.
run.bat now provides more information on what it's doing.
This commit is contained in:
Azareal 2017-01-17 07:55:46 +00:00
parent 2f50da8cd8
commit d4ad7f1a4c
35 changed files with 1716 additions and 893 deletions

5
.gitignore vendored
View File

@ -1,4 +1,9 @@
tmp/*
tmp2/*
uploads/avatar_* uploads/avatar_*
bin/* bin/*
gosora.exe gosora.exe
gosora.test.exe
install.exe install.exe
*.prof

View File

@ -1,9 +1,19 @@
@echo off @echo off
echo Generating the dynamic code
go generate
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the executable
go build go build
if %errorlevel% neq 0 ( if %errorlevel% neq 0 (
pause pause
exit /b %errorlevel% exit /b %errorlevel%
) )
echo Building the installer
go build ./install go build ./install
if %errorlevel% neq 0 ( if %errorlevel% neq 0 (
pause pause

View File

@ -32,3 +32,4 @@ var ssl_fullchain = ""
// Developer flag // Developer flag
var debug = false var debug = false
var profiling = false

View File

@ -130,8 +130,8 @@ INSERT INTO settings(`name`,`content`,`type`) VALUES ('bigpost_min_chars','250',
INSERT INTO settings(`name`,`content`,`type`) VALUES ('megapost_min_chars','1000','int'); INSERT INTO settings(`name`,`content`,`type`) VALUES ('megapost_min_chars','1000','int');
INSERT INTO themes(`uname`,`default`) VALUES ('tempra-simple',1); INSERT INTO themes(`uname`,`default`) VALUES ('tempra-simple',1);
INSERT INTO users(`name`,`password`,`email`,`group`,`is_super_admin`,`createdAt`,`lastActiveAt`,`message`) INSERT INTO users(`name`,`password`,`email`,`group`,`is_super_admin`,`createdAt`,`lastActiveAt`,`message`,`last_ip`)
VALUES ('Admin','password','admin@localhost',1,1,NOW(),NOW(),''); VALUES ('Admin','password','admin@localhost',1,1,NOW(),NOW(),'','127.0.0.1');
INSERT INTO emails(`email`,`uid`,`validated`) VALUES ('admin@localhost',1,1); INSERT INTO emails(`email`,`uid`,`validated`) VALUES ('admin@localhost',1,1);
/* /*

139
errors.go
View File

@ -4,160 +4,153 @@ import "log"
import "bytes" import "bytes"
import "net/http" import "net/http"
func InternalError(err error, w http.ResponseWriter, r *http.Request, user User) { var error_internal []byte
log.Fatal(err) var error_notfound []byte
pi := Page{"Internal Server Error","error",user,nList,tList,"A problem has occured in the system."} func init_errors() error {
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) user := User{0,"Guest","",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"0.0.0.0.0"}
errpage := b.String() pi := Page{"Internal Server Error",user,nList,tList,"A problem has occurred in the system."}
w.WriteHeader(500) err := templates.ExecuteTemplate(&b,"error.html", pi)
fmt.Fprintln(w,errpage) if err != nil {
return err
}
error_internal = b.Bytes()
b.Reset()
pi = Page{"Not Found",user,nList,tList,"The requested page doesn't exist."}
err = templates.ExecuteTemplate(&b,"error.html", pi)
if err != nil {
return err
}
error_notfound = b.Bytes()
return nil
}
func InternalError(err error, w http.ResponseWriter, r *http.Request, user User) {
w.Write(error_internal)
log.Fatal(err)
} }
func InternalErrorJSQ(err error, w http.ResponseWriter, r *http.Request, user User, is_js string) { func InternalErrorJSQ(err error, w http.ResponseWriter, r *http.Request, user User, is_js string) {
log.Fatal(err) w.WriteHeader(500)
errmsg := "A problem has occured in the system."
if is_js == "0" { if is_js == "0" {
pi := Page{"Internal Server Error","error",user,nList,tList,errmsg} w.Write(error_internal)
var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(500)
fmt.Fprintln(w,errpage)
} else { } else {
http.Error(w,"{'errmsg': '" + errmsg + "'}",500) w.Write([]byte(`{'errmsg': 'A problem has occured in the system.'}`))
} }
log.Fatal(err)
} }
func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user User) { func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user User) {
pi := Page{"Local Error","error",user,nList,tList,errmsg} w.WriteHeader(500)
pi := Page{"Local Error",user,nList,tList,errmsg}
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String() fmt.Fprintln(w,b.String())
w.WriteHeader(500)
fmt.Fprintln(w,errpage)
} }
func LoginRequired(w http.ResponseWriter, r *http.Request, user User) { func LoginRequired(w http.ResponseWriter, r *http.Request, user User) {
pi := Page{"Local Error","error",user,nList,tList,"You need to login to do that."} w.WriteHeader(401)
pi := Page{"Local Error",user,nList,tList,"You need to login to do that."}
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String() fmt.Fprintln(w,b.String())
w.WriteHeader(401)
fmt.Fprintln(w,errpage)
} }
func LocalErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, user User, is_js string) { func LocalErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, user User, is_js string) {
w.WriteHeader(500)
if is_js == "0" { if is_js == "0" {
pi := Page{"Local Error","error",user,nList,tList,errmsg} pi := Page{"Local Error",user,nList,tList,errmsg}
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String() fmt.Fprintln(w,b.String())
w.WriteHeader(500)
fmt.Fprintln(w,errpage)
} else { } else {
http.Error(w,"{'errmsg': '" + errmsg + "'}",500) w.Write([]byte(`{'errmsg': '` + errmsg + `'}`))
} }
} }
func NoPermissions(w http.ResponseWriter, r *http.Request, user User) { func NoPermissions(w http.ResponseWriter, r *http.Request, user User) {
errmsg := "You don't have permission to do that." w.WriteHeader(403)
pi := Page{"Local Error","error",user,nList,tList,errmsg} pi := Page{"Local Error",user,nList,tList,"You don't have permission to do that."}
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String() errpage := b.String()
w.WriteHeader(403)
fmt.Fprintln(w,errpage) fmt.Fprintln(w,errpage)
} }
func NoPermissionsJSQ(w http.ResponseWriter, r *http.Request, user User, is_js string) { func NoPermissionsJSQ(w http.ResponseWriter, r *http.Request, user User, is_js string) {
errmsg := "You don't have permission to do that." w.WriteHeader(403)
if is_js == "0" { if is_js == "0" {
pi := Page{"Local Error","error",user,nList,tList,errmsg} pi := Page{"Local Error",user,nList,tList,"You don't have permission to do that."}
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String() fmt.Fprintln(w,b.String())
w.WriteHeader(403)
fmt.Fprintln(w,errpage)
} else { } else {
http.Error(w,"{'errmsg': '" + errmsg + "'}",403) w.Write([]byte("{'errmsg': 'You don't have permission to do that.'}"))
} }
} }
func Banned(w http.ResponseWriter, r *http.Request, user User) { func Banned(w http.ResponseWriter, r *http.Request, user User) {
pi := Page{"Banned","error",user,nList,tList,"You have been banned from this site."} w.WriteHeader(403)
pi := Page{"Banned",user,nList,tList,"You have been banned from this site."}
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String() fmt.Fprintln(w,b.String())
w.WriteHeader(403)
fmt.Fprintln(w,errpage)
} }
func BannedJSQ(w http.ResponseWriter, r *http.Request, user User, is_js string) { func BannedJSQ(w http.ResponseWriter, r *http.Request, user User, is_js string) {
w.WriteHeader(403)
if is_js == "0" { if is_js == "0" {
pi := Page{"Banned","error",user,nList,tList,"You have been banned from this site."} pi := Page{"Banned",user,nList,tList,"You have been banned from this site."}
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String() fmt.Fprintln(w,b.String())
w.WriteHeader(403)
fmt.Fprintln(w,errpage)
} else { } else {
http.Error(w,"{'errmsg': 'You have been banned from this site.'}",403) w.Write([]byte("{'errmsg': 'You have been banned from this site.'}"))
} }
} }
func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user User, is_js string) { func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user User, is_js string) {
w.WriteHeader(401)
if is_js == "0" { if is_js == "0" {
pi := Page{"Local Error","error",user,nList,tList,"You need to login to do that."} pi := Page{"Local Error",user,nList,tList,"You need to login to do that."}
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String() fmt.Fprintln(w,b.String())
w.WriteHeader(401)
fmt.Fprintln(w,errpage)
} else { } else {
http.Error(w,"{'errmsg': 'You need to login to do that.'}",401) w.Write([]byte("{'errmsg': 'You need to login to do that.'}"))
} }
} }
func SecurityError(w http.ResponseWriter, r *http.Request, user User) { func SecurityError(w http.ResponseWriter, r *http.Request, user User) {
errmsg := "There was a security issue with your request." w.WriteHeader(403)
pi := Page{"Security Error","error",user,nList,tList,errmsg} pi := Page{"Security Error",user,nList,tList,"There was a security issue with your request."}
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String() fmt.Fprintln(w,b.String())
w.WriteHeader(403)
fmt.Fprintln(w,errpage)
} }
func NotFound(w http.ResponseWriter, r *http.Request, user User) { func NotFound(w http.ResponseWriter, r *http.Request, user User) {
errmsg := "The requested page doesn't exist."
pi := Page{"Not Found","error",user,nList,tList,errmsg}
var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(404) w.WriteHeader(404)
fmt.Fprintln(w,errpage) w.Write(error_notfound)
} }
func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, user User) { func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, user User) {
pi := Page{errtitle,"error",user,nList,tList,errmsg} w.WriteHeader(errcode)
pi := Page{errtitle,user,nList,tList,errmsg}
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String() fmt.Fprintln(w,b.String())
w.WriteHeader(errcode)
fmt.Fprintln(w,errpage)
} }
func CustomErrorJSQ(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, user User, is_js string) { func CustomErrorJSQ(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, user User, is_js string) {
w.WriteHeader(errcode)
if is_js == "0" { if is_js == "0" {
pi := Page{errtitle,"error",user,nList,tList,errmsg} pi := Page{errtitle,user,nList,tList,errmsg}
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String() fmt.Fprintln(w,b.String())
w.WriteHeader(errcode)
fmt.Fprintln(w,errpage)
} else { } else {
http.Error(w,"{'errmsg': '" + errmsg + "'}",errcode) w.Write([]byte(`{'errmsg': '` + errmsg + `'}`))
} }
} }

View File

@ -78,6 +78,7 @@ func (plugin *Plugin) RemoveHook(name string, handler interface{}) {
delete(plugin.Hooks, name) delete(plugin.Hooks, name)
} }
var plugins_inited bool = false
func init_plugins() { func init_plugins() {
for name, body := range plugins { for name, body := range plugins {
log.Print("Added plugin " + name) log.Print("Added plugin " + name)
@ -86,6 +87,7 @@ func init_plugins() {
plugins[name].Init() plugins[name].Init()
} }
} }
plugins_inited = true
} }
func run_hook(name string, data interface{}) interface{} { func run_hook(name string, data interface{}) interface{} {

View File

@ -1,4 +1,5 @@
package main package main
import "os"
import "log" import "log"
import "bytes" import "bytes"
import "strconv" import "strconv"
@ -8,29 +9,50 @@ import "net/http"
import "net/http/httptest" import "net/http/httptest"
import "io/ioutil" import "io/ioutil"
import "html/template" import "html/template"
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
//import "github.com/husobee/vestigo" //import "github.com/husobee/vestigo"
import "runtime/pprof"
var gloinited bool = false
func gloinit() {
debug = false
nogrouplog = true
// init_database is a little noisy for a benchmark
//discard := ioutil.Discard
//log.SetOutput(discard)
var err error
init_database(err)
db.SetMaxOpenConns(64)
external_sites["YT"] = "https://www.youtube.com/"
hooks["trow_assign"] = nil
hooks["rrow_assign"] = nil
//log.SetOutput(os.Stdout)
gloinited = true
}
func BenchmarkTopicTemplate(b *testing.B) { func BenchmarkTopicTemplate(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0} 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} admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58,"127.0.0.1"}
var noticeList map[int]string = make(map[int]string) noticeList := []string{"test"}
noticeList[0] = "test"
topic := TopicUser{Title: "Lol",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58} topic := TopicUser{Title: "Lol",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"}
var replyList []Reply var replyList []Reply
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0}) replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0}) replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0}) replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0}) replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0}) replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0}) replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0}) replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0}) replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0}) replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0}) replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
tpage := TopicPage{"Topic Blah",user,noticeList,replyList,topic,false} tpage := TopicPage{"Topic Blah",user,noticeList,replyList,topic,false}
tpage2 := TopicPage{"Topic Blah",admin,noticeList,replyList,topic,false} tpage2 := TopicPage{"Topic Blah",admin,noticeList,replyList,topic,false}
@ -56,61 +78,253 @@ func BenchmarkTopicTemplate(b *testing.B) {
templates.ExecuteTemplate(w,"topic.html", tpage) templates.ExecuteTemplate(w,"topic.html", tpage)
} }
}) })
w2 := httptest.NewRecorder()
b.Run("compiled_useradmin_recorder", func(b *testing.B) {
for i := 0; i < b.N; i++ {
w2.Body.Reset()
template_topic(tpage2,w2)
}
})
b.Run("interpreted_useradmin_recorder", func(b *testing.B) {
for i := 0; i < b.N; i++ {
w2.Body.Reset()
templates.ExecuteTemplate(w2,"topic.html", tpage2)
}
})
b.Run("compiled_userguest_recorder", func(b *testing.B) {
for i := 0; i < b.N; i++ {
w2.Body.Reset()
template_topic(tpage,w2)
}
})
b.Run("interpreted_userguest_recorder", func(b *testing.B) {
for i := 0; i < b.N; i++ {
w2.Body.Reset()
templates.ExecuteTemplate(w2,"topic.html", tpage)
}
})
/*f, err := os.Create("topic_bench.prof")
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()*/
} }
func BenchmarkTopicsTemplate(b *testing.B) { func BenchmarkTopicsTemplate(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0} 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} admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58,"127.0.0.1"}
var noticeList map[int]string = make(map[int]string) noticeList := []string{"test"}
noticeList[0] = "test"
var topicList []TopicUser var topicList []TopicUser
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58}) topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58}) topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58}) topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58}) topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58}) topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58}) topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58}) topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58}) topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58}) topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58}) topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
tpage := TopicsPage{"Topic Blah",user,noticeList,topicList,0}
tpage2 := TopicsPage{"Topic Blah",admin,noticeList,topicList,0}
w := ioutil.Discard w := ioutil.Discard
tpage := TopicsPage{"Topic Blah",user,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)
} }
}) })
b.Run("interpreted_useradmin", func(b *testing.B) { b.Run("interpreted_useradmin",func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
templates.ExecuteTemplate(w,"topics.html", tpage2) templates.ExecuteTemplate(w,"topics.html", tpage2)
} }
}) })
b.Run("compiled_userguest", func(b *testing.B) { b.Run("compiled_userguest",func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
template_topics(tpage,w) template_topics(tpage,w)
} }
}) })
b.Run("interpreted_userguest", func(b *testing.B) { b.Run("interpreted_userguest",func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
templates.ExecuteTemplate(w,"topics.html", tpage) templates.ExecuteTemplate(w,"topics.html", tpage)
} }
}) })
} }
func BenchmarkRoute(b *testing.B) { func BenchmarkStaticRouteParallel(b *testing.B) {
b.ReportAllocs()
if !gloinited {
gloinit()
}
b.RunParallel(func(pb *testing.PB) {
static_w := httptest.NewRecorder()
static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil))
static_handler := http.HandlerFunc(route_static)
for pb.Next() {
static_w.Body.Reset()
static_handler.ServeHTTP(static_w,static_req)
}
})
}
/*func BenchmarkStaticRouteParallelWithPlugins(b *testing.B) {
b.ReportAllocs()
if !gloinited {
gloinit()
}
if !plugins_inited {
init_plugins()
}
b.RunParallel(func(pb *testing.PB) {
static_w := httptest.NewRecorder()
static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil))
static_handler := http.HandlerFunc(route_static)
for pb.Next() {
static_w.Body.Reset()
static_handler.ServeHTTP(static_w,static_req)
}
})
}*/
func BenchmarkTopicAdminRouteParallel(b *testing.B) {
b.ReportAllocs()
if !gloinited {
gloinit()
}
b.RunParallel(func(pb *testing.PB) {
admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year}
// TO-DO: Stop hard-coding this value. Seriously.
admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year}
topic_w := httptest.NewRecorder()
topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil))
topic_req_admin := topic_req
topic_req_admin.AddCookie(&admin_uid_cookie)
topic_req_admin.AddCookie(&admin_session_cookie)
topic_handler := http.HandlerFunc(route_topic_id)
for pb.Next() {
//topic_w.Body.Reset()
topic_handler.ServeHTTP(topic_w,topic_req_admin)
}
})
}
func BenchmarkTopicGuestRouteParallel(b *testing.B) {
b.ReportAllocs()
if !gloinited {
gloinit()
}
b.RunParallel(func(pb *testing.PB) {
topic_w := httptest.NewRecorder()
topic_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil))
topic_handler := http.HandlerFunc(route_topic_id)
for pb.Next() {
topic_w.Body.Reset()
topic_handler.ServeHTTP(topic_w,topic_req)
}
})
}
func BenchmarkForumsAdminRouteParallel(b *testing.B) {
b.ReportAllocs()
if !gloinited {
gloinit()
}
b.RunParallel(func(pb *testing.PB) {
admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year}
// TO-DO: Stop hard-coding this value. Seriously.
admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year}
forums_w := httptest.NewRecorder()
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
forums_req_admin := forums_req
forums_req_admin.AddCookie(&admin_uid_cookie)
forums_req_admin.AddCookie(&admin_session_cookie)
forums_handler := http.HandlerFunc(route_forums)
for pb.Next() {
forums_w.Body.Reset()
forums_handler.ServeHTTP(forums_w,forums_req_admin)
}
})
}
func BenchmarkForumsAdminRouteParallelProf(b *testing.B) {
b.ReportAllocs()
if !gloinited {
gloinit()
}
b.RunParallel(func(pb *testing.PB) {
admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year}
// TO-DO: Stop hard-coding this value. Seriously.
admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year}
forums_w := httptest.NewRecorder()
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
forums_req_admin := forums_req
forums_req_admin.AddCookie(&admin_uid_cookie)
forums_req_admin.AddCookie(&admin_session_cookie)
forums_handler := http.HandlerFunc(route_forums)
f, err := os.Create("cpu_forums_admin_parallel.prof")
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
for pb.Next() {
forums_w.Body.Reset()
forums_handler.ServeHTTP(forums_w,forums_req_admin)
}
pprof.StopCPUProfile()
})
}
func BenchmarkForumsGuestRouteParallel(b *testing.B) {
b.ReportAllocs()
if !gloinited {
gloinit()
}
b.RunParallel(func(pb *testing.PB) {
forums_w := httptest.NewRecorder()
forums_req := httptest.NewRequest("get","/forums/",bytes.NewReader(nil))
forums_handler := http.HandlerFunc(route_forums)
for pb.Next() {
forums_w.Body.Reset()
forums_handler.ServeHTTP(forums_w,forums_req)
}
})
}
func BenchmarkRoutesSerial(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year} admin_uid_cookie := http.Cookie{Name: "uid",Value: "1",Path: "/",MaxAge: year}
// TO-DO: Stop hard-coding this value. Seriously. // TO-DO: Stop hard-coding this value. Seriously.
admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year} admin_session_cookie := http.Cookie{Name: "session",Value: "TKBh5Z-qEQhWDBnV6_XVmOhKAowMYPhHeRlrQjjbNc0QRrRiglvWOYFDc1AaMXQIywvEsyA2AOBRYUrZ5kvnGhThY1GhOW6FSJADnRWm_bI=",Path: "/",MaxAge: year}
if plugins_inited {
b.Log("Plugins have already been initialised, they can't be deinitialised so these tests will run with plugins on")
}
static_w := httptest.NewRecorder()
static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil))
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
@ -139,32 +353,31 @@ func BenchmarkRoute(b *testing.B) {
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)
static_w := httptest.NewRecorder() if !gloinited {
static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil)) gloinit()
static_handler := http.HandlerFunc(route_static) }
debug = false /*f, err := os.Create("routes_bench_cpu.prof")
nogrouplog = true if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)*/
//defer pprof.StopCPUProfile()
//pprof.StopCPUProfile()
// init_database is a little noisy for a benchmark b.Run("static_recorder", func(b *testing.B) {
discard := ioutil.Discard
log.SetOutput(discard)
var err error
init_database(err)
external_sites["YT"] = "https://www.youtube.com/"
hooks["trow_assign"] = nil
hooks["rrow_assign"] = nil
init_plugins()
b.Run("static_files", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
static_w.Body.Reset() static_w.Body.Reset()
static_handler.ServeHTTP(static_w,static_req) static_handler.ServeHTTP(static_w,static_req)
} }
}) })
b.Run("topic_admin", func(b *testing.B) { b.Run("topic_admin_recorder", func(b *testing.B) {
//f, err := os.Create("routes_bench_topic_cpu.prof")
//if err != nil {
// log.Fatal(err)
//}
//pprof.StartCPUProfile(f)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
//topic_w.Code = 200 //topic_w.Code = 200
topic_w.Body.Reset() topic_w.Body.Reset()
@ -174,55 +387,258 @@ func BenchmarkRoute(b *testing.B) {
// panic("HTTP Error!") // panic("HTTP Error!")
//} //}
} }
//pprof.StopCPUProfile()
}) })
b.Run("topic_guest", func(b *testing.B) { b.Run("topic_guest_recorder", func(b *testing.B) {
f, err := os.Create("routes_bench_topic_cpu_2.prof")
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
//topic_w.Code = 200 //topic_w.Code = 200
topic_w.Body.Reset() topic_w.Body.Reset()
topic_handler.ServeHTTP(topic_w,topic_req) topic_handler.ServeHTTP(topic_w,topic_req)
} }
pprof.StopCPUProfile()
}) })
b.Run("topics_admin", func(b *testing.B) { b.Run("topics_admin_recorder", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
//topics_w.Code = 200 //topics_w.Code = 200
topics_w.Body.Reset() topics_w.Body.Reset()
topics_handler.ServeHTTP(topics_w,topics_req_admin) topics_handler.ServeHTTP(topics_w,topics_req_admin)
} }
}) })
b.Run("topics_guest", func(b *testing.B) { b.Run("topics_guest_recorder", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
//topics_w.Code = 200 //topics_w.Code = 200
topics_w.Body.Reset() topics_w.Body.Reset()
topics_handler.ServeHTTP(topics_w,topics_req) topics_handler.ServeHTTP(topics_w,topics_req)
} }
}) })
b.Run("forum_admin", func(b *testing.B) { b.Run("forum_admin_recorder", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
//forum_w.Code = 200 //forum_w.Code = 200
forum_w.Body.Reset() forum_w.Body.Reset()
forum_handler.ServeHTTP(forum_w,forum_req_admin) forum_handler.ServeHTTP(forum_w,forum_req_admin)
} }
}) })
b.Run("forum_guest", func(b *testing.B) { b.Run("forum_guest_recorder", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
//forum_w.Code = 200 //forum_w.Code = 200
forum_w.Body.Reset() forum_w.Body.Reset()
forum_handler.ServeHTTP(forum_w,forum_req) forum_handler.ServeHTTP(forum_w,forum_req)
} }
}) })
b.Run("forums_admin", func(b *testing.B) { b.Run("forums_admin_recorder", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
//forums_w.Code = 200 //forums_w.Code = 200
forums_w.Body.Reset() forums_w.Body.Reset()
forums_handler.ServeHTTP(forums_w,forums_req_admin) forums_handler.ServeHTTP(forums_w,forums_req_admin)
} }
}) })
b.Run("forums_guest", func(b *testing.B) { b.Run("forums_guest_recorder", func(b *testing.B) {
/*f, err := os.Create("routes_bench_forums_cpu_2.prof")
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)*/
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
//forums_w.Code = 200 //forums_w.Code = 200
forums_w.Body.Reset() forums_w.Body.Reset()
forums_handler.ServeHTTP(forums_w,forums_req) forums_handler.ServeHTTP(forums_w,forums_req)
} }
//pprof.StopCPUProfile()
})
if !plugins_inited {
init_plugins()
}
b.Run("topic_admin_recorder_with_plugins", func(b *testing.B) {
/*f, err := os.Create("routes_bench_topic_cpu.prof")
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)*/
for i := 0; i < b.N; i++ {
//topic_w.Code = 200
topic_w.Body.Reset()
topic_handler.ServeHTTP(topic_w,topic_req_admin)
//if topic_w.Code != 200 {
// fmt.Println(topic_w.Body)
// panic("HTTP Error!")
//}
}
//pprof.StopCPUProfile()
})
b.Run("topic_guest_recorder_with_plugins", func(b *testing.B) {
/*f, err := os.Create("routes_bench_topic_cpu_2.prof")
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)*/
for i := 0; i < b.N; i++ {
//topic_w.Code = 200
topic_w.Body.Reset()
topic_handler.ServeHTTP(topic_w,topic_req)
}
//pprof.StopCPUProfile()
})
b.Run("topics_admin_recorder_with_plugins", func(b *testing.B) {
for i := 0; i < b.N; i++ {
//topics_w.Code = 200
topics_w.Body.Reset()
topics_handler.ServeHTTP(topics_w,topics_req_admin)
}
})
b.Run("topics_guest_recorder_with_plugins", func(b *testing.B) {
for i := 0; i < b.N; i++ {
//topics_w.Code = 200
topics_w.Body.Reset()
topics_handler.ServeHTTP(topics_w,topics_req)
}
})
b.Run("forum_admin_recorder_with_plugins", func(b *testing.B) {
for i := 0; i < b.N; i++ {
//forum_w.Code = 200
forum_w.Body.Reset()
forum_handler.ServeHTTP(forum_w,forum_req_admin)
}
})
b.Run("forum_guest_recorder_with_plugins", func(b *testing.B) {
for i := 0; i < b.N; i++ {
//forum_w.Code = 200
forum_w.Body.Reset()
forum_handler.ServeHTTP(forum_w,forum_req)
}
})
b.Run("forums_admin_recorder_with_plugins", func(b *testing.B) {
for i := 0; i < b.N; i++ {
//forums_w.Code = 200
forums_w.Body.Reset()
forums_handler.ServeHTTP(forums_w,forums_req_admin)
}
})
b.Run("forums_guest_recorder_with_plugins", func(b *testing.B) {
/*f, err := os.Create("routes_bench_forums_cpu_2.prof")
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)*/
for i := 0; i < b.N; i++ {
//forums_w.Code = 200
forums_w.Body.Reset()
forums_handler.ServeHTTP(forums_w,forums_req)
}
//pprof.StopCPUProfile()
})
}
func BenchmarkQueryTopicParallel(b *testing.B) {
b.ReportAllocs()
if !gloinited {
gloinit()
}
b.RunParallel(func(pb *testing.PB) {
topic := TopicUser{Css: no_css_tmpl}
var content string
var is_super_admin bool
var group int
for pb.Next() {
err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, topics.ipaddress from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level, &topic.IpAddress)
if err == sql.ErrNoRows {
log.Fatal("No rows found!")
return
} else if err != nil {
log.Fatal(err)
return
}
}
})
}
func BenchmarkQueryPreparedTopicParallel(b *testing.B) {
b.ReportAllocs()
if !gloinited {
gloinit()
}
b.RunParallel(func(pb *testing.PB) {
topic := TopicUser{Css: no_css_tmpl}
var content string
var is_super_admin bool
var group int
for pb.Next() {
err := get_topic_user_stmt.QueryRow(1).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level, &topic.IpAddress)
if err == sql.ErrNoRows {
log.Fatal("No rows found!")
return
} else if err != nil {
log.Fatal(err)
return
}
}
})
}
func BenchmarkQueriesSerial(b *testing.B) {
b.ReportAllocs()
topic := TopicUser{Css: no_css_tmpl}
var content string
var is_super_admin bool
var group int
b.Run("topic", func(b *testing.B) {
for i := 0; i < b.N; i++ {
err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, topics.ipaddress from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level, &topic.IpAddress)
if err == sql.ErrNoRows {
log.Fatal("No rows found!")
return
} else if err != nil {
log.Fatal(err)
return
}
}
})
b.Run("topic_replies", func(b *testing.B) {
for i := 0; i < b.N; i++ {
rows, err := db.Query("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress from replies left join users ON replies.createdBy = users.uid where tid = ?", 1)
if err != nil {
log.Fatal(err)
return
}
for rows.Next() {}
err = rows.Err()
if err != nil {
log.Fatal(err)
return
}
defer rows.Close()
}
})
replyItem := Reply{Css: no_css_tmpl}
b.Run("topic_replies_scan", func(b *testing.B) {
for i := 0; i < b.N; i++ {
rows, err := db.Query("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress from replies left join users ON replies.createdBy = users.uid where tid = ?", 1)
if err != nil {
log.Fatal(err)
return
}
for rows.Next() {
err := rows.Scan(&replyItem.ID, &replyItem.Content, &replyItem.CreatedBy, &replyItem.CreatedAt, &replyItem.LastEdit, &replyItem.LastEditBy, &replyItem.Avatar, &replyItem.CreatedByName, &is_super_admin, &group, &replyItem.URLPrefix, &replyItem.URLName, &replyItem.Level, &replyItem.IpAddress)
if err != nil {
log.Fatal(err)
return
}
}
err = rows.Err()
if err != nil {
log.Fatal(err)
return
}
defer rows.Close()
}
}) })
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 246 KiB

47
main.go
View File

@ -11,6 +11,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"html/template" "html/template"
//"runtime/pprof"
) )
const hour int = 60 * 60 const hour int = 60 * 60
@ -41,15 +42,14 @@ var template_profile_handle func(ProfilePage,io.Writer) = nil
func compile_templates() { func compile_templates() {
var c CTemplateSet var c CTemplateSet
user := User{62,"","compiler@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0} user := User{62,"","compiler@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"0.0.0.0.0"}
var noticeList map[int]string = make(map[int]string) noticeList := []string{"test"}
noticeList[0] = "test"
log.Print("Compiling the templates") log.Print("Compiling the templates")
topic := TopicUser{1,"Blah",template.HTML("Hey there!"),0,false,false,"",0,"","","",no_css_tmpl,0,"","","","",58} topic := TopicUser{1,"Blah",template.HTML("Hey there!"),0,false,false,"",0,"","","",no_css_tmpl,0,"","","","",58,"127.0.0.1"}
var replyList []Reply var replyList []Reply
replyList = append(replyList, Reply{0,0,"",template.HTML("Yo!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0}) replyList = append(replyList, Reply{0,0,"",template.HTML("Yo!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
var varList map[string]VarItem = make(map[string]VarItem) var varList map[string]VarItem = make(map[string]VarItem)
tpage := TopicPage{"Title",user,noticeList,replyList,topic,false} tpage := TopicPage{"Title",user,noticeList,replyList,topic,false}
@ -71,7 +71,7 @@ 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 topicList []TopicUser var topicList []TopicUser
topicList = append(topicList, TopicUser{1,"Topic Title","The topic content.",1,false,false,"",1,"open","Admin","","",0,"","","","",58}) topicList = append(topicList, TopicUser{1,"Topic Title","The topic content.",1,false,false,"",1,"open","Admin","","",0,"","","","",58,"127.0.0.1"})
topics_page := TopicsPage{"Topic List",user,noticeList,topicList,""} topics_page := TopicsPage{"Topic List",user,noticeList,topicList,""}
topics_tmpl := c.compile_template("topics.html","templates/","TopicsPage", topics_page, varList) topics_tmpl := c.compile_template("topics.html","templates/","TopicsPage", topics_page, varList)
@ -79,12 +79,13 @@ func compile_templates() {
forum_tmpl := c.compile_template("forum.html","templates/","ForumPage", forum_page, varList) forum_tmpl := c.compile_template("forum.html","templates/","ForumPage", forum_page, varList)
log.Print("Writing the templates") log.Print("Writing the templates")
write_template("topic", topic_id_tmpl) go write_template("topic", topic_id_tmpl)
write_template("topic_alt", topic_id_alt_tmpl) go write_template("topic_alt", topic_id_alt_tmpl)
write_template("profile", profile_tmpl) go write_template("profile", profile_tmpl)
write_template("forums", forums_tmpl) go write_template("forums", forums_tmpl)
write_template("topics", topics_tmpl) go write_template("topics", topics_tmpl)
write_template("forum", forum_tmpl) go write_template("forum", forum_tmpl)
go write_file("./template_list.go", "package main\n\n" + c.FragOut)
} }
func write_template(name string, content string) { func write_template(name string, content string) {
@ -92,10 +93,24 @@ func write_template(name string, content string) {
} }
func main(){ func main(){
//if profiling {
// f, err := os.Create("startup_cpu.prof")
// if err != nil {
// log.Fatal(err)
// }
// pprof.StartCPUProfile(f)
//}
init_themes() init_themes()
var err error var err error
init_database(err) init_database(err)
compile_templates() compile_templates()
db.SetMaxOpenConns(64)
err = init_errors()
if err != nil {
log.Fatal(err)
}
log.Print("Loading the static files.") log.Print("Loading the static files.")
err = filepath.Walk("./public", func(path string, f os.FileInfo, err error) error { err = filepath.Walk("./public", func(path string, f os.FileInfo, err error) error {
@ -122,7 +137,6 @@ func main(){
hooks["trow_assign"] = nil hooks["trow_assign"] = nil
hooks["rrow_assign"] = nil hooks["rrow_assign"] = nil
templates.ParseGlob("pages/*") templates.ParseGlob("pages/*")
init_plugins() init_plugins()
router := NewRouter() router := NewRouter()
@ -199,10 +213,15 @@ func main(){
router.HandleFunc("/panel/users/edit/", route_panel_users_edit) router.HandleFunc("/panel/users/edit/", route_panel_users_edit)
router.HandleFunc("/panel/users/edit/submit/", route_panel_users_edit_submit) router.HandleFunc("/panel/users/edit/submit/", route_panel_users_edit_submit)
router.HandleFunc("/panel/groups/", route_panel_groups) router.HandleFunc("/panel/groups/", route_panel_groups)
//router.HandleFunc("/exit/", route_exit)
router.HandleFunc("/", default_route) router.HandleFunc("/", default_route)
defer db.Close() defer db.Close()
//if profiling {
// pprof.StopCPUProfile()
//}
if !enable_ssl { if !enable_ssl {
if server_port == "" { if server_port == "" {
server_port = "80" server_port = "80"

View File

@ -383,7 +383,7 @@ func route_ban(w http.ResponseWriter, r *http.Request) {
confirm_msg := "Are you sure you want to ban '" + uname + "'?" confirm_msg := "Are you sure you want to ban '" + uname + "'?"
yousure := AreYouSure{"/users/ban/submit/" + strconv.Itoa(uid),confirm_msg} yousure := AreYouSure{"/users/ban/submit/" + strconv.Itoa(uid),confirm_msg}
pi := Page{"Ban User","ban-user",user,noticeList,tList,yousure} pi := Page{"Ban User",user,noticeList,tList,yousure}
templates.ExecuteTemplate(w,"areyousure.html", pi) templates.ExecuteTemplate(w,"areyousure.html", pi)
} }
@ -550,7 +550,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
return return
} }
pi := Page{"Control Panel Dashboard","panel",user,noticeList,tList,0} pi := Page{"Control Panel Dashboard",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"panel-dashboard.html", pi) templates.ExecuteTemplate(w,"panel-dashboard.html", pi)
} }
@ -571,7 +571,7 @@ func route_panel_forums(w http.ResponseWriter, r *http.Request){
} }
} }
pi := Page{"Forum Manager","panel-forums",user,noticeList,forumList,0} pi := Page{"Forum Manager",user,noticeList,forumList,0}
templates.ExecuteTemplate(w,"panel-forums.html", pi) templates.ExecuteTemplate(w,"panel-forums.html", pi)
} }
@ -641,7 +641,7 @@ func route_panel_forums_delete(w http.ResponseWriter, r *http.Request){
confirm_msg := "Are you sure you want to delete the '" + forums[fid].Name + "' forum?" confirm_msg := "Are you sure you want to delete the '" + forums[fid].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","panel-forums-delete",user,noticeList,tList,yousure} pi := Page{"Delete Forum",user,noticeList,tList,yousure}
templates.ExecuteTemplate(w,"areyousure.html", pi) templates.ExecuteTemplate(w,"areyousure.html", pi)
} }
@ -779,7 +779,7 @@ func route_panel_settings(w http.ResponseWriter, r *http.Request){
return return
} }
pi := Page{"Setting Manager","panel-settings",user, noticeList,tList,settingList} pi := Page{"Setting Manager",user, noticeList,tList,settingList}
templates.ExecuteTemplate(w,"panel-settings.html", pi) templates.ExecuteTemplate(w,"panel-settings.html", pi)
} }
@ -829,7 +829,7 @@ func route_panel_setting(w http.ResponseWriter, r *http.Request){
} }
} }
pi := Page{"Edit Setting","panel-setting",user,noticeList,itemList,setting} pi := Page{"Edit Setting",user,noticeList,itemList,setting}
templates.ExecuteTemplate(w,"panel-setting.html", pi) templates.ExecuteTemplate(w,"panel-setting.html", pi)
} }
@ -904,7 +904,7 @@ func route_panel_plugins(w http.ResponseWriter, r *http.Request){
pluginList = append(pluginList, plugin) pluginList = append(pluginList, plugin)
} }
pi := Page{"Plugin Manager","panel-plugins",user,noticeList,pluginList,0} pi := Page{"Plugin Manager",user,noticeList,pluginList,0}
templates.ExecuteTemplate(w,"panel-plugins.html", pi) templates.ExecuteTemplate(w,"panel-plugins.html", pi)
} }
@ -1075,7 +1075,7 @@ func route_panel_users(w http.ResponseWriter, r *http.Request){
return return
} }
pi := Page{"User Manager","panel-users",user,noticeList,userList,0} pi := Page{"User Manager",user,noticeList,userList,0}
err = templates.ExecuteTemplate(w,"panel-users.html", pi) err = templates.ExecuteTemplate(w,"panel-users.html", pi)
if err != nil { if err != nil {
InternalError(err, w, r, user) InternalError(err, w, r, user)
@ -1129,7 +1129,7 @@ func route_panel_users_edit(w http.ResponseWriter, r *http.Request){
groupList = append(groupList, group) groupList = append(groupList, group)
} }
pi := Page{"User Editor","panel-user-edit",user,noticeList,groupList,targetUser} pi := Page{"User Editor",user,noticeList,groupList,targetUser}
err = templates.ExecuteTemplate(w,"panel-user-edit.html", pi) err = templates.ExecuteTemplate(w,"panel-user-edit.html", pi)
if err != nil { if err != nil {
InternalError(err, w, r, user) InternalError(err, w, r, user)
@ -1246,7 +1246,7 @@ func route_panel_groups(w http.ResponseWriter, r *http.Request){
groupList = append(groupList, group) groupList = append(groupList, group)
} }
pi := Page{"Group Manager","panel-groups",user,noticeList,groupList,0} pi := Page{"Group Manager",user,noticeList,groupList,0}
templates.ExecuteTemplate(w,"panel-groups.html", pi) templates.ExecuteTemplate(w,"panel-groups.html", pi)
} }
@ -1265,7 +1265,7 @@ func route_panel_themes(w http.ResponseWriter, r *http.Request){
themeList = append(themeList, theme) themeList = append(themeList, theme)
} }
pi := Page{"Theme Manager","panel-themes",user,noticeList,themeList,0} pi := Page{"Theme Manager",user,noticeList,themeList,0}
err := templates.ExecuteTemplate(w,"panel-themes.html", pi) err := templates.ExecuteTemplate(w,"panel-themes.html", pi)
if err != nil { if err != nil {
log.Print(err) log.Print(err)

View File

@ -10,6 +10,9 @@ import "encoding/json"
var db *sql.DB var db *sql.DB
var get_session_stmt *sql.Stmt var get_session_stmt *sql.Stmt
var get_topic_list_stmt *sql.Stmt var get_topic_list_stmt *sql.Stmt
var get_topic_user_stmt *sql.Stmt
var get_topic_replies_stmt *sql.Stmt
var get_forum_topics_stmt *sql.Stmt
var create_topic_stmt *sql.Stmt var create_topic_stmt *sql.Stmt
var create_report_stmt *sql.Stmt var create_report_stmt *sql.Stmt
var create_reply_stmt *sql.Stmt var create_reply_stmt *sql.Stmt
@ -20,6 +23,7 @@ var delete_reply_stmt *sql.Stmt
var delete_topic_stmt *sql.Stmt var delete_topic_stmt *sql.Stmt
var stick_topic_stmt *sql.Stmt var stick_topic_stmt *sql.Stmt
var unstick_topic_stmt *sql.Stmt var unstick_topic_stmt *sql.Stmt
var update_last_ip_stmt *sql.Stmt
var login_stmt *sql.Stmt var login_stmt *sql.Stmt
var update_session_stmt *sql.Stmt var update_session_stmt *sql.Stmt
var logout_stmt *sql.Stmt var logout_stmt *sql.Stmt
@ -70,7 +74,7 @@ func init_database(err error) {
} }
log.Print("Preparing get_session statement.") log.Print("Preparing get_session statement.")
get_session_stmt, err = db.Prepare("select `uid`, `name`, `group`, `is_super_admin`, `session`, `email`, `avatar`, `message`, `url_prefix`, `url_name`, `level`, `score` FROM `users` where `uid` = ? AND `session` = ? AND `session` <> ''") get_session_stmt, err = db.Prepare("select `uid`,`name`,`group`,`is_super_admin`,`session`,`email`,`avatar`,`message`,`url_prefix`,`url_name`,`level`,`score`,`last_ip` from `users` where `uid` = ? and `session` = ? AND `session` <> ''")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -81,8 +85,26 @@ func init_database(err error) {
log.Fatal(err) log.Fatal(err)
} }
log.Print("Preparing get_topic_user statement.")
get_topic_user_stmt, err = db.Prepare("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, topics.ipaddress from topics left join users ON topics.createdBy = users.uid where tid = ?")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing get_topic_replies statement.")
get_topic_replies_stmt, err = db.Prepare("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress from replies left join users ON replies.createdBy = users.uid where tid = ?")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing get_forum_topics statement.")
get_forum_topics_stmt, err = db.Prepare("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid WHERE topics.parentID = ? order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing create_topic statement.") log.Print("Preparing create_topic statement.")
create_topic_stmt, err = db.Prepare("insert into topics(title,content,parsed_content,createdAt,createdBy) VALUES(?,?,?,NOW(),?)") create_topic_stmt, err = db.Prepare("insert into topics(title,content,parsed_content,createdAt,ipaddress,createdBy) VALUES(?,?,?,NOW(),?,?)")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -94,7 +116,7 @@ func init_database(err error) {
} }
log.Print("Preparing create_reply statement.") log.Print("Preparing create_reply statement.")
create_reply_stmt, err = db.Prepare("INSERT INTO replies(tid,content,parsed_content,createdAt,createdBy) VALUES(?,?,?,NOW(),?)") create_reply_stmt, err = db.Prepare("INSERT INTO replies(tid,content,parsed_content,createdAt,ipaddress,createdBy) VALUES(?,?,?,NOW(),?,?)")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -141,6 +163,12 @@ func init_database(err error) {
log.Fatal(err) log.Fatal(err)
} }
log.Print("Preparing update_last_ip statement.")
update_last_ip_stmt, err = db.Prepare("UPDATE users SET last_ip = ? WHERE uid = ?")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing login statement.") log.Print("Preparing login statement.")
login_stmt, err = db.Prepare("SELECT `uid`, `name`, `password`, `salt` FROM `users` WHERE `name` = ?") login_stmt, err = db.Prepare("SELECT `uid`, `name`, `password`, `salt` FROM `users` WHERE `name` = ?")
if err != nil { if err != nil {

View File

@ -5,9 +5,8 @@ import "regexp"
type Page struct type Page struct
{ {
Title string Title string
Name string // Deprecated. Marked for removal.
CurrentUser User CurrentUser User
NoticeList map[int]string NoticeList []string
ItemList []interface{} ItemList []interface{}
Something interface{} Something interface{}
} }
@ -16,7 +15,7 @@ type TopicPage struct
{ {
Title string Title string
CurrentUser User CurrentUser User
NoticeList map[int]string NoticeList []string
ItemList []Reply ItemList []Reply
Topic TopicUser Topic TopicUser
ExtData interface{} ExtData interface{}
@ -26,7 +25,7 @@ type TopicsPage struct
{ {
Title string Title string
CurrentUser User CurrentUser User
NoticeList map[int]string NoticeList []string
ItemList []TopicUser ItemList []TopicUser
ExtData interface{} ExtData interface{}
} }
@ -35,7 +34,7 @@ type ForumPage struct
{ {
Title string Title string
CurrentUser User CurrentUser User
NoticeList map[int]string NoticeList []string
ItemList []TopicUser ItemList []TopicUser
ExtData interface{} ExtData interface{}
} }
@ -44,7 +43,7 @@ type ForumsPage struct
{ {
Title string Title string
CurrentUser User CurrentUser User
NoticeList map[int]string NoticeList []string
ItemList []Forum ItemList []Forum
ExtData interface{} ExtData interface{}
} }
@ -53,7 +52,7 @@ type ProfilePage struct
{ {
Title string Title string
CurrentUser User CurrentUser User
NoticeList map[int]string NoticeList []string
ItemList []Reply ItemList []Reply
ProfileOwner User ProfileOwner User
ExtData interface{} ExtData interface{}

View File

@ -3,9 +3,15 @@ package main
//import "fmt" //import "fmt"
import "bytes" import "bytes"
//import "strings" //import "strings"
import "strconv"
import "regexp" import "regexp"
import "time"
import "math/rand"
var random *rand.Rand
var bbcode_invalid_url []byte var bbcode_invalid_url []byte
var bbcode_invalid_number []byte
var bbcode_missing_tag []byte
var bbcode_url_open []byte var bbcode_url_open []byte
var bbcode_url_open2 []byte var bbcode_url_open2 []byte
var bbcode_url_close []byte var bbcode_url_close []byte
@ -25,6 +31,8 @@ func init_bbcode() {
plugins["bbcode"].AddHook("parse_assign", bbcode_full_parse) plugins["bbcode"].AddHook("parse_assign", bbcode_full_parse)
bbcode_invalid_url = []byte("<span style='color: red;'>[Invalid URL]</span>") bbcode_invalid_url = []byte("<span style='color: red;'>[Invalid URL]</span>")
bbcode_invalid_number = []byte("<span style='color: red;'>[Invalid Number]</span>")
bbcode_missing_tag = []byte("<span style='color: red;'>[Missing Tag]</span>")
bbcode_url_open = []byte("<a href='") bbcode_url_open = []byte("<a href='")
bbcode_url_open2 = []byte("'>") bbcode_url_open2 = []byte("'>")
bbcode_url_close = []byte("</a>") bbcode_url_close = []byte("</a>")
@ -36,6 +44,8 @@ func init_bbcode() {
urlpattern := `(http|https|ftp|mailto*)(:??)\/\/([\.a-zA-Z\/]+)` urlpattern := `(http|https|ftp|mailto*)(:??)\/\/([\.a-zA-Z\/]+)`
bbcode_url = regexp.MustCompile(`\[url\]` + urlpattern + `\[/url\]`) bbcode_url = regexp.MustCompile(`\[url\]` + urlpattern + `\[/url\]`)
bbcode_url_label = regexp.MustCompile(`(?s)\[url=` + urlpattern + `\](.*)\[/url\]`) bbcode_url_label = regexp.MustCompile(`(?s)\[url=` + urlpattern + `\](.*)\[/url\]`)
random = rand.New(rand.NewSource(time.Now().UnixNano()))
} }
func deactivate_bbcode() { func deactivate_bbcode() {
@ -62,7 +72,7 @@ func bbcode_simple_parse(data interface{}) interface{} {
has_b := false has_b := false
has_i := false has_i := false
has_s := false has_s := false
for i := 0; i < len(msgbytes); i++ { for i := 0; (i + 2) < len(msgbytes); i++ {
if msgbytes[i] == '[' && msgbytes[i + 2] == ']' { if msgbytes[i] == '[' && msgbytes[i + 2] == ']' {
if msgbytes[i + 1] == 'b' { if msgbytes[i + 1] == 'b' {
msgbytes[i] = '<' msgbytes[i] = '<'
@ -102,7 +112,7 @@ func bbcode_parse_without_code(data interface{}) interface{} {
has_i := false has_i := false
has_s := false has_s := false
complex_bbc := false complex_bbc := false
for i := 0; i < len(msgbytes); i++ { for i := 0; (i + 2) < len(msgbytes); i++ {
if msgbytes[i] == '[' { if msgbytes[i] == '[' {
if msgbytes[i + 2] != ']' { if msgbytes[i + 2] != ']' {
if msgbytes[i + 1] == '/' { if msgbytes[i + 1] == '/' {
@ -177,7 +187,7 @@ func bbcode_full_parse(data interface{}) interface{} {
has_s := false has_s := false
has_c := false has_c := false
complex_bbc := false complex_bbc := false
for i := 0; i < len(msgbytes); i++ { for i := 0; (i + 2) < len(msgbytes); i++ {
if msgbytes[i] == '[' { if msgbytes[i] == '[' {
if msgbytes[i + 2] != ']' { if msgbytes[i + 2] != ']' {
if msgbytes[i + 1] == '/' { if msgbytes[i + 1] == '/' {
@ -249,20 +259,21 @@ func bbcode_full_parse(data interface{}) interface{} {
var start int var start int
var lastTag int var lastTag int
outbytes := make([]byte, len(msgbytes)) outbytes := make([]byte, len(msgbytes))
//fmt.Println(string(msgbytes))
for i := 0; i < len(msgbytes); i++ { for i := 0; i < len(msgbytes); i++ {
MainLoop: MainLoop:
if msgbytes[i] == '[' { if msgbytes[i] == '[' {
OuterComplex: OuterComplex:
if msgbytes[i + 1] == 'u' { if msgbytes[i + 1] == 'u' {
if msgbytes[i + 2] == 'r' && msgbytes[i + 3] == 'l' && msgbytes[i + 4] == ']' { if msgbytes[i+2] == 'r' && msgbytes[i+3] == 'l' && msgbytes[i+4] == ']' {
outbytes = append(outbytes, msgbytes[lastTag:i]...) outbytes = append(outbytes, msgbytes[lastTag:i]...)
start = i + 5 start = i + 5
i = start i = start
if msgbytes[i] == 'h' { if msgbytes[i] == 'h' {
if msgbytes[i + 1] == 't' && msgbytes[i + 2] == 't' && msgbytes[i + 3] == 'p' { if msgbytes[i+1] == 't' && msgbytes[i+2] == 't' && msgbytes[i+3] == 'p' {
if bytes.Equal(msgbytes[i + 4:i + 7],[]byte("s://")) { if bytes.Equal(msgbytes[i + 4:i + 7],[]byte("s://")) {
i += 7 i += 7
} else if msgbytes[i + 4] == ':' && msgbytes[i + 5] == '/' && msgbytes[i + 6] == '/' { } else if msgbytes[i+4] == ':' && msgbytes[i+5] == '/' && msgbytes[i+6] == '/' {
i += 6 i += 6
} else { } else {
outbytes = append(outbytes, bbcode_invalid_url...) outbytes = append(outbytes, bbcode_invalid_url...)
@ -270,16 +281,17 @@ func bbcode_full_parse(data interface{}) interface{} {
} }
} }
} else if msgbytes[i] == 'f' { } else if msgbytes[i] == 'f' {
if bytes.Equal(msgbytes[i + 1:i + 5],[]byte("tp://")) { if bytes.Equal(msgbytes[i+1:i+5],[]byte("tp://")) {
i += 5 i += 5
} }
} }
for ;; i++ { for ;; i++ {
if msgbytes[i] == '[' { if msgbytes[i] == '[' {
if !bytes.Equal(msgbytes[i + 1:i + 6],[]byte("/url]")) { if !bytes.Equal(msgbytes[i+1:i+6],[]byte("/url]")) {
//log.Print("Not the URL closing tag!") //log.Print("Not the URL closing tag!")
//fmt.Println(msgbytes[i + 1:i + 6]) //fmt.Println(msgbytes[i + 1:i + 6])
outbytes = append(outbytes, bbcode_missing_tag...)
goto OuterComplex goto OuterComplex
} }
break break
@ -288,6 +300,9 @@ func bbcode_full_parse(data interface{}) interface{} {
//log.Print("Weird character") //log.Print("Weird character")
//fmt.Println(msgbytes[i]) //fmt.Println(msgbytes[i])
goto MainLoop goto MainLoop
} else if (len(msgbytes) - 1) < (i + 6) {
outbytes = append(outbytes, bbcode_missing_tag...)
goto OuterComplex
} }
} }
outbytes = append(outbytes, bbcode_url_open...) outbytes = append(outbytes, bbcode_url_open...)
@ -298,9 +313,41 @@ func bbcode_full_parse(data interface{}) interface{} {
i += 6 i += 6
lastTag = i lastTag = i
} }
} else if msgbytes[i + 1] == 'r' {
if bytes.Equal(msgbytes[i+2:i+6],[]byte("and]")) {
outbytes = append(outbytes, msgbytes[lastTag:i]...)
start = i + 6
i = start
for ;; i++ {
if msgbytes[i] == '[' {
if !bytes.Equal(msgbytes[i+1:i+7],[]byte("/rand]")) {
outbytes = append(outbytes, bbcode_missing_tag...)
goto OuterComplex
}
break
} else if (len(msgbytes) - 1) < (i + 7) {
outbytes = append(outbytes, bbcode_missing_tag...)
goto OuterComplex
}
}
number, err := strconv.ParseInt(string(msgbytes[start:i]),10,64)
if err != nil {
outbytes = append(outbytes, bbcode_invalid_number...)
goto MainLoop
}
dat := []byte(strconv.FormatInt((random.Int63n(number)),10))
outbytes = append(outbytes, dat...)
//log.Print("Outputted the random number")
i += 6
lastTag = i
}
} }
} }
} }
//fmt.Println(outbytes)
//fmt.Println(string(outbytes))
if len(outbytes) != 0 { if len(outbytes) != 0 {
return string(outbytes) return string(outbytes)
} }
@ -313,4 +360,4 @@ func bbcode_full_parse(data interface{}) interface{} {
msg = string(msgbytes) msg = string(msgbytes)
} }
return msg return msg
} }

View File

@ -15,7 +15,6 @@ $(document).ready(function(){
$(".open_edit").click(function(event){ $(".open_edit").click(function(event){
console.log("Clicked on edit"); console.log("Clicked on edit");
event.preventDefault(); event.preventDefault();
$(".hide_on_edit").hide(); $(".hide_on_edit").hide();
$(".show_on_edit").show(); $(".show_on_edit").show();
}); });
@ -109,4 +108,17 @@ $(document).ready(function(){
}); });
}); });
}); });
$(this).find(".ip_item").each(function(){
var ip = $(this).text();
//var ip_width = $(this).width();
console.log("IP: " + ip);
if(ip.length > 10){
$(this).html("Show IP");
$(this).click(function(event){
event.preventDefault();
$(this).text(ip);/*.animate({width: ip.width},{duration: 1000, easing: 'easeOutBounce'});*/
});
}
});
}); });

View File

@ -21,4 +21,5 @@ type Reply struct
URLPrefix string URLPrefix string
URLName string URLName string
Level int Level int
IpAddress string
} }

View File

@ -43,7 +43,7 @@ func (router *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if req.URL.Path[len(req.URL.Path) - 1] == '/' { if req.URL.Path[len(req.URL.Path) - 1] == '/' {
w.WriteHeader(404) w.WriteHeader(404)
w.Write([]byte("")) w.Write(error_notfound)
return return
} }
@ -61,6 +61,6 @@ func (router *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
} }
w.WriteHeader(404) w.WriteHeader(404)
w.Write([]byte("")) w.Write(error_notfound)
return return
} }

178
routes.go
View File

@ -10,6 +10,7 @@ import "strings"
import "time" import "time"
import "io" import "io"
import "os" import "os"
import "net"
import "net/http" import "net/http"
import "html" import "html"
import "html/template" import "html/template"
@ -19,7 +20,7 @@ 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 map[int]string var nList []string
// GET functions // GET functions
func route_static(w http.ResponseWriter, r *http.Request){ func route_static(w http.ResponseWriter, r *http.Request){
@ -47,6 +48,11 @@ func route_static(w http.ResponseWriter, r *http.Request){
//io.CopyN(w, bytes.NewReader(file.Data), static_files[r.URL.Path].Length) //io.CopyN(w, bytes.NewReader(file.Data), static_files[r.URL.Path].Length)
} }
/*func route_exit(w http.ResponseWriter, r *http.Request){
db.Close()
os.Exit(0)
}*/
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)
} }
@ -56,8 +62,7 @@ func route_overview(w http.ResponseWriter, r *http.Request){
if !ok { if !ok {
return return
} }
pi := Page{"Overview",user,noticeList,tList,nil}
pi := Page{"Overview","overview",user,noticeList,tList,0}
err := templates.ExecuteTemplate(w,"overview.html", pi) err := templates.ExecuteTemplate(w,"overview.html", pi)
if err != nil { if err != nil {
InternalError(err, w, r, user) InternalError(err, w, r, user)
@ -73,8 +78,9 @@ func route_custom_page(w http.ResponseWriter, r *http.Request){
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,user) NotFound(w,r,user)
return
} }
pi := Page{"Page","page",user,noticeList,tList,0} pi := Page{"Page",user,noticeList,tList,0}
err := templates.ExecuteTemplate(w,"page_" + name,pi) err := templates.ExecuteTemplate(w,"page_" + name,pi)
if err != nil { if err != nil {
InternalError(err, w, r, user) InternalError(err, w, r, user)
@ -98,7 +104,6 @@ func route_topics(w http.ResponseWriter, r *http.Request){
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
} }
defer rows.Close()
topicItem := TopicUser{ID: 0,} topicItem := TopicUser{ID: 0,}
for rows.Next() { for rows.Next() {
@ -126,8 +131,9 @@ func route_topics(w http.ResponseWriter, r *http.Request){
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
} }
rows.Close()
pi := TopicsPage{"Topic List",user,noticeList,topicList,0} pi := TopicsPage{"Topic List",user,noticeList,topicList,nil}
if template_topics_handle != nil { if template_topics_handle != nil {
template_topics_handle(pi,w) template_topics_handle(pi,w)
} else { } else {
@ -145,7 +151,6 @@ func route_forum(w http.ResponseWriter, r *http.Request){
} }
var topicList []TopicUser var topicList []TopicUser
fid, err := strconv.Atoi(r.URL.Path[len("/forum/"):]) fid, err := strconv.Atoi(r.URL.Path[len("/forum/"):])
if err != nil { if err != nil {
LocalError("The provided ForumID is not a valid number.",w,r,user) LocalError("The provided ForumID is not a valid number.",w,r,user)
@ -162,12 +167,11 @@ func route_forum(w http.ResponseWriter, r *http.Request){
return return
} }
rows, err := db.Query("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid WHERE topics.parentID = ? order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC", fid) rows, err := get_forum_topics_stmt.Query(fid)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
} }
defer rows.Close()
topicItem := TopicUser{ID: 0} topicItem := TopicUser{ID: 0}
for rows.Next() { for rows.Next() {
@ -195,8 +199,9 @@ func route_forum(w http.ResponseWriter, r *http.Request){
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
} }
rows.Close()
pi := ForumPage{forums[fid].Name,user,noticeList,topicList,0} pi := ForumPage{forums[fid].Name,user,noticeList,topicList,nil}
if template_forum_handle != nil { if template_forum_handle != nil {
template_forum_handle(pi,w) template_forum_handle(pi,w)
} else { } else {
@ -220,13 +225,13 @@ func route_forums(w http.ResponseWriter, r *http.Request){
} }
} }
pi := ForumsPage{"Forum List",user,noticeList,forumList,0} pi := ForumsPage{"Forum List",user,noticeList,forumList,nil}
if template_forums_handle != nil { if template_forums_handle != nil {
template_forums_handle(pi,w) template_forums_handle(pi,w)
} else { } else {
err := templates.ExecuteTemplate(w,"forums.html", pi) err := templates.ExecuteTemplate(w,"forums.html",pi)
if err != nil { if err != nil {
InternalError(err, w, r, user) InternalError(err,w,r,user)
} }
} }
} }
@ -238,25 +243,9 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
} }
var( var(
err error err error
rid int
content string content string
replyContent string
replyCreatedBy int
replyCreatedByName string
replyCreatedAt string
replyLastEdit int
replyLastEditBy int
replyAvatar string
replyCss template.CSS
replyLines int
replyTag string
replyURL string
replyURLPrefix string
replyURLName string
replyLevel int
is_super_admin bool is_super_admin bool
group int group int
replyList []Reply replyList []Reply
) )
@ -274,7 +263,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
} }
// Get the topic.. // Get the topic..
err = db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?", topic.ID).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level) err = get_topic_user_stmt.QueryRow(topic.ID).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level, &topic.IpAddress)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
NotFound(w,r,user) NotFound(w,r,user)
return return
@ -302,11 +291,9 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
topic.Css = staff_css_tmpl topic.Css = staff_css_tmpl
topic.Level = -1 topic.Level = -1
} }
//if groups[group].Tag != "" {
topic.Tag = groups[group].Tag topic.Tag = groups[group].Tag
//} else {
// topic.Tag = ""
//}
if settings["url_tags"] == false { if settings["url_tags"] == false {
topic.URLName = "" topic.URLName = ""
} else { } else {
@ -314,56 +301,54 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
if !ok { if !ok {
topic.URL = topic.URLName topic.URL = topic.URLName
} else { } else {
topic.URL = replyURL + topic.URLName topic.URL = topic.URL + topic.URLName
} }
} }
// Get the replies.. // Get the replies..
rows, err := db.Query("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level from replies left join users ON replies.createdBy = users.uid where tid = ?", topic.ID) rows, err := get_topic_replies_stmt.Query(topic.ID)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
} }
defer rows.Close()
replyItem := Reply{Css: no_css_tmpl}
for rows.Next() { for rows.Next() {
err := rows.Scan(&rid, &replyContent, &replyCreatedBy, &replyCreatedAt, &replyLastEdit, &replyLastEditBy, &replyAvatar, &replyCreatedByName, &is_super_admin, &group, &replyURLPrefix, &replyURLName, &replyLevel) err := rows.Scan(&replyItem.ID, &replyItem.Content, &replyItem.CreatedBy, &replyItem.CreatedAt, &replyItem.LastEdit, &replyItem.LastEditBy, &replyItem.Avatar, &replyItem.CreatedByName, &is_super_admin, &group, &replyItem.URLPrefix, &replyItem.URLName, &replyItem.Level, &replyItem.IpAddress)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
} }
replyLines = strings.Count(replyContent,"\n") replyItem.ParentID = topic.ID
replyItem.ContentHtml = template.HTML(parse_message(replyItem.Content))
replyItem.ContentLines = strings.Count(replyItem.Content,"\n")
if is_super_admin || groups[group].Is_Mod || groups[group].Is_Admin { if is_super_admin || groups[group].Is_Mod || groups[group].Is_Admin {
replyCss = staff_css_tmpl replyItem.Css = staff_css_tmpl
replyLevel = -1 replyItem.Level = -1
} else { } else {
replyCss = no_css_tmpl replyItem.Css = no_css_tmpl
} }
if replyAvatar != "" { if replyItem.Avatar != "" {
if replyAvatar[0] == '.' { if replyItem.Avatar[0] == '.' {
replyAvatar = "/uploads/avatar_" + strconv.Itoa(replyCreatedBy) + replyAvatar replyItem.Avatar = "/uploads/avatar_" + strconv.Itoa(replyItem.CreatedBy) + replyItem.Avatar
} }
} else { } else {
replyAvatar = strings.Replace(noavatar,"{id}",strconv.Itoa(replyCreatedBy),1) replyItem.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(replyItem.CreatedBy),1)
}
//if groups[group].Tag != "" {
replyTag = groups[group].Tag
//} else {
// replyTag = ""
//}
if settings["url_tags"] == false {
replyURLName = ""
} else {
replyURL, ok = external_sites[replyURLPrefix]
if !ok {
replyURL = replyURLName
} else {
replyURL = replyURL + replyURLName
}
} }
replyItem := Reply{rid,topic.ID,replyContent,template.HTML(parse_message(replyContent)),replyCreatedBy,replyCreatedByName,replyCreatedAt,replyLastEdit,replyLastEditBy,replyAvatar,replyCss,replyLines,replyTag,replyURL,replyURLPrefix,replyURLName,replyLevel} replyItem.Tag = groups[group].Tag
if settings["url_tags"] == false {
replyItem.URLName = ""
} else {
replyItem.URL, ok = external_sites[replyItem.URLPrefix]
if !ok {
replyItem.URL = replyItem.URLName
} else {
replyItem.URL = replyItem.URL + replyItem.URLName
}
}
if hooks["rrow_assign"] != nil { if hooks["rrow_assign"] != nil {
replyItem = run_hook("rrow_assign", replyItem).(Reply) replyItem = run_hook("rrow_assign", replyItem).(Reply)
@ -375,8 +360,9 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
} }
rows.Close()
tpage := TopicPage{topic.Title,user,noticeList,replyList,topic,0} tpage := TopicPage{topic.Title,user,noticeList,replyList,topic,nil}
if template_topic_handle != nil { if template_topic_handle != nil {
template_topic_handle(tpage,w) template_topic_handle(tpage,w)
} else { } else {
@ -424,7 +410,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
puser = user puser = user
} else { } else {
// Fetch the user data // Fetch the user data
err = db.QueryRow("SELECT `name`, `group`, `is_super_admin`, `avatar`, `message`, `url_prefix`, `url_name`, `level` FROM `users` WHERE `uid` = ?", puser.ID).Scan(&puser.Name, &puser.Group, &puser.Is_Super_Admin, &puser.Avatar, &puser.Message, &puser.URLPrefix, &puser.URLName, &puser.Level) err = db.QueryRow("select `name`,`group`,`is_super_admin`,`avatar`,`message`,`url_prefix`,`url_name`,`level` from `users` where `uid` = ?", puser.ID).Scan(&puser.Name, &puser.Group, &puser.Is_Super_Admin, &puser.Avatar, &puser.Message, &puser.URLPrefix, &puser.URLName, &puser.Level)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
NotFound(w,r,user) NotFound(w,r,user)
return return
@ -442,11 +428,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
} }
} }
//if groups[puser.Group].Tag != "" { puser.Tag = groups[puser.Group].Tag
puser.Tag = groups[puser.Group].Tag
//} else {
// puser.Tag = ""
//}
if puser.Avatar != "" { if puser.Avatar != "" {
if puser.Avatar[0] == '.' { if puser.Avatar[0] == '.' {
@ -492,7 +474,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
replyTag = "" replyTag = ""
} }
replyList = append(replyList, Reply{rid,puser.ID,replyContent,template.HTML(parse_message(replyContent)),replyCreatedBy,replyCreatedByName,replyCreatedAt,replyLastEdit,replyLastEditBy,replyAvatar,replyCss,replyLines,replyTag,"","","",0}) replyList = append(replyList, Reply{rid,puser.ID,replyContent,template.HTML(parse_message(replyContent)),replyCreatedBy,replyCreatedByName,replyCreatedAt,replyLastEdit,replyLastEditBy,replyAvatar,replyCss,replyLines,replyTag,"","","",0,""})
} }
err = rows.Err() err = rows.Err()
if err != nil { if err != nil {
@ -520,7 +502,7 @@ func route_topic_create(w http.ResponseWriter, r *http.Request){
NoPermissions(w,r,user) NoPermissions(w,r,user)
return return
} }
pi := Page{"Create Topic","create-topic",user,noticeList,tList,0} pi := Page{"Create Topic",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"create-topic.html", pi) templates.ExecuteTemplate(w,"create-topic.html", pi)
} }
@ -542,8 +524,13 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
} }
topic_name := html.EscapeString(r.PostFormValue("topic-name")) topic_name := html.EscapeString(r.PostFormValue("topic-name"))
content := html.EscapeString(preparse_message(r.PostFormValue("topic-content"))) content := html.EscapeString(preparse_message(r.PostFormValue("topic-content")))
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
LocalError("Bad IP",w,r,user)
return
}
res, err := create_topic_stmt.Exec(topic_name,content,parse_message(content),user.ID) res, err := create_topic_stmt.Exec(topic_name,content,parse_message(content),ipaddress,user.ID)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
@ -591,8 +578,13 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
} }
content := preparse_message(html.EscapeString(r.PostFormValue("reply-content"))) content := preparse_message(html.EscapeString(r.PostFormValue("reply-content")))
//log.Print(content) ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
_, err = create_reply_stmt.Exec(tid,content,parse_message(content),user.ID) if err != nil {
LocalError("Bad IP",w,r,user)
return
}
_, err = create_reply_stmt.Exec(tid,content,parse_message(content),ipaddress,user.ID)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
@ -799,7 +791,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
if success != 1 { if success != 1 {
errmsg := "Unable to create the report" errmsg := "Unable to create the report"
pi := Page{"Error","error",user,nList,tList,errmsg} pi := Page{"Error",user,nList,tList,errmsg}
var b bytes.Buffer var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi) templates.ExecuteTemplate(&b,"error.html", pi)
@ -820,7 +812,7 @@ func route_account_own_edit_critical(w http.ResponseWriter, r *http.Request) {
LocalError("You need to login to edit your account.",w,r,user) LocalError("You need to login to edit your account.",w,r,user)
return return
} }
pi := Page{"Edit Password","account-own-edit",user,noticeList,tList,0} pi := Page{"Edit Password",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"account-own-edit.html", pi) templates.ExecuteTemplate(w,"account-own-edit.html", pi)
} }
@ -878,7 +870,7 @@ func route_account_own_edit_critical_submit(w http.ResponseWriter, r *http.Reque
} }
noticeList[len(noticeList)] = "Your password was successfully updated" noticeList[len(noticeList)] = "Your password was successfully updated"
pi := Page{"Edit Password","account-own-edit",user,noticeList,tList,0} pi := Page{"Edit Password",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"account-own-edit.html", pi) templates.ExecuteTemplate(w,"account-own-edit.html", pi)
} }
@ -891,7 +883,7 @@ func route_account_own_edit_avatar(w http.ResponseWriter, r *http.Request) {
LocalError("You need to login to edit your account.",w,r,user) LocalError("You need to login to edit your account.",w,r,user)
return return
} }
pi := Page{"Edit Avatar","account-own-edit-avatar",user,noticeList,tList,0} pi := Page{"Edit Avatar",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"account-own-edit-avatar.html", pi) templates.ExecuteTemplate(w,"account-own-edit-avatar.html", pi)
} }
@ -977,9 +969,9 @@ func route_account_own_edit_avatar_submit(w http.ResponseWriter, r *http.Request
return return
} }
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + "." + ext user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + "." + ext
noticeList[len(noticeList)] = "Your avatar was successfully updated" noticeList = append(noticeList, "Your avatar was successfully updated")
pi := Page{"Edit Avatar","account-own-edit-avatar",user,noticeList,tList,0} pi := Page{"Edit Avatar",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"account-own-edit-avatar.html", pi) templates.ExecuteTemplate(w,"account-own-edit-avatar.html", pi)
} }
@ -993,7 +985,7 @@ func route_account_own_edit_username(w http.ResponseWriter, r *http.Request) {
return return
} }
pi := Page{"Edit Username","account-own-edit-username",user,noticeList,tList,user.Name} pi := Page{"Edit Username",user,noticeList,tList,user.Name}
templates.ExecuteTemplate(w,"account-own-edit-username.html", pi) templates.ExecuteTemplate(w,"account-own-edit-username.html", pi)
} }
@ -1020,8 +1012,8 @@ func route_account_own_edit_username_submit(w http.ResponseWriter, r *http.Reque
} }
user.Name = new_username user.Name = new_username
noticeList[len(noticeList)] = "Your username was successfully updated" noticeList = append(noticeList,"Your username was successfully updated")
pi := Page{"Edit Username","account-own-edit-username",user,noticeList,tList,0} pi := Page{"Edit Username",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"account-own-edit-username.html", pi) templates.ExecuteTemplate(w,"account-own-edit-username.html", pi)
} }
@ -1037,7 +1029,7 @@ func route_account_own_edit_email(w http.ResponseWriter, r *http.Request) {
email := Email{UserID: user.ID} email := Email{UserID: user.ID}
var emailList []interface{} var emailList []interface{}
rows, err := db.Query("SELECT email, validated FROM emails WHERE uid = ?", user.ID) rows, err := db.Query("select email, validated from emails where uid = ?", user.ID)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -1068,9 +1060,9 @@ func route_account_own_edit_email(w http.ResponseWriter, r *http.Request) {
} }
if !enable_emails { if !enable_emails {
noticeList[len(noticeList)] = "The email system has been turned off. All features involving sending emails have been disabled." noticeList = append(noticeList, "The email system has been turned off. All features involving sending emails have been disabled.")
} }
pi := Page{"Email Manager","account-own-edit-email",user,noticeList,emailList,0} pi := Page{"Email Manager",user,noticeList,emailList,0}
templates.ExecuteTemplate(w,"account-own-edit-email.html", pi) templates.ExecuteTemplate(w,"account-own-edit-email.html", pi)
} }
@ -1088,7 +1080,7 @@ func route_account_own_edit_email_token_submit(w http.ResponseWriter, r *http.Re
email := Email{UserID: user.ID} email := Email{UserID: user.ID}
targetEmail := Email{UserID: user.ID} targetEmail := Email{UserID: user.ID}
var emailList []interface{} var emailList []interface{}
rows, err := db.Query("SELECT email, validated, token FROM emails WHERE uid = ?", user.ID) rows, err := db.Query("select email, validated, token from emails where uid = ?", user.ID)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -1138,10 +1130,10 @@ func route_account_own_edit_email_token_submit(w http.ResponseWriter, r *http.Re
} }
if !enable_emails { if !enable_emails {
noticeList[len(noticeList)] = "The email system has been turned off. All features involving sending emails have been disabled." noticeList = append(noticeList,"The email system has been turned off. All features involving sending emails have been disabled.")
} }
noticeList[len(noticeList)] = "Your email was successfully verified" noticeList = append(noticeList,"Your email was successfully verified")
pi := Page{"Email Manager","account-own-edit-email",user,noticeList,emailList,0} pi := Page{"Email Manager",user,noticeList,emailList,0}
templates.ExecuteTemplate(w,"account-own-edit-email.html", pi) templates.ExecuteTemplate(w,"account-own-edit-email.html", pi)
} }
@ -1172,7 +1164,7 @@ func route_login(w http.ResponseWriter, r *http.Request) {
LocalError("You're already logged in.",w,r,user) LocalError("You're already logged in.",w,r,user)
return return
} }
pi := Page{"Login","login",user,noticeList,tList,0} pi := Page{"Login",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"login.html", pi) templates.ExecuteTemplate(w,"login.html", pi)
} }
@ -1262,7 +1254,7 @@ func route_register(w http.ResponseWriter, r *http.Request) {
LocalError("You're already logged in.",w,r,user) LocalError("You're already logged in.",w,r,user)
return return
} }
pi := Page{"Registration","register",user,noticeList,tList,0} pi := Page{"Registration",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"register.html", pi) templates.ExecuteTemplate(w,"register.html", pi)
} }

10
run.bat
View File

@ -1,8 +1,18 @@
@echo off @echo off
echo Generating the dynamic code
go generate
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the executable
go build go build
if %errorlevel% neq 0 ( if %errorlevel% neq 0 (
pause pause
exit /b %errorlevel% exit /b %errorlevel%
) )
echo Running Gosora
gosora.exe gosora.exe
pause pause

View File

@ -1,7 +1,7 @@
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */ /* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main package main
import "strconv"
import "io" import "io"
import "strconv"
func init() { func init() {
template_forum_handle = template_forum template_forum_handle = template_forum
@ -12,93 +12,65 @@ func init() {
} }
func template_forum(tmpl_forum_vars ForumPage, w io.Writer) { func template_forum(tmpl_forum_vars ForumPage, w io.Writer) {
w.Write([]byte(`<!doctype html> w.Write(header_0)
<html lang="en"> w.Write([]byte(tmpl_forum_vars.Title))
<head> w.Write(header_1)
<title>` + tmpl_forum_vars.Title + `</title> w.Write([]byte(tmpl_forum_vars.CurrentUser.Session))
<link href="/static/main.css" rel="stylesheet" type="text/css"> w.Write(header_2)
<script type="text/javascript" src="/static/jquery-1.12.3.min.js"></script> w.Write(menu_0)
<script type="text/javascript">
var session = "` + tmpl_forum_vars.CurrentUser.Session + `";
</script>
<script type="text/javascript" src="/static/global.js"></script>
<meta name="viewport" content="width=device-width,initial-scale = 1.0, maximum-scale=1.0,user-scalable=no" />
</head>
<body>
<div class="container">
<div class="nav">
<div class="move_left">
<div class="move_right">
<ul>
<li class="menu_left menu_overview"><a href="/">Overview</a></li>
<li class="menu_left menu_forums"><a href="/forums/">Forums</a></li>
<li class="menu_left menu_topics"><a href="/">Topics</a></li>
<li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li>
`))
if tmpl_forum_vars.CurrentUser.Loggedin { if tmpl_forum_vars.CurrentUser.Loggedin {
w.Write([]byte(` w.Write(menu_1)
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li> w.Write([]byte(strconv.Itoa(tmpl_forum_vars.CurrentUser.ID)))
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_forum_vars.CurrentUser.ID) + `">Profile</a></li> w.Write(menu_2)
`))
if tmpl_forum_vars.CurrentUser.Is_Super_Mod { if tmpl_forum_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>`)) w.Write(menu_3)
} }
w.Write([]byte(` w.Write(menu_4)
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_forum_vars.CurrentUser.Session + `">Logout</a></li> w.Write([]byte(tmpl_forum_vars.CurrentUser.Session))
`)) w.Write(menu_5)
} else { } else {
w.Write([]byte(` w.Write(menu_6)
<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>
`))
} }
w.Write([]byte(` w.Write(menu_7)
</ul> w.Write(header_3)
</div>
</div>
<div style="clear: both;"></div>
</div>
<div id="back"><div id="main">`))
if len(tmpl_forum_vars.NoticeList) != 0 { if len(tmpl_forum_vars.NoticeList) != 0 {
for _, item := range tmpl_forum_vars.NoticeList { for _, item := range tmpl_forum_vars.NoticeList {
w.Write([]byte(`<div class="alert">` + item + `</div>`)) w.Write(header_4)
w.Write([]byte(item))
w.Write(header_5)
} }
} }
w.Write([]byte(` w.Write(forum_0)
<div class="rowblock"> w.Write([]byte(tmpl_forum_vars.Title))
<div class="rowitem rowhead"><a>` + tmpl_forum_vars.Title + `</a></div> w.Write(forum_1)
</div>
<div class="rowblock">
`))
if len(tmpl_forum_vars.ItemList) != 0 { if len(tmpl_forum_vars.ItemList) != 0 {
for _, item := range tmpl_forum_vars.ItemList { for _, item := range tmpl_forum_vars.ItemList {
w.Write([]byte(`<div class="rowitem passive" style="`)) w.Write(forum_2)
if item.Avatar != "" { if item.Avatar != "" {
w.Write([]byte(`background-image: url(` + item.Avatar + `);background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;`)) w.Write(forum_3)
w.Write([]byte(item.Avatar))
w.Write(forum_4)
} }
if item.Sticky { if item.Sticky {
w.Write([]byte(`background-color: #FFFFCC;`)) w.Write(forum_5)
} else { } else {
if item.Is_Closed { if item.Is_Closed {
w.Write([]byte(`background-color: #eaeaea;`)) w.Write(forum_6)
} }
} }
w.Write([]byte(`"> w.Write(forum_7)
<a href="/topic/` + strconv.Itoa(item.ID) + `">` + item.Title + `</a> `)) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(forum_8)
w.Write([]byte(item.Title))
w.Write(forum_9)
if item.Is_Closed { if item.Is_Closed {
w.Write([]byte(`<span class="username topic_status_e topic_status_closed" title="Status: Closed" style="float: right;">&#x1F512;&#xFE0E</span>`)) w.Write(forum_10)
} }
w.Write([]byte(` w.Write(forum_11)
</div>
`))
} }
} else { } else {
w.Write([]byte(`<div class="rowitem passive">There aren't any topics in this forum yet.</div>`)) w.Write(forum_12)
} }
w.Write([]byte(` w.Write(forum_13)
</div> w.Write(footer_0)
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`))
} }

View File

@ -12,76 +12,52 @@ func init() {
} }
func template_forums(tmpl_forums_vars ForumsPage, w io.Writer) { func template_forums(tmpl_forums_vars ForumsPage, w io.Writer) {
w.Write([]byte(`<!doctype html> w.Write(header_0)
<html lang="en"> w.Write([]byte(tmpl_forums_vars.Title))
<head> w.Write(header_1)
<title>` + tmpl_forums_vars.Title + `</title> w.Write([]byte(tmpl_forums_vars.CurrentUser.Session))
<link href="/static/main.css" rel="stylesheet" type="text/css"> w.Write(header_2)
<script type="text/javascript" src="/static/jquery-1.12.3.min.js"></script> w.Write(menu_0)
<script type="text/javascript">
var session = "` + tmpl_forums_vars.CurrentUser.Session + `";
</script>
<script type="text/javascript" src="/static/global.js"></script>
<meta name="viewport" content="width=device-width,initial-scale = 1.0, maximum-scale=1.0,user-scalable=no" />
</head>
<body>
<div class="container">
<div class="nav">
<div class="move_left">
<div class="move_right">
<ul>
<li class="menu_left menu_overview"><a href="/">Overview</a></li>
<li class="menu_left menu_forums"><a href="/forums/">Forums</a></li>
<li class="menu_left menu_topics"><a href="/">Topics</a></li>
<li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li>
`))
if tmpl_forums_vars.CurrentUser.Loggedin { if tmpl_forums_vars.CurrentUser.Loggedin {
w.Write([]byte(` w.Write(menu_1)
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li> w.Write([]byte(strconv.Itoa(tmpl_forums_vars.CurrentUser.ID)))
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_forums_vars.CurrentUser.ID) + `">Profile</a></li> w.Write(menu_2)
`))
if tmpl_forums_vars.CurrentUser.Is_Super_Mod { if tmpl_forums_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>`)) w.Write(menu_3)
} }
w.Write([]byte(` w.Write(menu_4)
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_forums_vars.CurrentUser.Session + `">Logout</a></li> w.Write([]byte(tmpl_forums_vars.CurrentUser.Session))
`)) w.Write(menu_5)
} else { } else {
w.Write([]byte(` w.Write(menu_6)
<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>
`))
} }
w.Write([]byte(` w.Write(menu_7)
</ul> w.Write(header_3)
</div>
</div>
<div style="clear: both;"></div>
</div>
<div id="back"><div id="main">`))
if len(tmpl_forums_vars.NoticeList) != 0 { if len(tmpl_forums_vars.NoticeList) != 0 {
for _, item := range tmpl_forums_vars.NoticeList { for _, item := range tmpl_forums_vars.NoticeList {
w.Write([]byte(`<div class="alert">` + item + `</div>`)) w.Write(header_4)
w.Write([]byte(item))
w.Write(header_5)
} }
} }
w.Write([]byte(` w.Write(forums_0)
<div class="rowblock">
`))
if len(tmpl_forums_vars.ItemList) != 0 { if len(tmpl_forums_vars.ItemList) != 0 {
for _, item := range tmpl_forums_vars.ItemList { for _, item := range tmpl_forums_vars.ItemList {
w.Write([]byte(`<div class="rowitem"> w.Write(forums_1)
<a href="/forum/` + strconv.Itoa(item.ID) + `" style="font-size: 20px;position:relative;top: -2px;font-weight: normal;text-transform: none;">` + item.Name + `</a> w.Write([]byte(strconv.Itoa(item.ID)))
<a href="/topic/` + strconv.Itoa(item.LastTopicID) + `" style="font-weight: normal;text-transform: none;float: right;">` + item.LastTopic + ` <small style="font-size: 12px;">` + item.LastTopicTime + `</small></a> w.Write(forums_2)
</div> w.Write([]byte(item.Name))
`)) w.Write(forums_3)
w.Write([]byte(strconv.Itoa(item.LastTopicID)))
w.Write(forums_4)
w.Write([]byte(item.LastTopic))
w.Write(forums_5)
w.Write([]byte(item.LastTopicTime))
w.Write(forums_6)
} }
} else { } else {
w.Write([]byte(`<div class="rowitem passive">You don't have access to any forums.</div>`)) w.Write(forums_7)
} }
w.Write([]byte(` w.Write(forums_8)
</div> w.Write(footer_0)
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`))
} }

421
template_list.go Normal file
View File

@ -0,0 +1,421 @@
package main
var header_0 []byte = []byte(`<!doctype html>
<html lang="en">
<head>
<title>`)
var header_1 []byte = []byte(`</title>
<link href="/static/main.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/static/jquery-1.12.3.min.js"></script>
<script type="text/javascript">
var session = "`)
var header_2 []byte = []byte(`";
</script>
<script type="text/javascript" src="/static/global.js"></script>
<meta name="viewport" content="width=device-width,initial-scale = 1.0, maximum-scale=1.0,user-scalable=no" />
</head>
<body>
<div class="container">
`)
var menu_0 []byte = []byte(`<div class="nav">
<div class="move_left">
<div class="move_right">
<ul>
<li class="menu_left menu_overview"><a href="/">Overview</a></li>
<li class="menu_left menu_forums"><a href="/forums/">Forums</a></li>
<li class="menu_left menu_topics"><a href="/">Topics</a></li>
<li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li>
`)
var menu_1 []byte = []byte(`
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_profile"><a href="/user/`)
var menu_2 []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_logout"><a href="/accounts/logout?session=`)
var menu_5 []byte = []byte(`">Logout</a></li>
`)
var menu_6 []byte = []byte(`
<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>
`)
var menu_7 []byte = []byte(`
</ul>
</div>
</div>
<div style="clear: both;"></div>
</div>`)
var header_3 []byte = []byte(`
<div id="back"><div id="main">`)
var header_4 []byte = []byte(`<div class="alert">`)
var header_5 []byte = []byte(`</div>`)
var topic_0 []byte = []byte(`
<div class="rowblock">
<form action='/topic/edit/submit/`)
var topic_1 []byte = []byte(`' method="post">
<div class="rowitem"`)
var topic_2 []byte = []byte(` style="background-color: #FFFFEA;"`)
var topic_3 []byte = []byte(` style="background-color: #eaeaea;"`)
var topic_4 []byte = []byte(`>
<a class='topic_name hide_on_edit'>`)
var topic_5 []byte = []byte(`</a>
`)
var topic_6 []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;">&#x1F512;&#xFE0E</span>`)
var topic_7 []byte = []byte(`
<a href='/topic/edit/`)
var topic_8 []byte = []byte(`' class="username hide_on_edit open_edit" style="font-weight: normal;margin-left: 6px;">Edit</a>
<a href='/topic/delete/submit/`)
var topic_9 []byte = []byte(`' class="username" style="font-weight: normal;">Delete</a>
`)
var topic_10 []byte = []byte(`<a href='/topic/unstick/submit/`)
var topic_11 []byte = []byte(`' class="username" style="font-weight: normal;">Unpin</a>`)
var topic_12 []byte = []byte(`<a href='/topic/stick/submit/`)
var topic_13 []byte = []byte(`' class="username" style="font-weight: normal;">Pin</a>`)
var topic_14 []byte = []byte(`
<input class='show_on_edit topic_name_input' name="topic_name" value='`)
var topic_15 []byte = []byte(`' type="text" />
<select name="topic_status" class='show_on_edit topic_status_input' style='float: right;'>
<option>open</option>
<option>closed</option>
</select>
<button name="topic-button" class="formbutton show_on_edit submit_edit">Update</button>
`)
var topic_16 []byte = []byte(`
<a href="/report/submit/`)
var topic_17 []byte = []byte(`?session=`)
var topic_18 []byte = []byte(`&type=topic" class="username report_item" style="font-weight: normal;">Report</a>
</div>
</form>
</div>
<div class="rowblock post_container">
<div class="rowitem passive editable_parent post_item" style="border-bottom: none;`)
var topic_19 []byte = []byte(`background-image: url(`)
var topic_20 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `)
var topic_21 []byte = []byte(`-1`)
var topic_22 []byte = []byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;`)
var topic_23 []byte = []byte(`">
<p class="hide_on_edit topic_content user_content" style="margin: 0;padding: 0;">`)
var topic_24 []byte = []byte(`</p>
<textarea name="topic_content" class="show_on_edit topic_content_input">`)
var topic_25 []byte = []byte(`</textarea><br /><br />
<a href="/user/`)
var topic_26 []byte = []byte(`" class="username real_username">`)
var topic_27 []byte = []byte(`</a>
<a class="username hide_on_micro" `)
var topic_28 []byte = []byte(`style="float: right;">`)
var topic_29 []byte = []byte(`style="color: #505050;float: right;">Level `)
var topic_30 []byte = []byte(`</a>
</div>
</div><br />
<div class="rowblock post_container" style="overflow: hidden;">`)
var topic_31 []byte = []byte(`
<div class="rowitem rowhead passive deletable_block editable_parent post_item" style="`)
var topic_32 []byte = []byte(`background-image: url(`)
var topic_33 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `)
var topic_34 []byte = []byte(`-1`)
var topic_35 []byte = []byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;`)
var topic_36 []byte = []byte(`">
<p class="editable_block user_content" style="margin: 0;padding: 0;">`)
var topic_37 []byte = []byte(`</p><br /><br />
<a href="/user/`)
var topic_38 []byte = []byte(`" class="username real_username">`)
var topic_39 []byte = []byte(`</a>
`)
var topic_40 []byte = []byte(`<a href="/reply/edit/submit/`)
var topic_41 []byte = []byte(`" class="mod_button"><button class="username edit_item">Edit</button></a> `)
var topic_42 []byte = []byte(`<a href="/reply/delete/submit/`)
var topic_43 []byte = []byte(`" class="mod_button"><button class="username delete_item">Delete</button></a> `)
var topic_44 []byte = []byte(`
<a href="/report/submit/`)
var topic_45 []byte = []byte(`?session=`)
var topic_46 []byte = []byte(`&type=reply" class="mod_button"><button class="username report_item">Report</button></a>
<a class="username hide_on_micro" `)
var topic_47 []byte = []byte(`style="float: right;">`)
var topic_48 []byte = []byte(`style="color: #505050;float: right;">Level `)
var topic_49 []byte = []byte(`</a>
</div>
`)
var topic_50 []byte = []byte(`</div>
`)
var topic_51 []byte = []byte(`
<div class="rowblock">
<form action="/reply/create/" method="post">
<input name="tid" value='`)
var topic_52 []byte = []byte(`' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>
<div class="formrow">
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</button></div>
</div>
</form>
</div>
`)
var footer_0 []byte = []byte(` <!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`)
var topic_alt_0 []byte = []byte(`
<div class="rowblock">
<form action='/topic/edit/submit/`)
var topic_alt_1 []byte = []byte(`' method="post">
<div class="rowitem rowhead`)
var topic_alt_2 []byte = []byte(` topic_sticky_head`)
var topic_alt_3 []byte = []byte(` topic_closed_head`)
var topic_alt_4 []byte = []byte(`">
<a class='topic_name hide_on_edit'>`)
var topic_alt_5 []byte = []byte(`</a>
`)
var topic_alt_6 []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;">&#x1F512;&#xFE0E</span>`)
var topic_alt_7 []byte = []byte(`
<a href='/topic/edit/`)
var topic_alt_8 []byte = []byte(`' class="username hide_on_edit open_edit topic_button" style="font-weight: normal;margin-left: 6px;">Edit</a>
<a href='/topic/delete/submit/`)
var topic_alt_9 []byte = []byte(`' class="username topic_button" style="font-weight: normal;">Delete</a>
`)
var topic_alt_10 []byte = []byte(`<a href='/topic/unstick/submit/`)
var topic_alt_11 []byte = []byte(`' class="username topic_button" style="font-weight: normal;">Unpin</a>`)
var topic_alt_12 []byte = []byte(`<a href='/topic/stick/submit/`)
var topic_alt_13 []byte = []byte(`' class="username topic_button" style="font-weight: normal;">Pin</a>`)
var topic_alt_14 []byte = []byte(`
<input class='show_on_edit topic_name_input' name="topic_name" value='`)
var topic_alt_15 []byte = []byte(`' type="text" />
<select name="topic_status" class='show_on_edit topic_status_input' style='float: right;'>
<option>open</option>
<option>closed</option>
</select>
<button name="topic-button" class="formbutton show_on_edit submit_edit">Update</button>
`)
var topic_alt_16 []byte = []byte(`
<a href="/report/submit/`)
var topic_alt_17 []byte = []byte(`?session=`)
var topic_alt_18 []byte = []byte(`&type=topic" class="username report_item topic_button" style="font-weight: normal;">Report</a>
</div>
</form>
</div>
<style type="text/css">.rowitem:last-child .content_container { margin-bottom: 5px !important; }</style>
<div class="rowblock post_container" style="border-top: none;">
<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="avatar_item" style="background-image: url(`)
var topic_alt_19 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div>
<a href="/user/`)
var topic_alt_20 []byte = []byte(`" class="the_name">`)
var topic_alt_21 []byte = []byte(`</a>
`)
var topic_alt_22 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">`)
var topic_alt_23 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_24 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level `)
var topic_alt_25 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_26 []byte = []byte(`
</div>
<div class="content_container">
<div class="hide_on_edit topic_content user_content">`)
var topic_alt_27 []byte = []byte(`</div>
<textarea name="topic_content" class="show_on_edit topic_content_input">`)
var topic_alt_28 []byte = []byte(`</textarea>
<div class="button_container">
`)
var topic_alt_29 []byte = []byte(`<a href="#" class="action_button action_button_right ip_item">`)
var topic_alt_30 []byte = []byte(`</a>`)
var topic_alt_31 []byte = []byte(`
</div>
</div><div style="clear:both;"></div>
</div>
`)
var topic_alt_32 []byte = []byte(`
<div class="rowitem passive deletable_block editable_parent post_item">
<div class="userinfo">
<div class="avatar_item" style="background-image: url(`)
var topic_alt_33 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div>
<a href="/user/`)
var topic_alt_34 []byte = []byte(`" class="the_name">`)
var topic_alt_35 []byte = []byte(`</a>
`)
var topic_alt_36 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">`)
var topic_alt_37 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_38 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level `)
var topic_alt_39 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_40 []byte = []byte(`
</div>
<div class="content_container">
<div class="editable_block user_content">`)
var topic_alt_41 []byte = []byte(`</div>
<div class="button_container">
`)
var topic_alt_42 []byte = []byte(`<a href="/reply/edit/submit/`)
var topic_alt_43 []byte = []byte(`" class="action_button edit_item">Edit</a>`)
var topic_alt_44 []byte = []byte(`<a href="/reply/delete/submit/`)
var topic_alt_45 []byte = []byte(`" class="action_button delete_item">Delete</a>`)
var topic_alt_46 []byte = []byte(`
<a href="/report/submit/`)
var topic_alt_47 []byte = []byte(`?session=`)
var topic_alt_48 []byte = []byte(`&type=reply" class="action_button report_item">Report</a>
`)
var topic_alt_49 []byte = []byte(`<a href="#" class="action_button action_button_right ip_item">`)
var topic_alt_50 []byte = []byte(`</a>`)
var topic_alt_51 []byte = []byte(`
</div>
</div>
<div style="clear:both;"></div>
</div>
`)
var topic_alt_52 []byte = []byte(`</div>
`)
var topic_alt_53 []byte = []byte(`
<div class="rowblock" style="border-top: none;">
<form action="/reply/create/" method="post">
<input name="tid" value='`)
var topic_alt_54 []byte = []byte(`' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>
<div class="formrow">
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</button></div>
</div>
</form>
</div>
`)
var profile_0 []byte = []byte(`
<div class="colblock_left" style="max-width: 220px;">
<div class="rowitem" style="padding: 0;"><img src="`)
var profile_1 []byte = []byte(`" style="max-width: 100%;margin: 0;display: block;" /></div>
<div class="rowitem" style="text-transform: capitalize;">
<span style="font-size: 18px;">`)
var profile_2 []byte = []byte(`</span>`)
var profile_3 []byte = []byte(`<span class="username" style="float: right;font-weight: normal;">`)
var profile_4 []byte = []byte(`</span>`)
var profile_5 []byte = []byte(`
</div>
<div class="rowitem passive">
<a class="username">Add Friend</a>
`)
var profile_6 []byte = []byte(`<a href="/users/unban/`)
var profile_7 []byte = []byte(`?session=`)
var profile_8 []byte = []byte(`" class="username">Unban</a>`)
var profile_9 []byte = []byte(`<a href="/users/ban/`)
var profile_10 []byte = []byte(`?session=`)
var profile_11 []byte = []byte(`" class="username">Ban</a>`)
var profile_12 []byte = []byte(`
<a href="/report/submit/`)
var profile_13 []byte = []byte(`?session=`)
var profile_14 []byte = []byte(`&type=user" class="username report_item">Report</a>
</div>
</div>
<div class="colblock_right">
<div class="rowitem rowhead"><a>Comments</a></div>
</div>
<div class="colblock_right" style="overflow: hidden;border-top: none;">`)
var profile_15 []byte = []byte(`
<div class="rowitem passive deletable_block editable_parent simple" style="`)
var profile_16 []byte = []byte(`background-image: url(`)
var profile_17 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `)
var profile_18 []byte = []byte(`-1`)
var profile_19 []byte = []byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;`)
var profile_20 []byte = []byte(`">
<span class="editable_block user_content simple">`)
var profile_21 []byte = []byte(`</span>
<br /><br />
<a href="/user/`)
var profile_22 []byte = []byte(`" class="username">`)
var profile_23 []byte = []byte(`</a>
`)
var profile_24 []byte = []byte(`<a href="/profile/reply/edit/submit/`)
var profile_25 []byte = []byte(`"><button class="username edit_item">Edit</button></a>
<a href="/profile/reply/delete/submit/`)
var profile_26 []byte = []byte(`"><button class="username delete_item">Delete</button></a>`)
var profile_27 []byte = []byte(`
<a href="/report/submit/`)
var profile_28 []byte = []byte(`?session=`)
var profile_29 []byte = []byte(`&type=user-reply"><button class="username report_item">Report</button></a>
`)
var profile_30 []byte = []byte(`<a class="username hide_on_mobile" style="float: right;">`)
var profile_31 []byte = []byte(`</a>`)
var profile_32 []byte = []byte(`
</div>
`)
var profile_33 []byte = []byte(`</div>
<div class="colblock_right" style="border-top: none;">
`)
var profile_34 []byte = []byte(`
<form action="/profile/reply/create/" method="post">
<input name="uid" value='`)
var profile_35 []byte = []byte(`' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>
<div class="formrow">
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</button></div>
</div>
</form>
`)
var profile_36 []byte = []byte(`
</div>
`)
var forums_0 []byte = []byte(`
<div class="rowblock">
`)
var forums_1 []byte = []byte(`<div class="rowitem">
<a href="/forum/`)
var forums_2 []byte = []byte(`" style="font-size: 20px;position:relative;top: -2px;font-weight: normal;text-transform: none;">`)
var forums_3 []byte = []byte(`</a>
<a href="/topic/`)
var forums_4 []byte = []byte(`" style="font-weight: normal;text-transform: none;float: right;">`)
var forums_5 []byte = []byte(` <small style="font-size: 12px;">`)
var forums_6 []byte = []byte(`</small></a>
</div>
`)
var forums_7 []byte = []byte(`<div class="rowitem passive">You don't have access to any forums.</div>`)
var forums_8 []byte = []byte(`
</div>
`)
var topics_0 []byte = []byte(`
<div class="rowblock">
<div class="rowitem rowhead"><a>Topic List</a></div>
</div>
<div class="rowblock">
`)
var topics_1 []byte = []byte(`<div class="rowitem passive" style="`)
var topics_2 []byte = []byte(`background-image: url(`)
var topics_3 []byte = []byte(`);background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;`)
var topics_4 []byte = []byte(`background-color: #FFFFCC;`)
var topics_5 []byte = []byte(`background-color: #eaeaea;`)
var topics_6 []byte = []byte(`">
<a href="/topic/`)
var topics_7 []byte = []byte(`">`)
var topics_8 []byte = []byte(`</a> `)
var topics_9 []byte = []byte(`<span class="username topic_status_e topic_status_closed" style="float: right;" title="Status: Closed">&#x1F512;&#xFE0E</span>`)
var topics_10 []byte = []byte(`
</div>
`)
var topics_11 []byte = []byte(`<div class="rowitem passive">There aren't any topics yet.</div>`)
var topics_12 []byte = []byte(`
</div>
`)
var forum_0 []byte = []byte(`
<div class="rowblock">
<div class="rowitem rowhead"><a>`)
var forum_1 []byte = []byte(`</a></div>
</div>
<div class="rowblock">
`)
var forum_2 []byte = []byte(`<div class="rowitem passive" style="`)
var forum_3 []byte = []byte(`background-image: url(`)
var forum_4 []byte = []byte(`);background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;`)
var forum_5 []byte = []byte(`background-color: #FFFFCC;`)
var forum_6 []byte = []byte(`background-color: #eaeaea;`)
var forum_7 []byte = []byte(`">
<a href="/topic/`)
var forum_8 []byte = []byte(`">`)
var forum_9 []byte = []byte(`</a> `)
var forum_10 []byte = []byte(`<span class="username topic_status_e topic_status_closed" title="Status: Closed" style="float: right;">&#x1F512;&#xFE0E</span>`)
var forum_11 []byte = []byte(`
</div>
`)
var forum_12 []byte = []byte(`<div class="rowitem passive">There aren't any topics in this forum yet.</div>`)
var forum_13 []byte = []byte(`
</div>
`)

View File

@ -12,141 +12,111 @@ func init() {
} }
func template_profile(tmpl_profile_vars ProfilePage, w io.Writer) { func template_profile(tmpl_profile_vars ProfilePage, w io.Writer) {
w.Write([]byte(`<!doctype html> w.Write(header_0)
<html lang="en"> w.Write([]byte(tmpl_profile_vars.Title))
<head> w.Write(header_1)
<title>` + tmpl_profile_vars.Title + `</title> w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
<link href="/static/main.css" rel="stylesheet" type="text/css"> w.Write(header_2)
<script type="text/javascript" src="/static/jquery-1.12.3.min.js"></script> w.Write(menu_0)
<script type="text/javascript">
var session = "` + tmpl_profile_vars.CurrentUser.Session + `";
</script>
<script type="text/javascript" src="/static/global.js"></script>
<meta name="viewport" content="width=device-width,initial-scale = 1.0, maximum-scale=1.0,user-scalable=no" />
</head>
<body>
<div class="container">
<div class="nav">
<div class="move_left">
<div class="move_right">
<ul>
<li class="menu_left menu_overview"><a href="/">Overview</a></li>
<li class="menu_left menu_forums"><a href="/forums/">Forums</a></li>
<li class="menu_left menu_topics"><a href="/">Topics</a></li>
<li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li>
`))
if tmpl_profile_vars.CurrentUser.Loggedin { if tmpl_profile_vars.CurrentUser.Loggedin {
w.Write([]byte(` w.Write(menu_1)
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li> w.Write([]byte(strconv.Itoa(tmpl_profile_vars.CurrentUser.ID)))
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_profile_vars.CurrentUser.ID) + `">Profile</a></li> w.Write(menu_2)
`))
if tmpl_profile_vars.CurrentUser.Is_Super_Mod { if tmpl_profile_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>`)) w.Write(menu_3)
} }
w.Write([]byte(` w.Write(menu_4)
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_profile_vars.CurrentUser.Session + `">Logout</a></li> w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
`)) w.Write(menu_5)
} else { } else {
w.Write([]byte(` w.Write(menu_6)
<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>
`))
} }
w.Write([]byte(` w.Write(menu_7)
</ul> w.Write(header_3)
</div>
</div>
<div style="clear: both;"></div>
</div>
<div id="back"><div id="main">`))
if len(tmpl_profile_vars.NoticeList) != 0 { if len(tmpl_profile_vars.NoticeList) != 0 {
for _, item := range tmpl_profile_vars.NoticeList { for _, item := range tmpl_profile_vars.NoticeList {
w.Write([]byte(`<div class="alert">` + item + `</div>`)) w.Write(header_4)
w.Write([]byte(item))
w.Write(header_5)
} }
} }
w.Write([]byte(` w.Write(profile_0)
<div class="colblock_left" style="max-width: 220px;"> w.Write([]byte(tmpl_profile_vars.ProfileOwner.Avatar))
<div class="rowitem" style="padding: 0;"><img src="` + tmpl_profile_vars.ProfileOwner.Avatar + `" style="max-width: 100%;margin: 0;display: block;" /></div> w.Write(profile_1)
<div class="rowitem" style="text-transform: capitalize;"> w.Write([]byte(tmpl_profile_vars.ProfileOwner.Name))
<span style="font-size: 18px;">` + tmpl_profile_vars.ProfileOwner.Name + `</span>`)) w.Write(profile_2)
if tmpl_profile_vars.ProfileOwner.Tag != "" { if tmpl_profile_vars.ProfileOwner.Tag != "" {
w.Write([]byte(`<span class="username" style="float: right;font-weight: normal;">` + tmpl_profile_vars.ProfileOwner.Tag + `</span>`)) w.Write(profile_3)
w.Write([]byte(tmpl_profile_vars.ProfileOwner.Tag))
w.Write(profile_4)
} }
w.Write([]byte(` w.Write(profile_5)
</div>
<div class="rowitem passive">
<a class="username">Add Friend</a>
`))
if tmpl_profile_vars.CurrentUser.Is_Super_Mod && !tmpl_profile_vars.ProfileOwner.Is_Super_Mod { if tmpl_profile_vars.CurrentUser.Is_Super_Mod && !tmpl_profile_vars.ProfileOwner.Is_Super_Mod {
w.Write([]byte(`
`))
if tmpl_profile_vars.ProfileOwner.Is_Banned { if tmpl_profile_vars.ProfileOwner.Is_Banned {
w.Write([]byte(`<a href="/users/unban/` + strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID) + `?session=` + tmpl_profile_vars.CurrentUser.Session + `" class="username">Unban</a>`)) w.Write(profile_6)
w.Write([]byte(strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID)))
w.Write(profile_7)
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
w.Write(profile_8)
} else { } else {
w.Write([]byte(`<a href="/users/ban/` + strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID) + `?session=` + tmpl_profile_vars.CurrentUser.Session + `" class="username">Ban</a>`)) w.Write(profile_9)
w.Write([]byte(strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID)))
w.Write(profile_10)
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
w.Write(profile_11)
} }
w.Write([]byte(`
`))
} }
w.Write([]byte(` w.Write(profile_12)
<a href="/report/submit/` + strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID) + `?session=` + tmpl_profile_vars.CurrentUser.Session + `&type=user" class="username report_item">Report</a> w.Write([]byte(strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID)))
</div> w.Write(profile_13)
</div> w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
<div class="colblock_right"> w.Write(profile_14)
<div class="rowitem rowhead"><a>Comments</a></div>
</div>
<div class="colblock_right" style="overflow: hidden;border-top: none;">`))
if len(tmpl_profile_vars.ItemList) != 0 { if len(tmpl_profile_vars.ItemList) != 0 {
for _, item := range tmpl_profile_vars.ItemList { for _, item := range tmpl_profile_vars.ItemList {
w.Write([]byte(` w.Write(profile_15)
<div class="rowitem passive deletable_block editable_parent simple" style="`))
if item.Avatar != "" { if item.Avatar != "" {
w.Write([]byte(`background-image: url(` + item.Avatar + `), url(/static/white-dot.jpg);background-position: 0px `)) w.Write(profile_16)
w.Write([]byte(item.Avatar))
w.Write(profile_17)
if item.ContentLines <= 5 { if item.ContentLines <= 5 {
w.Write([]byte(`-1`)) w.Write(profile_18)
} }
w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;` + string(item.Css))) w.Write(profile_19)
w.Write([]byte(string(item.Css)))
} }
w.Write([]byte(`"> w.Write(profile_20)
<span class="editable_block user_content simple">` + string(item.ContentHtml) + `</span> w.Write([]byte(string(item.ContentHtml)))
<br /><br /> w.Write(profile_21)
<a href="/user/` + strconv.Itoa(item.CreatedBy) + `" class="username">` + item.CreatedByName + `</a> w.Write([]byte(strconv.Itoa(item.CreatedBy)))
`)) w.Write(profile_22)
w.Write([]byte(item.CreatedByName))
w.Write(profile_23)
if tmpl_profile_vars.CurrentUser.Is_Mod { if tmpl_profile_vars.CurrentUser.Is_Mod {
w.Write([]byte(`<a href="/profile/reply/edit/submit/` + strconv.Itoa(item.ID) + `"><button class="username edit_item">Edit</button></a> w.Write(profile_24)
<a href="/profile/reply/delete/submit/` + strconv.Itoa(item.ID) + `"><button class="username delete_item">Delete</button></a>`)) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(profile_25)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(profile_26)
} }
w.Write([]byte(` w.Write(profile_27)
<a href="/report/submit/` + strconv.Itoa(item.ID) + `?session=` + tmpl_profile_vars.CurrentUser.Session + `&type=user-reply"><button class="username report_item">Report</button></a> w.Write([]byte(strconv.Itoa(item.ID)))
`)) w.Write(profile_28)
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
w.Write(profile_29)
if item.Tag != "" { if item.Tag != "" {
w.Write([]byte(`<a class="username hide_on_mobile" style="float: right;">` + item.Tag + `</a>`)) w.Write(profile_30)
w.Write([]byte(item.Tag))
w.Write(profile_31)
} }
w.Write([]byte(` w.Write(profile_32)
</div>
`))
} }
} }
w.Write([]byte(`</div> w.Write(profile_33)
<div class="colblock_right" style="border-top: none;">
`))
if !tmpl_profile_vars.CurrentUser.Is_Banned { if !tmpl_profile_vars.CurrentUser.Is_Banned {
w.Write([]byte(` w.Write(profile_34)
<form action="/profile/reply/create/" method="post"> w.Write([]byte(strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID)))
<input name="uid" value='` + strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID) + `' type="hidden" /> w.Write(profile_35)
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>
<div class="formrow">
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</button></div>
</div>
</form>
`))
} }
w.Write([]byte(` w.Write(profile_36)
</div> w.Write(footer_0)
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`))
} }

View File

@ -13,197 +13,151 @@ func init() {
} }
func template_topic(tmpl_topic_vars TopicPage, w io.Writer) { func template_topic(tmpl_topic_vars TopicPage, w io.Writer) {
w.Write([]byte(`<!doctype html> w.Write(header_0)
<html lang="en"> w.Write([]byte(tmpl_topic_vars.Title))
<head> w.Write(header_1)
<title>` + tmpl_topic_vars.Title + `</title> w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
<link href="/static/main.css" rel="stylesheet" type="text/css"> w.Write(header_2)
<script type="text/javascript" src="/static/jquery-1.12.3.min.js"></script> w.Write(menu_0)
<script type="text/javascript">
var session = "` + tmpl_topic_vars.CurrentUser.Session + `";
</script>
<script type="text/javascript" src="/static/global.js"></script>
<meta name="viewport" content="width=device-width,initial-scale = 1.0, maximum-scale=1.0,user-scalable=no" />
</head>
<body>
<div class="container">
<div class="nav">
<div class="move_left">
<div class="move_right">
<ul>
<li class="menu_left menu_overview"><a href="/">Overview</a></li>
<li class="menu_left menu_forums"><a href="/forums/">Forums</a></li>
<li class="menu_left menu_topics"><a href="/">Topics</a></li>
<li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li>
`))
if tmpl_topic_vars.CurrentUser.Loggedin { if tmpl_topic_vars.CurrentUser.Loggedin {
w.Write([]byte(` w.Write(menu_1)
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li> w.Write([]byte(strconv.Itoa(tmpl_topic_vars.CurrentUser.ID)))
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_topic_vars.CurrentUser.ID) + `">Profile</a></li> w.Write(menu_2)
`))
if tmpl_topic_vars.CurrentUser.Is_Super_Mod { if tmpl_topic_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>`)) w.Write(menu_3)
} }
w.Write([]byte(` w.Write(menu_4)
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_topic_vars.CurrentUser.Session + `">Logout</a></li> w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
`)) w.Write(menu_5)
} else { } else {
w.Write([]byte(` w.Write(menu_6)
<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>
`))
} }
w.Write([]byte(` w.Write(menu_7)
</ul> w.Write(header_3)
</div>
</div>
<div style="clear: both;"></div>
</div>
<div id="back"><div id="main">`))
if len(tmpl_topic_vars.NoticeList) != 0 { if len(tmpl_topic_vars.NoticeList) != 0 {
for _, item := range tmpl_topic_vars.NoticeList { for _, item := range tmpl_topic_vars.NoticeList {
w.Write([]byte(`<div class="alert">` + item + `</div>`)) w.Write(header_4)
w.Write([]byte(item))
w.Write(header_5)
} }
} }
w.Write([]byte(` w.Write(topic_0)
<div class="rowblock"> w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
<form action='/topic/edit/submit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' method="post"> w.Write(topic_1)
<div class="rowitem"`))
if tmpl_topic_vars.Topic.Sticky { if tmpl_topic_vars.Topic.Sticky {
w.Write([]byte(` style="background-color: #FFFFEA;"`)) w.Write(topic_2)
} else { } else {
if tmpl_topic_vars.Topic.Is_Closed { if tmpl_topic_vars.Topic.Is_Closed {
w.Write([]byte(` style="background-color: #eaeaea;"`)) w.Write(topic_3)
} }
} }
w.Write([]byte(`> w.Write(topic_4)
<a class='topic_name hide_on_edit'>` + tmpl_topic_vars.Topic.Title + `</a> w.Write([]byte(tmpl_topic_vars.Topic.Title))
`)) w.Write(topic_5)
if tmpl_topic_vars.Topic.Is_Closed { if tmpl_topic_vars.Topic.Is_Closed {
w.Write([]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;">&#x1F512;&#xFE0E</span>`)) w.Write(topic_6)
} }
w.Write([]byte(`
`))
if tmpl_topic_vars.CurrentUser.Is_Mod { if tmpl_topic_vars.CurrentUser.Is_Mod {
w.Write([]byte(` w.Write(topic_7)
<a href='/topic/edit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' class="username hide_on_edit open_edit" style="font-weight: normal;margin-left: 6px;">Edit</a> w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
<a href='/topic/delete/submit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' class="username" style="font-weight: normal;">Delete</a> w.Write(topic_8)
`)) w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_9)
if tmpl_topic_vars.Topic.Sticky { if tmpl_topic_vars.Topic.Sticky {
w.Write([]byte(`<a href='/topic/unstick/submit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' class="username" style="font-weight: normal;">Unpin</a>`)) w.Write(topic_10)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_11)
} else { } else {
w.Write([]byte(`<a href='/topic/stick/submit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' class="username" style="font-weight: normal;">Pin</a>`)) w.Write(topic_12)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_13)
} }
w.Write([]byte(` w.Write(topic_14)
w.Write([]byte(tmpl_topic_vars.Topic.Title))
<input class='show_on_edit topic_name_input' name="topic_name" value='` + tmpl_topic_vars.Topic.Title + `' type="text" /> w.Write(topic_15)
<select name="topic_status" class='show_on_edit topic_status_input' style='float: right;'>
<option>open</option>
<option>closed</option>
</select>
<button name="topic-button" class="formbutton show_on_edit submit_edit">Update</button>
`))
} }
w.Write([]byte(` w.Write(topic_16)
<a href="/report/submit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `?session=` + tmpl_topic_vars.CurrentUser.Session + `&type=topic" class="username report_item" style="font-weight: normal;">Report</a> w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
</div> w.Write(topic_17)
</form> w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
</div> w.Write(topic_18)
<div class="rowblock post_container">
<div class="rowitem passive editable_parent post_item" style="border-bottom: none;`))
if tmpl_topic_vars.Topic.Avatar != "" { if tmpl_topic_vars.Topic.Avatar != "" {
w.Write([]byte(`background-image: url(` + tmpl_topic_vars.Topic.Avatar + `), url(/static/white-dot.jpg);background-position: 0px `)) w.Write(topic_19)
w.Write([]byte(tmpl_topic_vars.Topic.Avatar))
w.Write(topic_20)
if tmpl_topic_vars.Topic.ContentLines <= 5 { if tmpl_topic_vars.Topic.ContentLines <= 5 {
w.Write([]byte(`-1`)) w.Write(topic_21)
} }
w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;` + string(tmpl_topic_vars.Topic.Css))) w.Write(topic_22)
w.Write([]byte(string(tmpl_topic_vars.Topic.Css)))
} }
w.Write([]byte(`"> w.Write(topic_23)
<p class="hide_on_edit topic_content user_content" style="margin: 0;padding: 0;">` + string(tmpl_topic_vars.Topic.Content.(template.HTML)) + `</p> w.Write([]byte(string(tmpl_topic_vars.Topic.Content.(template.HTML))))
<textarea name="topic_content" class="show_on_edit topic_content_input">` + string(tmpl_topic_vars.Topic.Content.(template.HTML)) + `</textarea><br /><br /> w.Write(topic_24)
<a href="/user/` + strconv.Itoa(tmpl_topic_vars.Topic.CreatedBy) + `" class="username real_username">` + tmpl_topic_vars.Topic.CreatedByName + `</a> w.Write([]byte(string(tmpl_topic_vars.Topic.Content.(template.HTML))))
`)) w.Write(topic_25)
if tmpl_topic_vars.Topic.Level != -1 { w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.CreatedBy)))
w.Write([]byte(`<a class="username level hide_on_mobile" title="Level ` + strconv.Itoa(tmpl_topic_vars.Topic.Level) + `">L` + strconv.Itoa(tmpl_topic_vars.Topic.Level) + `</a>`)) w.Write(topic_26)
} w.Write([]byte(tmpl_topic_vars.Topic.CreatedByName))
w.Write([]byte(` w.Write(topic_27)
`))
if tmpl_topic_vars.Topic.Tag != "" { if tmpl_topic_vars.Topic.Tag != "" {
w.Write([]byte(`<a class="username hide_on_micro" style="float: right;">` + tmpl_topic_vars.Topic.Tag + `</a>`)) w.Write(topic_28)
w.Write([]byte(tmpl_topic_vars.Topic.Tag))
} else { } else {
if tmpl_topic_vars.Topic.URLName != "" { w.Write(topic_29)
w.Write([]byte(`<a href="` + tmpl_topic_vars.Topic.URL + `" class="username" style="color: #505050;float: right;">` + tmpl_topic_vars.Topic.URLName + `</a> w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.Level)))
<a class="username" style="color: #505050;float: right;border-right: 0;">` + tmpl_topic_vars.Topic.URLPrefix + `</a>`))
} }
} w.Write(topic_30)
w.Write([]byte(`
</div>
</div><br />
<div class="rowblock post_container" style="overflow: hidden;">`))
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 {
w.Write([]byte(` w.Write(topic_31)
<div class="rowitem rowhead passive deletable_block editable_parent post_item" style="`))
if item.Avatar != "" { if item.Avatar != "" {
w.Write([]byte(`background-image: url(` + item.Avatar + `), url(/static/white-dot.jpg);background-position: 0px `)) w.Write(topic_32)
w.Write([]byte(item.Avatar))
w.Write(topic_33)
if item.ContentLines <= 5 { if item.ContentLines <= 5 {
w.Write([]byte(`-1`)) w.Write(topic_34)
} }
w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;` + string(item.Css))) w.Write(topic_35)
w.Write([]byte(string(item.Css)))
} }
w.Write([]byte(`"> w.Write(topic_36)
<p class="editable_block user_content" style="margin: 0;padding: 0;">` + string(item.ContentHtml) + `</p><br /><br /> w.Write([]byte(string(item.ContentHtml)))
<a href="/user/` + strconv.Itoa(item.CreatedBy) + `" class="username real_username">` + item.CreatedByName + `</a> w.Write(topic_37)
`)) w.Write([]byte(strconv.Itoa(item.CreatedBy)))
if item.Level != -1 { w.Write(topic_38)
w.Write([]byte(`<a class="username level hide_on_mobile" title="Level ` + strconv.Itoa(item.Level) + `">L` + strconv.Itoa(item.Level) + `</a>`)) w.Write([]byte(item.CreatedByName))
} w.Write(topic_39)
w.Write([]byte(`
`))
if tmpl_topic_vars.CurrentUser.Perms.EditReply { if tmpl_topic_vars.CurrentUser.Perms.EditReply {
w.Write([]byte(`<a href="/reply/edit/submit/` + strconv.Itoa(item.ID) + `" class="mod_button"><button class="username edit_item">Edit</button></a>`)) w.Write(topic_40)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_41)
} }
w.Write([]byte(`
`))
if tmpl_topic_vars.CurrentUser.Perms.DeleteReply { if tmpl_topic_vars.CurrentUser.Perms.DeleteReply {
w.Write([]byte(`<a href="/reply/delete/submit/` + strconv.Itoa(item.ID) + `" class="mod_button"><button class="username delete_item">Delete</button></a>`)) w.Write(topic_42)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_43)
} }
w.Write([]byte(` w.Write(topic_44)
<a href="/report/submit/` + strconv.Itoa(item.ID) + `?session=` + tmpl_topic_vars.CurrentUser.Session + `&type=reply" class="mod_button"><button class="username report_item">Report</button></a> w.Write([]byte(strconv.Itoa(item.ID)))
`)) w.Write(topic_45)
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
w.Write(topic_46)
if item.Tag != "" { if item.Tag != "" {
w.Write([]byte(`<a class="username hide_on_micro" style="float: right;">` + item.Tag + `</a>`)) w.Write(topic_47)
w.Write([]byte(item.Tag))
} else { } else {
if item.URLName != "" { w.Write(topic_48)
w.Write([]byte(`<a href="` + item.URL + `" class="username hide_on_mobile" style="color: #505050;float: right;" rel="nofollow">` + item.URLName + `</a> w.Write([]byte(strconv.Itoa(item.Level)))
<a class="username hide_on_mobile" style="color: #505050;float: right;border-right: 0;">` + item.URLPrefix + `</a>`)) }
w.Write(topic_49)
} }
} }
w.Write([]byte(` w.Write(topic_50)
</div>
`))
}
}
w.Write([]byte(`</div>
`))
if tmpl_topic_vars.CurrentUser.Perms.CreateReply { if tmpl_topic_vars.CurrentUser.Perms.CreateReply {
w.Write([]byte(` w.Write(topic_51)
<div class="rowblock"> w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
<form action="/reply/create/" method="post"> w.Write(topic_52)
<input name="tid" value='` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>
<div class="formrow">
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</button></div>
</div>
</form>
</div>
`))
} }
w.Write([]byte(` w.Write(footer_0)
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`))
} }

View File

@ -13,179 +13,149 @@ func init() {
} }
func template_topic_alt(tmpl_topic_alt_vars TopicPage, w io.Writer) { func template_topic_alt(tmpl_topic_alt_vars TopicPage, w io.Writer) {
w.Write([]byte(`<!doctype html> w.Write(header_0)
<html lang="en"> w.Write([]byte(tmpl_topic_alt_vars.Title))
<head> w.Write(header_1)
<title>` + tmpl_topic_alt_vars.Title + `</title> w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
<link href="/static/main.css" rel="stylesheet" type="text/css"> w.Write(header_2)
<script type="text/javascript" src="/static/jquery-1.12.3.min.js"></script> w.Write(menu_0)
<script type="text/javascript">
var session = "` + tmpl_topic_alt_vars.CurrentUser.Session + `";
</script>
<script type="text/javascript" src="/static/global.js"></script>
<meta name="viewport" content="width=device-width,initial-scale = 1.0, maximum-scale=1.0,user-scalable=no" />
</head>
<body>
<div class="container">
<div class="nav">
<div class="move_left">
<div class="move_right">
<ul>
<li class="menu_left menu_overview"><a href="/">Overview</a></li>
<li class="menu_left menu_forums"><a href="/forums/">Forums</a></li>
<li class="menu_left menu_topics"><a href="/">Topics</a></li>
<li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li>
`))
if tmpl_topic_alt_vars.CurrentUser.Loggedin { if tmpl_topic_alt_vars.CurrentUser.Loggedin {
w.Write([]byte(` w.Write(menu_1)
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li> w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.CurrentUser.ID)))
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_topic_alt_vars.CurrentUser.ID) + `">Profile</a></li> w.Write(menu_2)
`))
if tmpl_topic_alt_vars.CurrentUser.Is_Super_Mod { if tmpl_topic_alt_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>`)) w.Write(menu_3)
} }
w.Write([]byte(` w.Write(menu_4)
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_topic_alt_vars.CurrentUser.Session + `">Logout</a></li> w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
`)) w.Write(menu_5)
} else { } else {
w.Write([]byte(` w.Write(menu_6)
<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>
`))
} }
w.Write([]byte(` w.Write(menu_7)
</ul> w.Write(header_3)
</div>
</div>
<div style="clear: both;"></div>
</div>
<div id="back"><div id="main">`))
if len(tmpl_topic_alt_vars.NoticeList) != 0 { if len(tmpl_topic_alt_vars.NoticeList) != 0 {
for _, item := range tmpl_topic_alt_vars.NoticeList { for _, item := range tmpl_topic_alt_vars.NoticeList {
w.Write([]byte(`<div class="alert">` + item + `</div>`)) w.Write(header_4)
w.Write([]byte(item))
w.Write(header_5)
} }
} }
w.Write([]byte(` w.Write(topic_alt_0)
<div class="rowblock"> w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
<form action='/topic/edit/submit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' method="post"> w.Write(topic_alt_1)
<div class="rowitem rowhead`))
if tmpl_topic_alt_vars.Topic.Sticky { if tmpl_topic_alt_vars.Topic.Sticky {
w.Write([]byte(` topic_sticky_head`)) w.Write(topic_alt_2)
} else { } else {
if tmpl_topic_alt_vars.Topic.Is_Closed { if tmpl_topic_alt_vars.Topic.Is_Closed {
w.Write([]byte(` topic_closed_head`)) w.Write(topic_alt_3)
} }
} }
w.Write([]byte(`"> w.Write(topic_alt_4)
<a class='topic_name hide_on_edit'>` + tmpl_topic_alt_vars.Topic.Title + `</a> w.Write([]byte(tmpl_topic_alt_vars.Topic.Title))
`)) w.Write(topic_alt_5)
if tmpl_topic_alt_vars.Topic.Is_Closed { if tmpl_topic_alt_vars.Topic.Is_Closed {
w.Write([]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;">&#x1F512;&#xFE0E</span>`)) w.Write(topic_alt_6)
} }
w.Write([]byte(`
`))
if tmpl_topic_alt_vars.CurrentUser.Is_Mod { if tmpl_topic_alt_vars.CurrentUser.Is_Mod {
w.Write([]byte(` w.Write(topic_alt_7)
<a href='/topic/edit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' class="username hide_on_edit open_edit topic_button" style="font-weight: normal;margin-left: 6px;">Edit</a> w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
<a href='/topic/delete/submit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' class="username topic_button" style="font-weight: normal;">Delete</a> w.Write(topic_alt_8)
`)) w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_9)
if tmpl_topic_alt_vars.Topic.Sticky { if tmpl_topic_alt_vars.Topic.Sticky {
w.Write([]byte(`<a href='/topic/unstick/submit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' class="username topic_button" style="font-weight: normal;">Unpin</a>`)) w.Write(topic_alt_10)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_11)
} else { } else {
w.Write([]byte(`<a href='/topic/stick/submit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' class="username topic_button" style="font-weight: normal;">Pin</a>`)) w.Write(topic_alt_12)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_13)
} }
w.Write([]byte(` w.Write(topic_alt_14)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Title))
<input class='show_on_edit topic_name_input' name="topic_name" value='` + tmpl_topic_alt_vars.Topic.Title + `' type="text" /> w.Write(topic_alt_15)
<select name="topic_status" class='show_on_edit topic_status_input' style='float: right;'>
<option>open</option>
<option>closed</option>
</select>
<button name="topic-button" class="formbutton show_on_edit submit_edit">Update</button>
`))
} }
w.Write([]byte(` w.Write(topic_alt_16)
<a href="/report/submit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `?session=` + tmpl_topic_alt_vars.CurrentUser.Session + `&type=topic" class="username report_item topic_button" style="font-weight: normal;">Report</a> w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
</div> w.Write(topic_alt_17)
</form> w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
</div> w.Write(topic_alt_18)
<style type="text/css">.rowitem:last-child .content_container { margin-bottom: 5px !important; }</style> w.Write([]byte(tmpl_topic_alt_vars.Topic.Avatar))
<div class="rowblock post_container" style="border-top: none;"> w.Write(topic_alt_19)
<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;"> w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.CreatedBy)))
<div class="userinfo"> w.Write(topic_alt_20)
<div class="avatar_item" style="background-image: url(` + tmpl_topic_alt_vars.Topic.Avatar + `), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div> w.Write([]byte(tmpl_topic_alt_vars.Topic.CreatedByName))
<a href="/user/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.CreatedBy) + `" class="the_name">` + tmpl_topic_alt_vars.Topic.CreatedByName + `</a> w.Write(topic_alt_21)
`))
if tmpl_topic_alt_vars.Topic.Tag != "" { if tmpl_topic_alt_vars.Topic.Tag != "" {
w.Write([]byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">` + tmpl_topic_alt_vars.Topic.Tag + `</div><div class="tag_post"></div></div>`)) w.Write(topic_alt_22)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Tag))
w.Write(topic_alt_23)
} else { } else {
w.Write([]byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level ` + strconv.Itoa(tmpl_topic_alt_vars.Topic.Level) + `</div><div class="tag_post"></div></div>`)) w.Write(topic_alt_24)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.Level)))
w.Write(topic_alt_25)
} }
w.Write([]byte(` w.Write(topic_alt_26)
</div> w.Write([]byte(string(tmpl_topic_alt_vars.Topic.Content.(template.HTML))))
<div class="content_container"> w.Write(topic_alt_27)
<div class="hide_on_edit topic_content user_content nobuttons">` + string(tmpl_topic_alt_vars.Topic.Content.(template.HTML)) + `</div> w.Write([]byte(string(tmpl_topic_alt_vars.Topic.Content.(template.HTML))))
<textarea name="topic_content" class="show_on_edit topic_content_input">` + string(tmpl_topic_alt_vars.Topic.Content.(template.HTML)) + `</textarea> w.Write(topic_alt_28)
</div> if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs {
<div style="clear:both;"></div> w.Write(topic_alt_29)
</div> w.Write([]byte(tmpl_topic_alt_vars.Topic.IpAddress))
`)) w.Write(topic_alt_30)
}
w.Write(topic_alt_31)
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([]byte(` w.Write(topic_alt_32)
<div class="rowitem passive deletable_block editable_parent post_item"> w.Write([]byte(item.Avatar))
<div class="userinfo"> w.Write(topic_alt_33)
<div class="avatar_item" style="background-image: url(` + item.Avatar + `), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div> w.Write([]byte(strconv.Itoa(item.CreatedBy)))
<a href="/user/` + strconv.Itoa(item.CreatedBy) + `" class="the_name">` + item.CreatedByName + `</a> w.Write(topic_alt_34)
`)) w.Write([]byte(item.CreatedByName))
w.Write(topic_alt_35)
if item.Tag != "" { if item.Tag != "" {
w.Write([]byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">` + item.Tag + `</div><div class="tag_post"></div></div>`)) w.Write(topic_alt_36)
w.Write([]byte(item.Tag))
w.Write(topic_alt_37)
} else { } else {
w.Write([]byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level ` + strconv.Itoa(item.Level) + `</div><div class="tag_post"></div></div>`)) w.Write(topic_alt_38)
w.Write([]byte(strconv.Itoa(item.Level)))
w.Write(topic_alt_39)
} }
w.Write([]byte(` w.Write(topic_alt_40)
</div> w.Write([]byte(string(item.ContentHtml)))
<div class="content_container"> w.Write(topic_alt_41)
<div class="editable_block user_content">` + string(item.ContentHtml) + `</div>
<div class="button_container">
`))
if tmpl_topic_alt_vars.CurrentUser.Perms.EditReply { if tmpl_topic_alt_vars.CurrentUser.Perms.EditReply {
w.Write([]byte(`<a href="/reply/edit/submit/` + strconv.Itoa(item.ID) + `" class="action_button edit_item">Edit</a>`)) w.Write(topic_alt_42)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_alt_43)
} }
w.Write([]byte(`
`))
if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteReply { if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteReply {
w.Write([]byte(`<a href="/reply/delete/submit/` + strconv.Itoa(item.ID) + `" class="action_button delete_item">Delete</a>`)) w.Write(topic_alt_44)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_alt_45)
} }
w.Write([]byte(` w.Write(topic_alt_46)
<a href="/report/submit/` + strconv.Itoa(item.ID) + `?session=` + tmpl_topic_alt_vars.CurrentUser.Session + `&type=reply" class="action_button report_item">Report</a> w.Write([]byte(strconv.Itoa(item.ID)))
</div> w.Write(topic_alt_47)
</div> w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
<div style="clear:both;"></div> w.Write(topic_alt_48)
</div> if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs {
`)) w.Write(topic_alt_49)
w.Write([]byte(item.IpAddress))
w.Write(topic_alt_50)
}
w.Write(topic_alt_51)
} }
} }
w.Write([]byte(`</div> w.Write(topic_alt_52)
`))
if tmpl_topic_alt_vars.CurrentUser.Perms.CreateReply { if tmpl_topic_alt_vars.CurrentUser.Perms.CreateReply {
w.Write([]byte(` w.Write(topic_alt_53)
<div class="rowblock" style="border-top: none;"> w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
<form action="/reply/create/" method="post"> w.Write(topic_alt_54)
<input name="tid" value='` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>
<div class="formrow">
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</button></div>
</div>
</form>
</div>
`))
} }
w.Write([]byte(` w.Write(footer_0)
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`))
} }

View File

@ -1,7 +1,7 @@
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */ /* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main package main
import "io"
import "strconv" import "strconv"
import "io"
func init() { func init() {
template_topics_handle = template_topics template_topics_handle = template_topics
@ -12,93 +12,63 @@ func init() {
} }
func template_topics(tmpl_topics_vars TopicsPage, w io.Writer) { func template_topics(tmpl_topics_vars TopicsPage, w io.Writer) {
w.Write([]byte(`<!doctype html> w.Write(header_0)
<html lang="en"> w.Write([]byte(tmpl_topics_vars.Title))
<head> w.Write(header_1)
<title>` + tmpl_topics_vars.Title + `</title> w.Write([]byte(tmpl_topics_vars.CurrentUser.Session))
<link href="/static/main.css" rel="stylesheet" type="text/css"> w.Write(header_2)
<script type="text/javascript" src="/static/jquery-1.12.3.min.js"></script> w.Write(menu_0)
<script type="text/javascript">
var session = "` + tmpl_topics_vars.CurrentUser.Session + `";
</script>
<script type="text/javascript" src="/static/global.js"></script>
<meta name="viewport" content="width=device-width,initial-scale = 1.0, maximum-scale=1.0,user-scalable=no" />
</head>
<body>
<div class="container">
<div class="nav">
<div class="move_left">
<div class="move_right">
<ul>
<li class="menu_left menu_overview"><a href="/">Overview</a></li>
<li class="menu_left menu_forums"><a href="/forums/">Forums</a></li>
<li class="menu_left menu_topics"><a href="/">Topics</a></li>
<li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li>
`))
if tmpl_topics_vars.CurrentUser.Loggedin { if tmpl_topics_vars.CurrentUser.Loggedin {
w.Write([]byte(` w.Write(menu_1)
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li> w.Write([]byte(strconv.Itoa(tmpl_topics_vars.CurrentUser.ID)))
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_topics_vars.CurrentUser.ID) + `">Profile</a></li> w.Write(menu_2)
`))
if tmpl_topics_vars.CurrentUser.Is_Super_Mod { if tmpl_topics_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>`)) w.Write(menu_3)
} }
w.Write([]byte(` w.Write(menu_4)
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_topics_vars.CurrentUser.Session + `">Logout</a></li> w.Write([]byte(tmpl_topics_vars.CurrentUser.Session))
`)) w.Write(menu_5)
} else { } else {
w.Write([]byte(` w.Write(menu_6)
<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>
`))
} }
w.Write([]byte(` w.Write(menu_7)
</ul> w.Write(header_3)
</div>
</div>
<div style="clear: both;"></div>
</div>
<div id="back"><div id="main">`))
if len(tmpl_topics_vars.NoticeList) != 0 { if len(tmpl_topics_vars.NoticeList) != 0 {
for _, item := range tmpl_topics_vars.NoticeList { for _, item := range tmpl_topics_vars.NoticeList {
w.Write([]byte(`<div class="alert">` + item + `</div>`)) w.Write(header_4)
w.Write([]byte(item))
w.Write(header_5)
} }
} }
w.Write([]byte(` w.Write(topics_0)
<div class="rowblock">
<div class="rowitem rowhead"><a>Topic List</a></div>
</div>
<div class="rowblock">
`))
if len(tmpl_topics_vars.ItemList) != 0 { if len(tmpl_topics_vars.ItemList) != 0 {
for _, item := range tmpl_topics_vars.ItemList { for _, item := range tmpl_topics_vars.ItemList {
w.Write([]byte(`<div class="rowitem passive" style="`)) w.Write(topics_1)
if item.Avatar != "" { if item.Avatar != "" {
w.Write([]byte(`background-image: url(` + item.Avatar + `);background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;`)) w.Write(topics_2)
w.Write([]byte(item.Avatar))
w.Write(topics_3)
} }
if item.Sticky { if item.Sticky {
w.Write([]byte(`background-color: #FFFFCC;`)) w.Write(topics_4)
} else { } else {
if item.Is_Closed { if item.Is_Closed {
w.Write([]byte(`background-color: #eaeaea;`)) w.Write(topics_5)
} }
} }
w.Write([]byte(`"> w.Write(topics_6)
<a href="/topic/` + strconv.Itoa(item.ID) + `">` + item.Title + `</a> `)) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topics_7)
w.Write([]byte(item.Title))
w.Write(topics_8)
if item.Is_Closed { if item.Is_Closed {
w.Write([]byte(`<span class="username topic_status_e topic_status_closed" style="float: right;" title="Status: Closed">&#x1F512;&#xFE0E</span>`)) w.Write(topics_9)
} }
w.Write([]byte(` w.Write(topics_10)
</div>
`))
} }
} else { } else {
w.Write([]byte(`<div class="rowitem passive">There aren't any topics yet.</div>`)) w.Write(topics_11)
} }
w.Write([]byte(` w.Write(topics_12)
</div> w.Write(footer_0)
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`))
} }

View File

@ -1,8 +1,10 @@
package main package main
import "log" import "log"
import "fmt" import "fmt"
import "bytes"
import "strings" import "strings"
import "strconv" import "strconv"
//import "regexp"
import "reflect" import "reflect"
import "path/filepath" import "path/filepath"
import "io/ioutil" import "io/ioutil"
@ -31,6 +33,9 @@ type CTemplateSet struct
dir string dir string
funcMap map[string]interface{} funcMap map[string]interface{}
importMap map[string]string importMap map[string]string
Fragments map[string]int
FragmentCursor map[string]int
FragOut string
varList map[string]VarItem varList map[string]VarItem
localVars map[string]map[string]VarItemReflect localVars map[string]map[string]VarItemReflect
stats map[string]int stats map[string]int
@ -95,6 +100,11 @@ func (c *CTemplateSet) compile_template(name string, dir string, expects string,
c.localVars = make(map[string]map[string]VarItemReflect) c.localVars = make(map[string]map[string]VarItemReflect)
c.localVars[fname] = make(map[string]VarItemReflect) c.localVars[fname] = make(map[string]VarItemReflect)
c.localVars[fname]["."] = VarItemReflect{".",varholder,holdreflect} c.localVars[fname]["."] = VarItemReflect{".",varholder,holdreflect}
if c.Fragments == nil {
c.Fragments = make(map[string]int)
}
c.FragmentCursor = make(map[string]int)
c.FragmentCursor[fname] = 0
subtree := c.tlist[fname] subtree := c.tlist[fname]
if debug { if debug {
@ -135,6 +145,9 @@ func (c *CTemplateSet) compile_template(name string, dir string, expects string,
fout = strings.Replace(fout,`)) fout = strings.Replace(fout,`))
w.Write([]byte(`," + ",-1) w.Write([]byte(`," + ",-1)
fout = strings.Replace(fout,"` + `","",-1) fout = strings.Replace(fout,"` + `","",-1)
//spstr := "`([:space:]*)`"
//whitespace_writes := regexp.MustCompile(`(?s)w.Write\(\[\]byte\(`+spstr+`\)\)`)
//fout = whitespace_writes.ReplaceAllString(fout,"")
for index, count := range c.stats { for index, count := range c.stats {
fmt.Println(index + ": " + strconv.Itoa(count)) fmt.Println(index + ": " + strconv.Itoa(count))
@ -256,7 +269,20 @@ func (c *CTemplateSet) compile_switch(varholder string, holdreflect reflect.Valu
c.previousNode = c.currentNode c.previousNode = c.currentNode
c.currentNode = node.Type() c.currentNode = node.Type()
c.nextNode = 0 c.nextNode = 0
return "w.Write([]byte(`" + string(node.Text) + "`))\n" tmpText := bytes.TrimSpace(node.Text)
if len(tmpText) == 0 {
return ""
} else {
//return "w.Write([]byte(`" + string(node.Text) + "`))\n"
fragment_name := template_name + "_" + strconv.Itoa(c.FragmentCursor[template_name])
_, ok := c.Fragments[fragment_name]
if !ok {
c.Fragments[fragment_name] = len(node.Text)
c.FragOut += "var " + fragment_name + " []byte = []byte(`" + string(node.Text) + "`)\n"
}
c.FragmentCursor[template_name] = c.FragmentCursor[template_name] + 1
return "w.Write(" + fragment_name + ")\n"
}
default: default:
panic("Unknown Node in main switch") panic("Unknown Node in main switch")
} }
@ -670,6 +696,7 @@ func (c *CTemplateSet) compile_subtemplate(pvarholder string, pholdreflect refle
c.localVars[fname] = make(map[string]VarItemReflect) c.localVars[fname] = make(map[string]VarItemReflect)
c.localVars[fname]["."] = VarItemReflect{".",varholder,holdreflect} c.localVars[fname]["."] = VarItemReflect{".",varholder,holdreflect}
c.FragmentCursor[fname] = 0
treeLength := len(subtree.Root.Nodes) treeLength := len(subtree.Root.Nodes)
for index, node := range subtree.Root.Nodes { for index, node := range subtree.Root.Nodes {

View File

@ -7,7 +7,7 @@
{{range .ItemList}} {{range .ItemList}}
<div class="rowitem editable_parent" style="font-weight: normal;"> <div class="rowitem editable_parent" style="font-weight: normal;">
<a class="editable_block" style="font-size: 20px;position:relative;top: -2px;text-transform: none;">{{.Name}}</a> <a class="editable_block" style="font-size: 20px;position:relative;top: -2px;text-transform: none;">{{.Name}}</a>
{{if not (eq .ID 0)}}<span style="float: right;"> {{if ne .ID 0}}<span style="float: right;">
<a href="/panel/forums/edit/submit/{{.ID}}" class="username edit_field">Edit</a> <a href="/panel/forums/edit/submit/{{.ID}}" class="username edit_field">Edit</a>
<a href="/panel/forums/delete/{{.ID}}?session={{$.CurrentUser.Session}}" class="username">Delete</a> <a href="/panel/forums/delete/{{.ID}}?session={{$.CurrentUser.Session}}" class="username">Delete</a>
</span>{{end}} </span>{{end}}

View File

@ -25,21 +25,17 @@
<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><br /><br /> <textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea><br /><br />
<a href="/user/{{.Topic.CreatedBy}}" class="username real_username">{{.Topic.CreatedByName}}</a> <a href="/user/{{.Topic.CreatedBy}}" class="username real_username">{{.Topic.CreatedByName}}</a>
{{if ne .Topic.Level -1}}<a class="username level hide_on_mobile" title="Level {{.Topic.Level}}">L{{.Topic.Level}}</a>{{end}} <a class="username hide_on_micro" {{if .Topic.Tag}}style="float: right;">{{.Topic.Tag}}{{else}}style="color: #505050;float: right;">Level {{.Topic.Level}}{{end}}</a>
{{if .Topic.Tag}}<a class="username hide_on_micro" style="float: right;">{{.Topic.Tag}}</a>{{else if .Topic.URLName}}<a href="{{.Topic.URL}}" class="username" style="color: #505050;float: right;">{{.Topic.URLName}}</a>
<a class="username" style="color: #505050;float: right;border-right: 0;">{{.Topic.URLPrefix}}</a>{{end}}
</div> </div>
</div><br /> </div><br />
<div class="rowblock post_container" style="overflow: hidden;">{{range .ItemList}} <div class="rowblock post_container" style="overflow: hidden;">{{range .ItemList}}
<div class="rowitem rowhead 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 rowhead 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><br /><br /> <p class="editable_block user_content" style="margin: 0;padding: 0;">{{.ContentHtml}}</p><br /><br />
<a href="/user/{{.CreatedBy}}" class="username real_username">{{.CreatedByName}}</a> <a href="/user/{{.CreatedBy}}" class="username real_username">{{.CreatedByName}}</a>
{{if ne .Level -1}}<a class="username level hide_on_mobile" title="Level {{.Level}}">L{{.Level}}</a>{{end}} {{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="mod_button"><button class="username edit_item">Edit</button></a> {{end}}
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="mod_button"><button class="username edit_item">Edit</button></a>{{end}} {{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" class="mod_button"><button class="username delete_item">Delete</button></a> {{end}}
{{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" class="mod_button"><button class="username delete_item">Delete</button></a>{{end}}
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" class="mod_button"><button class="username report_item">Report</button></a> <a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" class="mod_button"><button class="username report_item">Report</button></a>
{{if .Tag}}<a class="username hide_on_micro" style="float: right;">{{.Tag}}</a>{{else if .URLName}}<a href="{{.URL}}" class="username hide_on_mobile" style="color: #505050;float: right;" rel="nofollow">{{.URLName}}</a> <a class="username hide_on_micro" {{if .Tag}}style="float: right;">{{.Tag}}{{else}}style="color: #505050;float: right;">Level {{.Level}}{{end}}</a>
<a class="username hide_on_mobile" style="color: #505050;float: right;border-right: 0;">{{.URLPrefix}}</a>{{end}}
</div> </div>
{{end}}</div> {{end}}</div>
{{if .CurrentUser.Perms.CreateReply}} {{if .CurrentUser.Perms.CreateReply}}

View File

@ -29,10 +29,13 @@
{{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">
<div class="hide_on_edit topic_content user_content nobuttons">{{.Topic.Content}}</div> <div class="hide_on_edit topic_content user_content">{{.Topic.Content}}</div>
<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>
</div> <div class="button_container">
<div style="clear:both;"></div> {{/* Element Queries might help with having to use JS. Unfortunately, the W3C is taking a while with it */}}
{{if $.CurrentUser.Perms.ViewIPs}}<a href="#" class="action_button action_button_right ip_item">{{.Topic.IpAddress}}</a>{{end}}
</div>
</div><div style="clear:both;"></div>
</div> </div>
{{range .ItemList}} {{range .ItemList}}
<div class="rowitem passive deletable_block editable_parent post_item"> <div class="rowitem passive deletable_block editable_parent post_item">
@ -47,6 +50,7 @@
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="action_button edit_item">Edit</a>{{end}} {{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="action_button edit_item">Edit</a>{{end}}
{{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" class="action_button delete_item">Delete</a>{{end}} {{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" class="action_button delete_item">Delete</a>{{end}}
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" class="action_button report_item">Report</a> <a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" class="action_button report_item">Report</a>
{{if $.CurrentUser.Perms.ViewIPs}}<a href="#" class="action_button action_button_right ip_item">{{.IpAddress}}</a>{{end}}
</div> </div>
</div> </div>
<div style="clear:both;"></div> <div style="clear:both;"></div>

View File

@ -517,6 +517,10 @@ blockquote p
padding-left: 5px; padding-left: 5px;
padding-right: 5px; padding-right: 5px;
} }
.action_button_right {
float: right;
border-left: solid 1px #eaeaea;
}
.post_item:not(.simple) { .post_item:not(.simple) {
background-color: #eaeaea; background-color: #eaeaea;

View File

@ -564,6 +564,10 @@ blockquote p
padding-left: 5px; padding-left: 5px;
padding-right: 5px; padding-right: 5px;
} }
.action_button_right {
float: right;
border-left: solid 1px #eaeaea;
}
.post_item:not(.simple) { .post_item:not(.simple) {
background-color: #eaeaea; background-color: #eaeaea;
} }

View File

@ -354,6 +354,10 @@ button.username
padding-left: 5px; padding-left: 5px;
padding-right: 5px; padding-right: 5px;
} }
.action_button_right {
float: right;
border-left: solid 1px #eaeaea;
}
.simple { background-color: white; } .simple { background-color: white; }
.post_item:not(.simple) { .post_item:not(.simple) {

View File

@ -248,11 +248,7 @@ button
color: #505050; /* 80,80,80 */ color: #505050; /* 80,80,80 */
border-radius: 2px; border-radius: 2px;
} }
.topic_status:empty { display: none; }
.topic_status:empty
{
display: none;
}
.username .username
{ {

View File

@ -35,4 +35,6 @@ type TopicUser struct
URLPrefix string URLPrefix string
URLName string URLName string
Level int Level int
IpAddress string
} }

46
user.go
View File

@ -1,6 +1,8 @@
package main package main
//import "fmt"
import "strings" import "strings"
import "strconv" import "strconv"
import "net"
import "net/http" import "net/http"
import "golang.org/x/crypto/bcrypt" import "golang.org/x/crypto/bcrypt"
import "database/sql" import "database/sql"
@ -28,6 +30,7 @@ type User struct
Tag string Tag string
Level int Level int
Score int Score int
Last_IP string
} }
type Email struct type Email struct
@ -70,18 +73,14 @@ func SendValidationEmail(username string, email string, token string) bool {
return SendEmail(email, subject, msg) return SendEmail(email, subject, msg)
} }
func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList map[int]string, success bool) { func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList []string, success bool) {
noticeList = make(map[int]string)
// Are there any session cookies..? // Are there any session cookies..?
// Assign it to user.name to avoid having to create a temporary variable for the type conversion
cookie, err := r.Cookie("uid") cookie, err := r.Cookie("uid")
if err != nil { if err != nil {
user.Perms = GuestPerms user.Perms = GuestPerms
return user, noticeList, true return user, noticeList, true
} }
user.Name = cookie.Value user.ID, err = strconv.Atoi(cookie.Value)
user.ID, err = strconv.Atoi(user.Name)
if err != nil { if err != nil {
user.Perms = GuestPerms user.Perms = GuestPerms
return user, noticeList, true return user, noticeList, true
@ -91,10 +90,9 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList
user.Perms = GuestPerms user.Perms = GuestPerms
return user, noticeList, true return user, noticeList, true
} }
user.Session = cookie.Value
// Is this session valid..? // Is this session valid..?
err = get_session_stmt.QueryRow(user.ID,user.Session).Scan(&user.ID, &user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score) err = get_session_stmt.QueryRow(user.ID,cookie.Value).Scan(&user.ID, &user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
user.ID = 0 user.ID = 0
user.Session = "" user.Session = ""
@ -121,7 +119,7 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList
} }
if user.Is_Banned { if user.Is_Banned {
noticeList[0] = "Your account has been suspended. Some of your permissions may have been revoked." noticeList = append(noticeList, "Your account has been suspended. Some of your permissions may have been revoked.")
} }
if user.Avatar != "" { if user.Avatar != "" {
@ -131,19 +129,26 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList
} else { } else {
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
} }
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
LocalError("Bad IP",w,r,user)
return user, noticeList, false
}
if host != user.Last_IP {
go update_last_ip_stmt.Exec(host, user.ID)
}
return user, noticeList, true return user, noticeList, true
} }
func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, success bool) { func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, success bool) {
// Are there any session cookies..? // Are there any session cookies..?
// Assign it to user.name to avoid having to create a temporary variable for the type conversion
cookie, err := r.Cookie("uid") cookie, err := r.Cookie("uid")
if err != nil { if err != nil {
user.Perms = GuestPerms user.Perms = GuestPerms
return user, true return user, true
} }
user.Name = cookie.Value user.ID, err = strconv.Atoi(cookie.Value)
user.ID, err = strconv.Atoi(user.Name)
if err != nil { if err != nil {
user.Perms = GuestPerms user.Perms = GuestPerms
return user, true return user, true
@ -153,10 +158,9 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, succ
user.Perms = GuestPerms user.Perms = GuestPerms
return user, true return user, true
} }
user.Session = cookie.Value
// Is this session valid..? // Is this session valid..?
err = get_session_stmt.QueryRow(user.ID,user.Session).Scan(&user.ID, &user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score) err = get_session_stmt.QueryRow(user.ID,cookie.Value).Scan(&user.ID, &user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.Email, &user.Avatar, &user.Message, &user.URLPrefix, &user.URLName, &user.Level, &user.Score, &user.Last_IP)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
user.ID = 0 user.ID = 0
user.Session = "" user.Session = ""
@ -189,6 +193,20 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, succ
} else { } else {
user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1) user.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(user.ID),1)
} }
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
LocalError("Bad IP",w,r,user)
return user, false
}
if host != user.Last_IP {
//fmt.Println("Update")
_, err = update_last_ip_stmt.Exec(host, user.ID)
if err != nil {
InternalError(err,w,r,user)
return user, false
}
}
return user, true return user, true
} }