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_*
bin/*
gosora.exe
gosora.test.exe
install.exe
*.prof

View File

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

View File

@ -32,3 +32,4 @@ var ssl_fullchain = ""
// Developer flag
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 themes(`uname`,`default`) VALUES ('tempra-simple',1);
INSERT INTO users(`name`,`password`,`email`,`group`,`is_super_admin`,`createdAt`,`lastActiveAt`,`message`)
VALUES ('Admin','password','admin@localhost',1,1,NOW(),NOW(),'');
INSERT INTO users(`name`,`password`,`email`,`group`,`is_super_admin`,`createdAt`,`lastActiveAt`,`message`,`last_ip`)
VALUES ('Admin','password','admin@localhost',1,1,NOW(),NOW(),'','127.0.0.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 "net/http"
func InternalError(err error, w http.ResponseWriter, r *http.Request, user User) {
log.Fatal(err)
pi := Page{"Internal Server Error","error",user,nList,tList,"A problem has occured in the system."}
var error_internal []byte
var error_notfound []byte
func init_errors() error {
var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(500)
fmt.Fprintln(w,errpage)
user := User{0,"Guest","",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"0.0.0.0.0"}
pi := Page{"Internal Server Error",user,nList,tList,"A problem has occurred in the system."}
err := templates.ExecuteTemplate(&b,"error.html", pi)
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) {
log.Fatal(err)
errmsg := "A problem has occured in the system."
w.WriteHeader(500)
if is_js == "0" {
pi := Page{"Internal Server Error","error",user,nList,tList,errmsg}
var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(500)
fmt.Fprintln(w,errpage)
w.Write(error_internal)
} 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) {
pi := Page{"Local Error","error",user,nList,tList,errmsg}
w.WriteHeader(500)
pi := Page{"Local Error",user,nList,tList,errmsg}
var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(500)
fmt.Fprintln(w,errpage)
fmt.Fprintln(w,b.String())
}
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
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(401)
fmt.Fprintln(w,errpage)
fmt.Fprintln(w,b.String())
}
func LocalErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, user User, is_js string) {
w.WriteHeader(500)
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
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(500)
fmt.Fprintln(w,errpage)
fmt.Fprintln(w,b.String())
} else {
http.Error(w,"{'errmsg': '" + errmsg + "'}",500)
w.Write([]byte(`{'errmsg': '` + errmsg + `'}`))
}
}
func NoPermissions(w http.ResponseWriter, r *http.Request, user User) {
errmsg := "You don't have permission to do that."
pi := Page{"Local Error","error",user,nList,tList,errmsg}
w.WriteHeader(403)
pi := Page{"Local Error",user,nList,tList,"You don't have permission to do that."}
var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(403)
fmt.Fprintln(w,errpage)
}
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" {
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
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(403)
fmt.Fprintln(w,errpage)
fmt.Fprintln(w,b.String())
} 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) {
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
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(403)
fmt.Fprintln(w,errpage)
fmt.Fprintln(w,b.String())
}
func BannedJSQ(w http.ResponseWriter, r *http.Request, user User, is_js string) {
w.WriteHeader(403)
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
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(403)
fmt.Fprintln(w,errpage)
fmt.Fprintln(w,b.String())
} 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) {
w.WriteHeader(401)
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
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(401)
fmt.Fprintln(w,errpage)
fmt.Fprintln(w,b.String())
} 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) {
errmsg := "There was a security issue with your request."
pi := Page{"Security Error","error",user,nList,tList,errmsg}
w.WriteHeader(403)
pi := Page{"Security Error",user,nList,tList,"There was a security issue with your request."}
var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(403)
fmt.Fprintln(w,errpage)
fmt.Fprintln(w,b.String())
}
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)
fmt.Fprintln(w,errpage)
w.Write(error_notfound)
}
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
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(errcode)
fmt.Fprintln(w,errpage)
fmt.Fprintln(w,b.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" {
pi := Page{errtitle,"error",user,nList,tList,errmsg}
pi := Page{errtitle,user,nList,tList,errmsg}
var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(errcode)
fmt.Fprintln(w,errpage)
fmt.Fprintln(w,b.String())
} 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)
}
var plugins_inited bool = false
func init_plugins() {
for name, body := range plugins {
log.Print("Added plugin " + name)
@ -86,6 +87,7 @@ func init_plugins() {
plugins[name].Init()
}
}
plugins_inited = true
}
func run_hook(name string, data interface{}) interface{} {

View File

@ -1,4 +1,5 @@
package main
import "os"
import "log"
import "bytes"
import "strconv"
@ -8,29 +9,50 @@ import "net/http"
import "net/http/httptest"
import "io/ioutil"
import "html/template"
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
//import "github.com/husobee/vestigo"
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) {
b.ReportAllocs()
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0}
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58}
var noticeList map[int]string = make(map[int]string)
noticeList[0] = "test"
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"127.0.0.1"}
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58,"127.0.0.1"}
noticeList := []string{"test"}
topic := TopicUser{Title: "Lol",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58}
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
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})
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})
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})
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})
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})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
tpage := TopicPage{"Topic Blah",user,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)
}
})
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) {
b.ReportAllocs()
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0}
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58}
var noticeList map[int]string = make(map[int]string)
noticeList[0] = "test"
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"127.0.0.1"}
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","","",-1,58,"127.0.0.1"}
noticeList := []string{"test"}
var topicList []TopicUser
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58})
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})
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})
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})
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})
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, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
topicList = append(topicList, TopicUser{Title: "Hey everyone!",Content: template.HTML("Hey everyone!"),CreatedBy: 1,CreatedAt: "0000-00-00 00:00:00",ParentID: 1,CreatedByName:"Admin",Css: no_css_tmpl,Tag: "Admin", Level: 58, IpAddress: "127.0.0.1"})
tpage := TopicsPage{"Topic Blah",user,noticeList,topicList,0}
tpage2 := TopicsPage{"Topic Blah",admin,noticeList,topicList,0}
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) {
for i := 0; i < b.N; i++ {
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++ {
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++ {
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++ {
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()
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}
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_req := httptest.NewRequest("get","/topic/1",bytes.NewReader(nil))
topic_req_admin := topic_req
@ -139,32 +353,31 @@ func BenchmarkRoute(b *testing.B) {
forums_req_admin.AddCookie(&admin_session_cookie)
forums_handler := http.HandlerFunc(route_forums)
static_w := httptest.NewRecorder()
static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil))
static_handler := http.HandlerFunc(route_static)
if !gloinited {
gloinit()
}
debug = false
nogrouplog = true
/*f, err := os.Create("routes_bench_cpu.prof")
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)*/
//defer pprof.StopCPUProfile()
//pprof.StopCPUProfile()
// init_database is a little noisy for a benchmark
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) {
b.Run("static_recorder", func(b *testing.B) {
for i := 0; i < b.N; i++ {
static_w.Body.Reset()
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++ {
//topic_w.Code = 200
topic_w.Body.Reset()
@ -174,55 +387,258 @@ func BenchmarkRoute(b *testing.B) {
// 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++ {
//topic_w.Code = 200
topic_w.Body.Reset()
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++ {
//topics_w.Code = 200
topics_w.Body.Reset()
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++ {
//topics_w.Code = 200
topics_w.Body.Reset()
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++ {
//forum_w.Code = 200
forum_w.Body.Reset()
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++ {
//forum_w.Code = 200
forum_w.Body.Reset()
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++ {
//forums_w.Code = 200
forums_w.Body.Reset()
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++ {
//forums_w.Code = 200
forums_w.Body.Reset()
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"
"os"
"html/template"
//"runtime/pprof"
)
const hour int = 60 * 60
@ -41,15 +42,14 @@ var template_profile_handle func(ProfilePage,io.Writer) = nil
func compile_templates() {
var c CTemplateSet
user := User{62,"","compiler@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0}
var noticeList map[int]string = make(map[int]string)
noticeList[0] = "test"
user := User{62,"","compiler@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","","",0,0,"0.0.0.0.0"}
noticeList := []string{"test"}
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
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)
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)
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_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)
log.Print("Writing the templates")
write_template("topic", topic_id_tmpl)
write_template("topic_alt", topic_id_alt_tmpl)
write_template("profile", profile_tmpl)
write_template("forums", forums_tmpl)
write_template("topics", topics_tmpl)
write_template("forum", forum_tmpl)
go write_template("topic", topic_id_tmpl)
go write_template("topic_alt", topic_id_alt_tmpl)
go write_template("profile", profile_tmpl)
go write_template("forums", forums_tmpl)
go write_template("topics", topics_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) {
@ -92,10 +93,24 @@ func write_template(name string, content string) {
}
func main(){
//if profiling {
// f, err := os.Create("startup_cpu.prof")
// if err != nil {
// log.Fatal(err)
// }
// pprof.StartCPUProfile(f)
//}
init_themes()
var err error
init_database(err)
compile_templates()
db.SetMaxOpenConns(64)
err = init_errors()
if err != nil {
log.Fatal(err)
}
log.Print("Loading the static files.")
err = filepath.Walk("./public", func(path string, f os.FileInfo, err error) error {
@ -122,7 +137,6 @@ func main(){
hooks["trow_assign"] = nil
hooks["rrow_assign"] = nil
templates.ParseGlob("pages/*")
init_plugins()
router := NewRouter()
@ -199,10 +213,15 @@ func main(){
router.HandleFunc("/panel/users/edit/", route_panel_users_edit)
router.HandleFunc("/panel/users/edit/submit/", route_panel_users_edit_submit)
router.HandleFunc("/panel/groups/", route_panel_groups)
//router.HandleFunc("/exit/", route_exit)
router.HandleFunc("/", default_route)
defer db.Close()
//if profiling {
// pprof.StopCPUProfile()
//}
if !enable_ssl {
if server_port == "" {
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 + "'?"
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)
}
@ -550,7 +550,7 @@ func route_panel(w http.ResponseWriter, r *http.Request){
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)
}
@ -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)
}
@ -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?"
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)
}
@ -779,7 +779,7 @@ func route_panel_settings(w http.ResponseWriter, r *http.Request){
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)
}
@ -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)
}
@ -904,7 +904,7 @@ func route_panel_plugins(w http.ResponseWriter, r *http.Request){
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)
}
@ -1075,7 +1075,7 @@ func route_panel_users(w http.ResponseWriter, r *http.Request){
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)
if err != nil {
InternalError(err, w, r, user)
@ -1129,7 +1129,7 @@ func route_panel_users_edit(w http.ResponseWriter, r *http.Request){
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)
if err != nil {
InternalError(err, w, r, user)
@ -1246,7 +1246,7 @@ func route_panel_groups(w http.ResponseWriter, r *http.Request){
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)
}
@ -1265,7 +1265,7 @@ func route_panel_themes(w http.ResponseWriter, r *http.Request){
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)
if err != nil {
log.Print(err)

View File

@ -10,6 +10,9 @@ import "encoding/json"
var db *sql.DB
var get_session_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_report_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 stick_topic_stmt *sql.Stmt
var unstick_topic_stmt *sql.Stmt
var update_last_ip_stmt *sql.Stmt
var login_stmt *sql.Stmt
var update_session_stmt *sql.Stmt
var logout_stmt *sql.Stmt
@ -70,7 +74,7 @@ func init_database(err error) {
}
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 {
log.Fatal(err)
}
@ -81,8 +85,26 @@ func init_database(err error) {
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.")
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 {
log.Fatal(err)
}
@ -94,7 +116,7 @@ func init_database(err error) {
}
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 {
log.Fatal(err)
}
@ -141,6 +163,12 @@ func init_database(err error) {
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.")
login_stmt, err = db.Prepare("SELECT `uid`, `name`, `password`, `salt` FROM `users` WHERE `name` = ?")
if err != nil {

View File

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

View File

@ -3,9 +3,15 @@ package main
//import "fmt"
import "bytes"
//import "strings"
import "strconv"
import "regexp"
import "time"
import "math/rand"
var random *rand.Rand
var bbcode_invalid_url []byte
var bbcode_invalid_number []byte
var bbcode_missing_tag []byte
var bbcode_url_open []byte
var bbcode_url_open2 []byte
var bbcode_url_close []byte
@ -25,6 +31,8 @@ func init_bbcode() {
plugins["bbcode"].AddHook("parse_assign", bbcode_full_parse)
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_open2 = []byte("'>")
bbcode_url_close = []byte("</a>")
@ -36,6 +44,8 @@ func init_bbcode() {
urlpattern := `(http|https|ftp|mailto*)(:??)\/\/([\.a-zA-Z\/]+)`
bbcode_url = regexp.MustCompile(`\[url\]` + urlpattern + `\[/url\]`)
bbcode_url_label = regexp.MustCompile(`(?s)\[url=` + urlpattern + `\](.*)\[/url\]`)
random = rand.New(rand.NewSource(time.Now().UnixNano()))
}
func deactivate_bbcode() {
@ -62,7 +72,7 @@ func bbcode_simple_parse(data interface{}) interface{} {
has_b := false
has_i := 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 + 1] == 'b' {
msgbytes[i] = '<'
@ -102,7 +112,7 @@ func bbcode_parse_without_code(data interface{}) interface{} {
has_i := false
has_s := 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 + 2] != ']' {
if msgbytes[i + 1] == '/' {
@ -177,7 +187,7 @@ func bbcode_full_parse(data interface{}) interface{} {
has_s := false
has_c := 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 + 2] != ']' {
if msgbytes[i + 1] == '/' {
@ -249,20 +259,21 @@ func bbcode_full_parse(data interface{}) interface{} {
var start int
var lastTag int
outbytes := make([]byte, len(msgbytes))
//fmt.Println(string(msgbytes))
for i := 0; i < len(msgbytes); i++ {
MainLoop:
if msgbytes[i] == '[' {
OuterComplex:
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]...)
start = i + 5
i = start
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://")) {
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
} else {
outbytes = append(outbytes, bbcode_invalid_url...)
@ -270,16 +281,17 @@ func bbcode_full_parse(data interface{}) interface{} {
}
}
} 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
}
}
for ;; 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!")
//fmt.Println(msgbytes[i + 1:i + 6])
outbytes = append(outbytes, bbcode_missing_tag...)
goto OuterComplex
}
break
@ -288,6 +300,9 @@ func bbcode_full_parse(data interface{}) interface{} {
//log.Print("Weird character")
//fmt.Println(msgbytes[i])
goto MainLoop
} else if (len(msgbytes) - 1) < (i + 6) {
outbytes = append(outbytes, bbcode_missing_tag...)
goto OuterComplex
}
}
outbytes = append(outbytes, bbcode_url_open...)
@ -298,9 +313,41 @@ func bbcode_full_parse(data interface{}) interface{} {
i += 6
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 {
return string(outbytes)
}
@ -313,4 +360,4 @@ func bbcode_full_parse(data interface{}) interface{} {
msg = string(msgbytes)
}
return msg
}
}

View File

@ -15,7 +15,6 @@ $(document).ready(function(){
$(".open_edit").click(function(event){
console.log("Clicked on edit");
event.preventDefault();
$(".hide_on_edit").hide();
$(".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
URLName string
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] == '/' {
w.WriteHeader(404)
w.Write([]byte(""))
w.Write(error_notfound)
return
}
@ -61,6 +61,6 @@ func (router *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
w.WriteHeader(404)
w.Write([]byte(""))
w.Write(error_notfound)
return
}

178
routes.go
View File

@ -10,6 +10,7 @@ import "strings"
import "time"
import "io"
import "os"
import "net"
import "net/http"
import "html"
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
var tList []interface{}
var nList map[int]string
var nList []string
// GET functions
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)
}
/*func route_exit(w http.ResponseWriter, r *http.Request){
db.Close()
os.Exit(0)
}*/
func route_fstatic(w http.ResponseWriter, r *http.Request){
http.ServeFile(w, r, r.URL.Path)
}
@ -56,8 +62,7 @@ func route_overview(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
pi := Page{"Overview","overview",user,noticeList,tList,0}
pi := Page{"Overview",user,noticeList,tList,nil}
err := templates.ExecuteTemplate(w,"overview.html", pi)
if err != nil {
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/"):]
if templates.Lookup("page_" + name) == nil {
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)
if err != nil {
InternalError(err, w, r, user)
@ -98,7 +104,6 @@ func route_topics(w http.ResponseWriter, r *http.Request){
InternalError(err,w,r,user)
return
}
defer rows.Close()
topicItem := TopicUser{ID: 0,}
for rows.Next() {
@ -126,8 +131,9 @@ func route_topics(w http.ResponseWriter, r *http.Request){
InternalError(err,w,r,user)
return
}
rows.Close()
pi := TopicsPage{"Topic List",user,noticeList,topicList,0}
pi := TopicsPage{"Topic List",user,noticeList,topicList,nil}
if template_topics_handle != nil {
template_topics_handle(pi,w)
} else {
@ -145,7 +151,6 @@ func route_forum(w http.ResponseWriter, r *http.Request){
}
var topicList []TopicUser
fid, err := strconv.Atoi(r.URL.Path[len("/forum/"):])
if err != nil {
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
}
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 {
InternalError(err,w,r,user)
return
}
defer rows.Close()
topicItem := TopicUser{ID: 0}
for rows.Next() {
@ -195,8 +199,9 @@ func route_forum(w http.ResponseWriter, r *http.Request){
InternalError(err,w,r,user)
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 {
template_forum_handle(pi,w)
} 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 {
template_forums_handle(pi,w)
} else {
err := templates.ExecuteTemplate(w,"forums.html", pi)
err := templates.ExecuteTemplate(w,"forums.html",pi)
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(
err error
rid int
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
group int
replyList []Reply
)
@ -274,7 +263,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
}
// 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 {
NotFound(w,r,user)
return
@ -302,11 +291,9 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
topic.Css = staff_css_tmpl
topic.Level = -1
}
//if groups[group].Tag != "" {
topic.Tag = groups[group].Tag
//} else {
// topic.Tag = ""
//}
topic.Tag = groups[group].Tag
if settings["url_tags"] == false {
topic.URLName = ""
} else {
@ -314,56 +301,54 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
if !ok {
topic.URL = topic.URLName
} else {
topic.URL = replyURL + topic.URLName
topic.URL = topic.URL + topic.URLName
}
}
// 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 {
InternalError(err,w,r,user)
return
}
defer rows.Close()
replyItem := Reply{Css: no_css_tmpl}
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 {
InternalError(err,w,r,user)
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 {
replyCss = staff_css_tmpl
replyLevel = -1
replyItem.Css = staff_css_tmpl
replyItem.Level = -1
} else {
replyCss = no_css_tmpl
replyItem.Css = no_css_tmpl
}
if replyAvatar != "" {
if replyAvatar[0] == '.' {
replyAvatar = "/uploads/avatar_" + strconv.Itoa(replyCreatedBy) + replyAvatar
if replyItem.Avatar != "" {
if replyItem.Avatar[0] == '.' {
replyItem.Avatar = "/uploads/avatar_" + strconv.Itoa(replyItem.CreatedBy) + replyItem.Avatar
}
} else {
replyAvatar = strings.Replace(noavatar,"{id}",strconv.Itoa(replyCreatedBy),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.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(replyItem.CreatedBy),1)
}
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 {
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)
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 {
template_topic_handle(tpage,w)
} else {
@ -424,7 +410,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
puser = user
} else {
// 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 {
NotFound(w,r,user)
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
//} else {
// puser.Tag = ""
//}
puser.Tag = groups[puser.Group].Tag
if puser.Avatar != "" {
if puser.Avatar[0] == '.' {
@ -492,7 +474,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
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()
if err != nil {
@ -520,7 +502,7 @@ func route_topic_create(w http.ResponseWriter, r *http.Request){
NoPermissions(w,r,user)
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)
}
@ -542,8 +524,13 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
}
topic_name := html.EscapeString(r.PostFormValue("topic-name"))
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 {
InternalError(err,w,r,user)
return
@ -591,8 +578,13 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
}
content := preparse_message(html.EscapeString(r.PostFormValue("reply-content")))
//log.Print(content)
_, err = create_reply_stmt.Exec(tid,content,parse_message(content),user.ID)
ipaddress, _, err := net.SplitHostPort(r.RemoteAddr)
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 {
InternalError(err,w,r,user)
return
@ -799,7 +791,7 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
if success != 1 {
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
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)
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)
}
@ -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"
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)
}
@ -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)
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)
}
@ -977,9 +969,9 @@ func route_account_own_edit_avatar_submit(w http.ResponseWriter, r *http.Request
return
}
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)
}
@ -993,7 +985,7 @@ func route_account_own_edit_username(w http.ResponseWriter, r *http.Request) {
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)
}
@ -1020,8 +1012,8 @@ func route_account_own_edit_username_submit(w http.ResponseWriter, r *http.Reque
}
user.Name = new_username
noticeList[len(noticeList)] = "Your username was successfully updated"
pi := Page{"Edit Username","account-own-edit-username",user,noticeList,tList,0}
noticeList = append(noticeList,"Your username was successfully updated")
pi := Page{"Edit Username",user,noticeList,tList,0}
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}
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 {
log.Fatal(err)
}
@ -1068,9 +1060,9 @@ func route_account_own_edit_email(w http.ResponseWriter, r *http.Request) {
}
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)
}
@ -1088,7 +1080,7 @@ func route_account_own_edit_email_token_submit(w http.ResponseWriter, r *http.Re
email := Email{UserID: user.ID}
targetEmail := Email{UserID: user.ID}
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 {
log.Fatal(err)
}
@ -1138,10 +1130,10 @@ func route_account_own_edit_email_token_submit(w http.ResponseWriter, r *http.Re
}
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"
pi := Page{"Email Manager","account-own-edit-email",user,noticeList,emailList,0}
noticeList = append(noticeList,"Your email was successfully verified")
pi := Page{"Email Manager",user,noticeList,emailList,0}
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)
return
}
pi := Page{"Login","login",user,noticeList,tList,0}
pi := Page{"Login",user,noticeList,tList,0}
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)
return
}
pi := Page{"Registration","register",user,noticeList,tList,0}
pi := Page{"Registration",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"register.html", pi)
}

10
run.bat
View File

@ -1,8 +1,18 @@
@echo off
echo Generating the dynamic code
go generate
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Building the executable
go build
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Running Gosora
gosora.exe
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. */
package main
import "strconv"
import "io"
import "strconv"
func init() {
template_forum_handle = template_forum
@ -12,93 +12,65 @@ func init() {
}
func template_forum(tmpl_forum_vars ForumPage, w io.Writer) {
w.Write([]byte(`<!doctype html>
<html lang="en">
<head>
<title>` + tmpl_forum_vars.Title + `</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 = "` + 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>
`))
w.Write(header_0)
w.Write([]byte(tmpl_forum_vars.Title))
w.Write(header_1)
w.Write([]byte(tmpl_forum_vars.CurrentUser.Session))
w.Write(header_2)
w.Write(menu_0)
if tmpl_forum_vars.CurrentUser.Loggedin {
w.Write([]byte(`
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_forum_vars.CurrentUser.ID) + `">Profile</a></li>
`))
w.Write(menu_1)
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.CurrentUser.ID)))
w.Write(menu_2)
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(`
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_forum_vars.CurrentUser.Session + `">Logout</a></li>
`))
w.Write(menu_4)
w.Write([]byte(tmpl_forum_vars.CurrentUser.Session))
w.Write(menu_5)
} else {
w.Write([]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>
`))
w.Write(menu_6)
}
w.Write([]byte(`
</ul>
</div>
</div>
<div style="clear: both;"></div>
</div>
<div id="back"><div id="main">`))
w.Write(menu_7)
w.Write(header_3)
if len(tmpl_forum_vars.NoticeList) != 0 {
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(`
<div class="rowblock">
<div class="rowitem rowhead"><a>` + tmpl_forum_vars.Title + `</a></div>
</div>
<div class="rowblock">
`))
w.Write(forum_0)
w.Write([]byte(tmpl_forum_vars.Title))
w.Write(forum_1)
if len(tmpl_forum_vars.ItemList) != 0 {
for _, item := range tmpl_forum_vars.ItemList {
w.Write([]byte(`<div class="rowitem passive" style="`))
w.Write(forum_2)
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 {
w.Write([]byte(`background-color: #FFFFCC;`))
w.Write(forum_5)
} else {
if item.Is_Closed {
w.Write([]byte(`background-color: #eaeaea;`))
w.Write(forum_6)
}
}
w.Write([]byte(`">
<a href="/topic/` + strconv.Itoa(item.ID) + `">` + item.Title + `</a> `))
w.Write(forum_7)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(forum_8)
w.Write([]byte(item.Title))
w.Write(forum_9)
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(`
</div>
`))
w.Write(forum_11)
}
} 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(`
</div>
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`))
w.Write(forum_13)
w.Write(footer_0)
}

View File

@ -12,76 +12,52 @@ func init() {
}
func template_forums(tmpl_forums_vars ForumsPage, w io.Writer) {
w.Write([]byte(`<!doctype html>
<html lang="en">
<head>
<title>` + tmpl_forums_vars.Title + `</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 = "` + 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>
`))
w.Write(header_0)
w.Write([]byte(tmpl_forums_vars.Title))
w.Write(header_1)
w.Write([]byte(tmpl_forums_vars.CurrentUser.Session))
w.Write(header_2)
w.Write(menu_0)
if tmpl_forums_vars.CurrentUser.Loggedin {
w.Write([]byte(`
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_forums_vars.CurrentUser.ID) + `">Profile</a></li>
`))
w.Write(menu_1)
w.Write([]byte(strconv.Itoa(tmpl_forums_vars.CurrentUser.ID)))
w.Write(menu_2)
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(`
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_forums_vars.CurrentUser.Session + `">Logout</a></li>
`))
w.Write(menu_4)
w.Write([]byte(tmpl_forums_vars.CurrentUser.Session))
w.Write(menu_5)
} else {
w.Write([]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>
`))
w.Write(menu_6)
}
w.Write([]byte(`
</ul>
</div>
</div>
<div style="clear: both;"></div>
</div>
<div id="back"><div id="main">`))
w.Write(menu_7)
w.Write(header_3)
if len(tmpl_forums_vars.NoticeList) != 0 {
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(`
<div class="rowblock">
`))
w.Write(forums_0)
if len(tmpl_forums_vars.ItemList) != 0 {
for _, item := range tmpl_forums_vars.ItemList {
w.Write([]byte(`<div class="rowitem">
<a href="/forum/` + strconv.Itoa(item.ID) + `" style="font-size: 20px;position:relative;top: -2px;font-weight: normal;text-transform: none;">` + item.Name + `</a>
<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>
</div>
`))
w.Write(forums_1)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(forums_2)
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 {
w.Write([]byte(`<div class="rowitem passive">You don't have access to any forums.</div>`))
w.Write(forums_7)
}
w.Write([]byte(`
</div>
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`))
w.Write(forums_8)
w.Write(footer_0)
}

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) {
w.Write([]byte(`<!doctype html>
<html lang="en">
<head>
<title>` + tmpl_profile_vars.Title + `</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 = "` + 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>
`))
w.Write(header_0)
w.Write([]byte(tmpl_profile_vars.Title))
w.Write(header_1)
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
w.Write(header_2)
w.Write(menu_0)
if tmpl_profile_vars.CurrentUser.Loggedin {
w.Write([]byte(`
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_profile_vars.CurrentUser.ID) + `">Profile</a></li>
`))
w.Write(menu_1)
w.Write([]byte(strconv.Itoa(tmpl_profile_vars.CurrentUser.ID)))
w.Write(menu_2)
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(`
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_profile_vars.CurrentUser.Session + `">Logout</a></li>
`))
w.Write(menu_4)
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
w.Write(menu_5)
} else {
w.Write([]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>
`))
w.Write(menu_6)
}
w.Write([]byte(`
</ul>
</div>
</div>
<div style="clear: both;"></div>
</div>
<div id="back"><div id="main">`))
w.Write(menu_7)
w.Write(header_3)
if len(tmpl_profile_vars.NoticeList) != 0 {
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(`
<div class="colblock_left" style="max-width: 220px;">
<div class="rowitem" style="padding: 0;"><img src="` + tmpl_profile_vars.ProfileOwner.Avatar + `" style="max-width: 100%;margin: 0;display: block;" /></div>
<div class="rowitem" style="text-transform: capitalize;">
<span style="font-size: 18px;">` + tmpl_profile_vars.ProfileOwner.Name + `</span>`))
w.Write(profile_0)
w.Write([]byte(tmpl_profile_vars.ProfileOwner.Avatar))
w.Write(profile_1)
w.Write([]byte(tmpl_profile_vars.ProfileOwner.Name))
w.Write(profile_2)
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(`
</div>
<div class="rowitem passive">
<a class="username">Add Friend</a>
`))
w.Write(profile_5)
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 {
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 {
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(`
<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>
</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;">`))
w.Write(profile_12)
w.Write([]byte(strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID)))
w.Write(profile_13)
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
w.Write(profile_14)
if len(tmpl_profile_vars.ItemList) != 0 {
for _, item := range tmpl_profile_vars.ItemList {
w.Write([]byte(`
<div class="rowitem passive deletable_block editable_parent simple" style="`))
w.Write(profile_15)
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 {
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(`">
<span class="editable_block user_content simple">` + string(item.ContentHtml) + `</span>
<br /><br />
<a href="/user/` + strconv.Itoa(item.CreatedBy) + `" class="username">` + item.CreatedByName + `</a>
`))
w.Write(profile_20)
w.Write([]byte(string(item.ContentHtml)))
w.Write(profile_21)
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 {
w.Write([]byte(`<a href="/profile/reply/edit/submit/` + strconv.Itoa(item.ID) + `"><button class="username edit_item">Edit</button></a>
<a href="/profile/reply/delete/submit/` + strconv.Itoa(item.ID) + `"><button class="username delete_item">Delete</button></a>`))
w.Write(profile_24)
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(`
<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(profile_27)
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 != "" {
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(`
</div>
`))
w.Write(profile_32)
}
}
w.Write([]byte(`</div>
<div class="colblock_right" style="border-top: none;">
`))
w.Write(profile_33)
if !tmpl_profile_vars.CurrentUser.Is_Banned {
w.Write([]byte(`
<form action="/profile/reply/create/" method="post">
<input name="uid" value='` + strconv.Itoa(tmpl_profile_vars.ProfileOwner.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>
`))
w.Write(profile_34)
w.Write([]byte(strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID)))
w.Write(profile_35)
}
w.Write([]byte(`
</div>
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`))
w.Write(profile_36)
w.Write(footer_0)
}

View File

@ -13,197 +13,151 @@ func init() {
}
func template_topic(tmpl_topic_vars TopicPage, w io.Writer) {
w.Write([]byte(`<!doctype html>
<html lang="en">
<head>
<title>` + tmpl_topic_vars.Title + `</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 = "` + 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>
`))
w.Write(header_0)
w.Write([]byte(tmpl_topic_vars.Title))
w.Write(header_1)
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
w.Write(header_2)
w.Write(menu_0)
if tmpl_topic_vars.CurrentUser.Loggedin {
w.Write([]byte(`
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_topic_vars.CurrentUser.ID) + `">Profile</a></li>
`))
w.Write(menu_1)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.CurrentUser.ID)))
w.Write(menu_2)
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(`
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_topic_vars.CurrentUser.Session + `">Logout</a></li>
`))
w.Write(menu_4)
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
w.Write(menu_5)
} else {
w.Write([]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>
`))
w.Write(menu_6)
}
w.Write([]byte(`
</ul>
</div>
</div>
<div style="clear: both;"></div>
</div>
<div id="back"><div id="main">`))
w.Write(menu_7)
w.Write(header_3)
if len(tmpl_topic_vars.NoticeList) != 0 {
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(`
<div class="rowblock">
<form action='/topic/edit/submit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' method="post">
<div class="rowitem"`))
w.Write(topic_0)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_1)
if tmpl_topic_vars.Topic.Sticky {
w.Write([]byte(` style="background-color: #FFFFEA;"`))
w.Write(topic_2)
} else {
if tmpl_topic_vars.Topic.Is_Closed {
w.Write([]byte(` style="background-color: #eaeaea;"`))
w.Write(topic_3)
}
}
w.Write([]byte(`>
<a class='topic_name hide_on_edit'>` + tmpl_topic_vars.Topic.Title + `</a>
`))
w.Write(topic_4)
w.Write([]byte(tmpl_topic_vars.Topic.Title))
w.Write(topic_5)
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 {
w.Write([]byte(`
<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>
<a href='/topic/delete/submit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' class="username" style="font-weight: normal;">Delete</a>
`))
w.Write(topic_7)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_8)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_9)
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 {
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(`
<input class='show_on_edit topic_name_input' name="topic_name" value='` + tmpl_topic_vars.Topic.Title + `' 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>
`))
w.Write(topic_14)
w.Write([]byte(tmpl_topic_vars.Topic.Title))
w.Write(topic_15)
}
w.Write([]byte(`
<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>
</div>
</form>
</div>
<div class="rowblock post_container">
<div class="rowitem passive editable_parent post_item" style="border-bottom: none;`))
w.Write(topic_16)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_17)
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
w.Write(topic_18)
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 {
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(`">
<p class="hide_on_edit topic_content user_content" style="margin: 0;padding: 0;">` + string(tmpl_topic_vars.Topic.Content.(template.HTML)) + `</p>
<textarea name="topic_content" class="show_on_edit topic_content_input">` + string(tmpl_topic_vars.Topic.Content.(template.HTML)) + `</textarea><br /><br />
<a href="/user/` + strconv.Itoa(tmpl_topic_vars.Topic.CreatedBy) + `" class="username real_username">` + tmpl_topic_vars.Topic.CreatedByName + `</a>
`))
if tmpl_topic_vars.Topic.Level != -1 {
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([]byte(`
`))
w.Write(topic_23)
w.Write([]byte(string(tmpl_topic_vars.Topic.Content.(template.HTML))))
w.Write(topic_24)
w.Write([]byte(string(tmpl_topic_vars.Topic.Content.(template.HTML))))
w.Write(topic_25)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.CreatedBy)))
w.Write(topic_26)
w.Write([]byte(tmpl_topic_vars.Topic.CreatedByName))
w.Write(topic_27)
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 {
if tmpl_topic_vars.Topic.URLName != "" {
w.Write([]byte(`<a href="` + tmpl_topic_vars.Topic.URL + `" class="username" style="color: #505050;float: right;">` + tmpl_topic_vars.Topic.URLName + `</a>
<a class="username" style="color: #505050;float: right;border-right: 0;">` + tmpl_topic_vars.Topic.URLPrefix + `</a>`))
w.Write(topic_29)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.Level)))
}
}
w.Write([]byte(`
</div>
</div><br />
<div class="rowblock post_container" style="overflow: hidden;">`))
w.Write(topic_30)
if len(tmpl_topic_vars.ItemList) != 0 {
for _, item := range tmpl_topic_vars.ItemList {
w.Write([]byte(`
<div class="rowitem rowhead passive deletable_block editable_parent post_item" style="`))
w.Write(topic_31)
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 {
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(`">
<p class="editable_block user_content" style="margin: 0;padding: 0;">` + string(item.ContentHtml) + `</p><br /><br />
<a href="/user/` + strconv.Itoa(item.CreatedBy) + `" class="username real_username">` + item.CreatedByName + `</a>
`))
if item.Level != -1 {
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(`
`))
w.Write(topic_36)
w.Write([]byte(string(item.ContentHtml)))
w.Write(topic_37)
w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(topic_38)
w.Write([]byte(item.CreatedByName))
w.Write(topic_39)
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 {
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(`
<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(topic_44)
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 != "" {
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 {
if item.URLName != "" {
w.Write([]byte(`<a href="` + item.URL + `" class="username hide_on_mobile" style="color: #505050;float: right;" rel="nofollow">` + item.URLName + `</a>
<a class="username hide_on_mobile" style="color: #505050;float: right;border-right: 0;">` + item.URLPrefix + `</a>`))
w.Write(topic_48)
w.Write([]byte(strconv.Itoa(item.Level)))
}
w.Write(topic_49)
}
}
w.Write([]byte(`
</div>
`))
}
}
w.Write([]byte(`</div>
`))
w.Write(topic_50)
if tmpl_topic_vars.CurrentUser.Perms.CreateReply {
w.Write([]byte(`
<div class="rowblock">
<form action="/reply/create/" method="post">
<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(topic_51)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_52)
}
w.Write([]byte(`
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`))
w.Write(footer_0)
}

View File

@ -13,179 +13,149 @@ func init() {
}
func template_topic_alt(tmpl_topic_alt_vars TopicPage, w io.Writer) {
w.Write([]byte(`<!doctype html>
<html lang="en">
<head>
<title>` + tmpl_topic_alt_vars.Title + `</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 = "` + 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>
`))
w.Write(header_0)
w.Write([]byte(tmpl_topic_alt_vars.Title))
w.Write(header_1)
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
w.Write(header_2)
w.Write(menu_0)
if tmpl_topic_alt_vars.CurrentUser.Loggedin {
w.Write([]byte(`
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_topic_alt_vars.CurrentUser.ID) + `">Profile</a></li>
`))
w.Write(menu_1)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.CurrentUser.ID)))
w.Write(menu_2)
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(`
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_topic_alt_vars.CurrentUser.Session + `">Logout</a></li>
`))
w.Write(menu_4)
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
w.Write(menu_5)
} else {
w.Write([]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>
`))
w.Write(menu_6)
}
w.Write([]byte(`
</ul>
</div>
</div>
<div style="clear: both;"></div>
</div>
<div id="back"><div id="main">`))
w.Write(menu_7)
w.Write(header_3)
if len(tmpl_topic_alt_vars.NoticeList) != 0 {
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(`
<div class="rowblock">
<form action='/topic/edit/submit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' method="post">
<div class="rowitem rowhead`))
w.Write(topic_alt_0)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_1)
if tmpl_topic_alt_vars.Topic.Sticky {
w.Write([]byte(` topic_sticky_head`))
w.Write(topic_alt_2)
} else {
if tmpl_topic_alt_vars.Topic.Is_Closed {
w.Write([]byte(` topic_closed_head`))
w.Write(topic_alt_3)
}
}
w.Write([]byte(`">
<a class='topic_name hide_on_edit'>` + tmpl_topic_alt_vars.Topic.Title + `</a>
`))
w.Write(topic_alt_4)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Title))
w.Write(topic_alt_5)
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 {
w.Write([]byte(`
<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>
<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_7)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
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 {
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 {
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(`
<input class='show_on_edit topic_name_input' name="topic_name" value='` + tmpl_topic_alt_vars.Topic.Title + `' 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>
`))
w.Write(topic_alt_14)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Title))
w.Write(topic_alt_15)
}
w.Write([]byte(`
<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>
</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(` + tmpl_topic_alt_vars.Topic.Avatar + `), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div>
<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_16)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_17)
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
w.Write(topic_alt_18)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Avatar))
w.Write(topic_alt_19)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.CreatedBy)))
w.Write(topic_alt_20)
w.Write([]byte(tmpl_topic_alt_vars.Topic.CreatedByName))
w.Write(topic_alt_21)
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 {
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(`
</div>
<div class="content_container">
<div class="hide_on_edit topic_content user_content nobuttons">` + string(tmpl_topic_alt_vars.Topic.Content.(template.HTML)) + `</div>
<textarea name="topic_content" class="show_on_edit topic_content_input">` + string(tmpl_topic_alt_vars.Topic.Content.(template.HTML)) + `</textarea>
</div>
<div style="clear:both;"></div>
</div>
`))
w.Write(topic_alt_26)
w.Write([]byte(string(tmpl_topic_alt_vars.Topic.Content.(template.HTML))))
w.Write(topic_alt_27)
w.Write([]byte(string(tmpl_topic_alt_vars.Topic.Content.(template.HTML))))
w.Write(topic_alt_28)
if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs {
w.Write(topic_alt_29)
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 {
for _, item := range tmpl_topic_alt_vars.ItemList {
w.Write([]byte(`
<div class="rowitem passive deletable_block editable_parent post_item">
<div class="userinfo">
<div class="avatar_item" style="background-image: url(` + item.Avatar + `), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div>
<a href="/user/` + strconv.Itoa(item.CreatedBy) + `" class="the_name">` + item.CreatedByName + `</a>
`))
w.Write(topic_alt_32)
w.Write([]byte(item.Avatar))
w.Write(topic_alt_33)
w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(topic_alt_34)
w.Write([]byte(item.CreatedByName))
w.Write(topic_alt_35)
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 {
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(`
</div>
<div class="content_container">
<div class="editable_block user_content">` + string(item.ContentHtml) + `</div>
<div class="button_container">
`))
w.Write(topic_alt_40)
w.Write([]byte(string(item.ContentHtml)))
w.Write(topic_alt_41)
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 {
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(`
<a href="/report/submit/` + strconv.Itoa(item.ID) + `?session=` + tmpl_topic_alt_vars.CurrentUser.Session + `&type=reply" class="action_button report_item">Report</a>
</div>
</div>
<div style="clear:both;"></div>
</div>
`))
w.Write(topic_alt_46)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_alt_47)
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
w.Write(topic_alt_48)
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 {
w.Write([]byte(`
<div class="rowblock" style="border-top: none;">
<form action="/reply/create/" method="post">
<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(topic_alt_53)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_54)
}
w.Write([]byte(`
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`))
w.Write(footer_0)
}

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. */
package main
import "io"
import "strconv"
import "io"
func init() {
template_topics_handle = template_topics
@ -12,93 +12,63 @@ func init() {
}
func template_topics(tmpl_topics_vars TopicsPage, w io.Writer) {
w.Write([]byte(`<!doctype html>
<html lang="en">
<head>
<title>` + tmpl_topics_vars.Title + `</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 = "` + 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>
`))
w.Write(header_0)
w.Write([]byte(tmpl_topics_vars.Title))
w.Write(header_1)
w.Write([]byte(tmpl_topics_vars.CurrentUser.Session))
w.Write(header_2)
w.Write(menu_0)
if tmpl_topics_vars.CurrentUser.Loggedin {
w.Write([]byte(`
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_topics_vars.CurrentUser.ID) + `">Profile</a></li>
`))
w.Write(menu_1)
w.Write([]byte(strconv.Itoa(tmpl_topics_vars.CurrentUser.ID)))
w.Write(menu_2)
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(`
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_topics_vars.CurrentUser.Session + `">Logout</a></li>
`))
w.Write(menu_4)
w.Write([]byte(tmpl_topics_vars.CurrentUser.Session))
w.Write(menu_5)
} else {
w.Write([]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>
`))
w.Write(menu_6)
}
w.Write([]byte(`
</ul>
</div>
</div>
<div style="clear: both;"></div>
</div>
<div id="back"><div id="main">`))
w.Write(menu_7)
w.Write(header_3)
if len(tmpl_topics_vars.NoticeList) != 0 {
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(`
<div class="rowblock">
<div class="rowitem rowhead"><a>Topic List</a></div>
</div>
<div class="rowblock">
`))
w.Write(topics_0)
if len(tmpl_topics_vars.ItemList) != 0 {
for _, item := range tmpl_topics_vars.ItemList {
w.Write([]byte(`<div class="rowitem passive" style="`))
w.Write(topics_1)
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 {
w.Write([]byte(`background-color: #FFFFCC;`))
w.Write(topics_4)
} else {
if item.Is_Closed {
w.Write([]byte(`background-color: #eaeaea;`))
w.Write(topics_5)
}
}
w.Write([]byte(`">
<a href="/topic/` + strconv.Itoa(item.ID) + `">` + item.Title + `</a> `))
w.Write(topics_6)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topics_7)
w.Write([]byte(item.Title))
w.Write(topics_8)
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(`
</div>
`))
w.Write(topics_10)
}
} else {
w.Write([]byte(`<div class="rowitem passive">There aren't any topics yet.</div>`))
w.Write(topics_11)
}
w.Write([]byte(`
</div>
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div><div style="clear: both;"></div></div></div>
</body>
</html>`))
w.Write(topics_12)
w.Write(footer_0)
}

View File

@ -1,8 +1,10 @@
package main
import "log"
import "fmt"
import "bytes"
import "strings"
import "strconv"
//import "regexp"
import "reflect"
import "path/filepath"
import "io/ioutil"
@ -31,6 +33,9 @@ type CTemplateSet struct
dir string
funcMap map[string]interface{}
importMap map[string]string
Fragments map[string]int
FragmentCursor map[string]int
FragOut string
varList map[string]VarItem
localVars map[string]map[string]VarItemReflect
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[fname] = make(map[string]VarItemReflect)
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]
if debug {
@ -135,6 +145,9 @@ func (c *CTemplateSet) compile_template(name string, dir string, expects string,
fout = strings.Replace(fout,`))
w.Write([]byte(`," + ",-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 {
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.currentNode = node.Type()
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:
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]["."] = VarItemReflect{".",varholder,holdreflect}
c.FragmentCursor[fname] = 0
treeLength := len(subtree.Root.Nodes)
for index, node := range subtree.Root.Nodes {

View File

@ -7,7 +7,7 @@
{{range .ItemList}}
<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>
{{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/delete/{{.ID}}?session={{$.CurrentUser.Session}}" class="username">Delete</a>
</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>
<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>
{{if ne .Topic.Level -1}}<a class="username level hide_on_mobile" title="Level {{.Topic.Level}}">L{{.Topic.Level}}</a>{{end}}
{{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}}
<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>
</div>
</div><br />
<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}}">
<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>
{{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.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" class="mod_button"><button class="username delete_item">Delete</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}}
<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_mobile" style="color: #505050;float: right;border-right: 0;">{{.URLPrefix}}</a>{{end}}
<a class="username hide_on_micro" {{if .Tag}}style="float: right;">{{.Tag}}{{else}}style="color: #505050;float: right;">Level {{.Level}}{{end}}</a>
</div>
{{end}}</div>
{{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}}
</div>
<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>
</div>
<div style="clear:both;"></div>
<div class="button_container">
{{/* 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>
{{range .ItemList}}
<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.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>
{{if $.CurrentUser.Perms.ViewIPs}}<a href="#" class="action_button action_button_right ip_item">{{.IpAddress}}</a>{{end}}
</div>
</div>
<div style="clear:both;"></div>

View File

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

View File

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

View File

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

View File

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

View File

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

46
user.go
View File

@ -1,6 +1,8 @@
package main
//import "fmt"
import "strings"
import "strconv"
import "net"
import "net/http"
import "golang.org/x/crypto/bcrypt"
import "database/sql"
@ -28,6 +30,7 @@ type User struct
Tag string
Level int
Score int
Last_IP string
}
type Email struct
@ -70,18 +73,14 @@ func SendValidationEmail(username string, email string, token string) bool {
return SendEmail(email, subject, msg)
}
func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList map[int]string, success bool) {
noticeList = make(map[int]string)
func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList []string, success bool) {
// 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")
if err != nil {
user.Perms = GuestPerms
return user, noticeList, true
}
user.Name = cookie.Value
user.ID, err = strconv.Atoi(user.Name)
user.ID, err = strconv.Atoi(cookie.Value)
if err != nil {
user.Perms = GuestPerms
return user, noticeList, true
@ -91,10 +90,9 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList
user.Perms = GuestPerms
return user, noticeList, true
}
user.Session = cookie.Value
// 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 {
user.ID = 0
user.Session = ""
@ -121,7 +119,7 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList
}
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 != "" {
@ -131,19 +129,26 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList
} else {
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
}
func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, success bool) {
// 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")
if err != nil {
user.Perms = GuestPerms
return user, true
}
user.Name = cookie.Value
user.ID, err = strconv.Atoi(user.Name)
user.ID, err = strconv.Atoi(cookie.Value)
if err != nil {
user.Perms = GuestPerms
return user, true
@ -153,10 +158,9 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, succ
user.Perms = GuestPerms
return user, true
}
user.Session = cookie.Value
// 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 {
user.ID = 0
user.Session = ""
@ -189,6 +193,20 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, succ
} else {
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
}