Added the Level System.

The .bat files now exit upon encountering an error.
Post, bigpost, megapost, and topic stats are now tracked for each user.
Added the bigpost_min_chars and megapost_min_chars settings. Probably needs to be renamed.
Added the Levels test. Run `go test -run "Levels"`
The installer now validates the inputted server port.
Added a word counter utility function.
The template engine now borks less on variable nodes.
Added the lt, gt, ge, eq and ne to the template engine. I'm fairly sure eq was already in there, but things get handled differently depending on what type of node it is.
Eliminated more "success" variables by converting the errors over into InternalError() and LocalErrors()
This commit is contained in:
Azareal 2017-01-12 02:55:08 +00:00
parent 7f8aaedb0a
commit b7c89fd020
22 changed files with 431 additions and 235 deletions

View File

@ -4,7 +4,7 @@ A super fast forum software written in Go.
The initial code-base was forked from one of my side projects, but has now gone far beyond that.
Discord Server: https://discord.gg/eyYvtTf
Azareal's Discord Chat: https://discord.gg/eyYvtTf
If you like this software, please give it a star and give us some feedback :)

View File

@ -1,3 +1,13 @@
@echo off
go build
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
go build ./install
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Gosora was successfully built
pause

View File

@ -2,19 +2,25 @@ CREATE TABLE `users`(
`uid` int not null AUTO_INCREMENT,
`name` varchar(100) not null,
`password` varchar(100) not null,
`salt` varchar(80) DEFAULT '' not null,
`salt` varchar(80) default '' not null,
`group` int not null,
`active` tinyint DEFAULT 0 not null,
`active` tinyint default 0 not null,
`is_super_admin` tinyint(1) not null,
`createdAt` datetime not null,
`lastActiveAt` datetime not null,
`session` varchar(200) DEFAULT '' not null,
`last_ip` varchar(200) DEFAULT '0.0.0.0.0' not null,
`email` varchar(200) DEFAULT '' not null,
`avatar` varchar(20) DEFAULT '' not null,
`session` varchar(200) default '' not null,
`last_ip` varchar(200) default '0.0.0.0.0' not null,
`email` varchar(200) default '' not null,
`avatar` varchar(20) default '' not null,
`message` text not null,
`url_prefix` varchar(20) DEFAULT '' not null,
`url_name` varchar(100) DEFAULT '' not null,
`url_prefix` varchar(20) default '' not null,
`url_name` varchar(100) default '' not null,
`level` tinyint default 0 not null,
`score` int default 0 not null,
`posts` int default 0 not null,
`bigposts` int default 0 not null,
`megaposts` int default 0 not null,
`topics` int default 0 not null,
primary key(`uid`),
unique(`name`)
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
@ -91,8 +97,8 @@ CREATE TABLE `users_replies`(
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
CREATE TABLE `likes`(
`weight` int DEFAULT 1 not null,
`type` int not null, /* Regular Post = 1, Big Post = 2, Mega Post = 3, etc.*/
`weight` tinyint DEFAULT 1 not null,
`type` tinyint not null, /* Regular Post = 1, Big Post = 2, Mega Post = 3, etc.*/
`targetItem` int not null,
`sentBy` int not null,
`recalc` tinyint DEFAULT 0 not null
@ -120,6 +126,8 @@ CREATE TABLE `themes`(
INSERT INTO settings(`name`,`content`,`type`) VALUES ('url_tags','1','bool');
INSERT INTO settings(`name`,`content`,`type`,`constraints`) VALUES ('activation_type','1','list','1-3');
INSERT INTO settings(`name`,`content`,`type`) VALUES ('bigpost_min_chars','250','int');
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`)

View File

@ -1,6 +1,7 @@
package main
import "log"
import "bytes"
import "strconv"
import "math/rand"
import "testing"
import "net/http"
@ -12,24 +13,24 @@ import "html/template"
func BenchmarkTopicTemplate(b *testing.B) {
b.ReportAllocs()
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","",""}
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","",""}
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"
topic := TopicUser{0,"Lol",template.HTML("Hey everyone!"),0,false,false,"",0,"","","",no_css_tmpl,0,"","","",""}
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}
var replyList []Reply
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,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})
tpage := TopicPage{"Topic Blah",user,noticeList,replyList,topic,false}
tpage2 := TopicPage{"Topic Blah",admin,noticeList,replyList,topic,false}
@ -60,22 +61,22 @@ func BenchmarkTopicTemplate(b *testing.B) {
func BenchmarkTopicsTemplate(b *testing.B) {
b.ReportAllocs()
user := User{0,"Bob","bob@localhost",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","",""}
admin := User{1,"Admin","admin@localhost",0,true,true,true,true,true,false,AllPerms,"",false,"","","","",""}
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"
var topicList []TopicUser
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
topicList = append(topicList, TopicUser{0,"Hey everyone!",template.HTML("Hey everyone!"),0,false,false,"0000-00-00 00:00:00",1,"open","Admin","",no_css_tmpl,0,"Admin","","",""})
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})
tpage := TopicsPage{"Topic Blah",user,noticeList,topicList,0}
tpage2 := TopicsPage{"Topic Blah",admin,noticeList,topicList,0}
@ -895,6 +896,14 @@ func BenchmarkBBCodePluginWithFullParser(b *testing.B) {
})
}
func TestLevels(t *testing.T) {
levels := getLevels(40)
for level, score := range levels {
sscore := strconv.FormatFloat(score, 'f', -1, 64)
log.Print("Level: " + strconv.Itoa(level) + " Score: " + sscore)
}
}
/*func TestRoute(t *testing.T) {
}*/

BIN
images/level_algorithm.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
images/levels.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB

View File

@ -1,5 +1,25 @@
@echo off
echo Installing the dependencies
go get -u github.com/go-sql-driver/mysql
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
go get -u golang.org/x/crypto/bcrypt
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo Preparing the installer
go build
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
go build ./install
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
install.exe

View File

@ -273,6 +273,11 @@ func get_site_details() bool {
if server_port == "" {
server_port = default_server_port
}
_, err := strconv.Atoi(server_port)
if err != nil {
fmt.Println("That's not a valid number!")
return false
}
fmt.Println("Set the server port to " + server_port)
return true
}

View File

@ -41,15 +41,15 @@ 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,"","","","",""}
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"
log.Print("Compiling the templates")
topic := TopicUser{1,"Blah",template.HTML("Hey there!"),0,false,false,"",0,"","","",no_css_tmpl,0,"","","",""}
topic := TopicUser{1,"Blah",template.HTML("Hey there!"),0,false,false,"",0,"","","",no_css_tmpl,0,"","","","",58}
var replyList []Reply
replyList = append(replyList, Reply{0,0,"",template.HTML("Yo!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"",template.HTML("Yo!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0})
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,"","","",""})
topicList = append(topicList, TopicUser{1,"Topic Title","The topic content.",1,false,false,"",1,"open","Admin","","",0,"","","","",58})
topics_page := TopicsPage{"Topic List",user,noticeList,topicList,""}
topics_tmpl := c.compile_template("topics.html","templates/","TopicsPage", topics_page, varList)

View File

@ -38,11 +38,7 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
topic_name := r.PostFormValue("topic_name")
topic_status := r.PostFormValue("topic_status")
var is_closed bool
if topic_status == "closed" {
is_closed = true
}
is_closed := (topic_status == "closed")
topic_content := html.EscapeString(r.PostFormValue("topic_content"))
_, err = edit_topic_stmt.Exec(topic_name, preparse_message(topic_content), parse_message(html.EscapeString(preparse_message(topic_content))), is_closed, tid)
@ -74,7 +70,9 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
return
}
err = db.QueryRow("SELECT tid from topics where tid = ?", tid).Scan(&tid)
var content string
var createdBy int
err = db.QueryRow("select tid, content, createdBy from topics where tid = ?", tid).Scan(&tid, &content, &createdBy)
if err == sql.ErrNoRows {
LocalError("The topic you tried to delete doesn't exist.",w,r,user)
return
@ -88,9 +86,15 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r,user)
return
}
log.Print("The topic '" + strconv.Itoa(tid) + "' was deleted by User ID #" + strconv.Itoa(user.ID) + ".")
http.Redirect(w, r, "/", http.StatusSeeOther)
http.Redirect(w,r,"/",http.StatusSeeOther)
wcount := word_count(content)
err = decrease_post_user_stats(wcount, createdBy, true, user)
if err != nil {
InternalError(err,w,r,user)
return
}
}
func route_stick_topic(w http.ResponseWriter, r *http.Request) {
@ -152,7 +156,6 @@ func route_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
LocalError("Bad Form", w, r, user)
return
}
is_js := r.PostFormValue("js")
if is_js == "" {
is_js = "0"
@ -218,7 +221,9 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
}
var tid int
err = db.QueryRow("SELECT tid from replies where rid = ?", rid).Scan(&tid)
var content string
var createdBy int
err = db.QueryRow("SELECT tid, content, createdBy from replies where rid = ?", rid).Scan(&tid, &content, &createdBy)
if err == sql.ErrNoRows {
LocalErrorJSQ("The reply you tried to delete doesn't exist.",w,r,user,is_js)
return
@ -233,12 +238,18 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
return
}
log.Print("The reply '" + strconv.Itoa(rid) + "' was deleted by User ID #" + strconv.Itoa(user.ID) + ".")
if is_js == "0" {
//http.Redirect(w,r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
} else {
fmt.Fprintf(w,"{'success': '1'}")
}
wcount := word_count(content)
err = decrease_post_user_stats(wcount, createdBy, false, user)
if err != nil {
InternalError(err,w,r,user)
return
}
}
func route_profile_reply_edit_submit(w http.ResponseWriter, r *http.Request) {

View File

@ -34,6 +34,12 @@ var register_stmt *sql.Stmt
var username_exists_stmt *sql.Stmt
var change_group_stmt *sql.Stmt
var activate_user_stmt *sql.Stmt
var update_user_level_stmt *sql.Stmt
var increment_user_score_stmt *sql.Stmt
var increment_user_posts_stmt *sql.Stmt
var increment_user_bigposts_stmt *sql.Stmt
var increment_user_megaposts_stmt *sql.Stmt
var increment_user_topics_stmt *sql.Stmt
var create_profile_reply_stmt *sql.Stmt
var edit_profile_reply_stmt *sql.Stmt
var delete_profile_reply_stmt *sql.Stmt
@ -64,7 +70,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` 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` FROM `users` where `uid` = ? AND `session` = ? AND `session` <> ''")
if err != nil {
log.Fatal(err)
}
@ -222,6 +228,42 @@ func init_database(err error) {
log.Fatal(err)
}
log.Print("Preparing update_user_level statement.")
update_user_level_stmt, err = db.Prepare("UPDATE users SET level = ? WHERE uid = ?")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing increment_user_score statement.")
increment_user_score_stmt, err = db.Prepare("UPDATE users SET score = score + ? WHERE uid = ?")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing increment_user_posts statement.")
increment_user_posts_stmt, err = db.Prepare("UPDATE users SET posts = posts + ? WHERE uid = ?")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing increment_user_bigposts statement.")
increment_user_bigposts_stmt, err = db.Prepare("UPDATE users SET posts = posts + ?, bigposts = bigposts + ? WHERE uid = ?")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing increment_user_megaposts statement.")
increment_user_megaposts_stmt, err = db.Prepare("UPDATE users SET posts = posts + ?, bigposts = bigposts + ?, megaposts = megaposts + ? WHERE uid = ?")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing increment_user_topics statement.")
increment_user_topics_stmt, err = db.Prepare("UPDATE users SET topics = topics + ? WHERE uid = ?")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing create_profile_reply statement.")
create_profile_reply_stmt, err = db.Prepare("INSERT INTO users_replies(uid,content,parsed_content,createdAt,createdBy) VALUES(?,?,?,NOW(),?)")
if err != nil {

View File

@ -20,4 +20,5 @@ type Reply struct
URL string
URLPrefix string
URLName string
Level int
}

230
routes.go
View File

@ -236,7 +236,6 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
var(
err error
rid int
@ -254,13 +253,14 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
replyURL string
replyURLPrefix string
replyURLName string
replyLevel int
is_super_admin bool
group int
replyList []Reply
)
topic := TopicUser{0,"","",0,false,false,"",0,"","","",no_css_tmpl,0,"","","",""}
topic := TopicUser{Css: no_css_tmpl}
topic.ID, err = strconv.Atoi(r.URL.Path[len("/topic/"):])
if err != nil {
LocalError("The provided TopicID is not a valid number.",w,r,user)
@ -274,7 +274,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 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)
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)
if err == sql.ErrNoRows {
NotFound(w,r,user)
return
@ -300,12 +300,13 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
}
if is_super_admin || groups[group].Is_Mod || groups[group].Is_Admin {
topic.Css = staff_css_tmpl
topic.Level = -1
}
if groups[group].Tag != "" {
//if groups[group].Tag != "" {
topic.Tag = groups[group].Tag
} else {
topic.Tag = ""
}
//} else {
// topic.Tag = ""
//}
if settings["url_tags"] == false {
topic.URLName = ""
} else {
@ -318,7 +319,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
}
// 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 from replies left join users ON replies.createdBy = users.uid where tid = ?", topic.ID)
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)
if err != nil {
InternalError(err,w,r,user)
return
@ -326,7 +327,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
defer rows.Close()
for rows.Next() {
err := rows.Scan(&rid, &replyContent, &replyCreatedBy, &replyCreatedAt, &replyLastEdit, &replyLastEditBy, &replyAvatar, &replyCreatedByName, &is_super_admin, &group, &replyURLPrefix, &replyURLName)
err := rows.Scan(&rid, &replyContent, &replyCreatedBy, &replyCreatedAt, &replyLastEdit, &replyLastEditBy, &replyAvatar, &replyCreatedByName, &is_super_admin, &group, &replyURLPrefix, &replyURLName, &replyLevel)
if err != nil {
InternalError(err,w,r,user)
return
@ -335,6 +336,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
replyLines = strings.Count(replyContent,"\n")
if is_super_admin || groups[group].Is_Mod || groups[group].Is_Admin {
replyCss = staff_css_tmpl
replyLevel = -1
} else {
replyCss = no_css_tmpl
}
@ -345,11 +347,11 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
} else {
replyAvatar = strings.Replace(noavatar,"{id}",strconv.Itoa(replyCreatedBy),1)
}
if groups[group].Tag != "" {
//if groups[group].Tag != "" {
replyTag = groups[group].Tag
} else {
replyTag = ""
}
//} else {
// replyTag = ""
//}
if settings["url_tags"] == false {
replyURLName = ""
} else {
@ -361,7 +363,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
}
}
replyItem := Reply{rid,topic.ID,replyContent,template.HTML(parse_message(replyContent)),replyCreatedBy,replyCreatedByName,replyCreatedAt,replyLastEdit,replyLastEditBy,replyAvatar,replyCss,replyLines,replyTag,replyURL,replyURLPrefix,replyURLName}
replyItem := Reply{rid,topic.ID,replyContent,template.HTML(parse_message(replyContent)),replyCreatedBy,replyCreatedByName,replyCreatedAt,replyLastEdit,replyLastEditBy,replyAvatar,replyCss,replyLines,replyTag,replyURL,replyURLPrefix,replyURLName,replyLevel}
if hooks["rrow_assign"] != nil {
replyItem = run_hook("rrow_assign", replyItem).(Reply)
@ -422,7 +424,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` FROM `users` WHERE `uid` = ?", puser.ID).Scan(&puser.Name, &puser.Group, &puser.Is_Super_Admin, &puser.Avatar, &puser.Message, &puser.URLPrefix, &puser.URLName)
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
@ -440,11 +442,11 @@ func route_profile(w http.ResponseWriter, r *http.Request){
}
}
if groups[puser.Group].Tag != "" {
//if groups[puser.Group].Tag != "" {
puser.Tag = groups[puser.Group].Tag
} else {
puser.Tag = ""
}
//} else {
// puser.Tag = ""
//}
if puser.Avatar != "" {
if puser.Avatar[0] == '.' {
@ -490,7 +492,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,"","",""})
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 {
@ -518,7 +520,6 @@ 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}
templates.ExecuteTemplate(w,"create-topic.html", pi)
}
@ -539,38 +540,32 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
LocalError("Bad Form", w, r, user)
return
}
success := 1
topic_name := html.EscapeString(r.PostFormValue("topic-name"))
content := html.EscapeString(preparse_message(r.PostFormValue("topic-content")))
res, err := create_topic_stmt.Exec(topic_name,html.EscapeString(preparse_message(r.PostFormValue("topic-content"))),parse_message(html.EscapeString(preparse_message(r.PostFormValue("topic-content")))),user.ID)
res, err := create_topic_stmt.Exec(topic_name,content,parse_message(content),user.ID)
if err != nil {
log.Print(err)
success = 0
InternalError(err,w,r,user)
return
}
lastId, err := res.LastInsertId()
if err != nil {
log.Print(err)
success = 0
InternalError(err,w,r,user)
return
}
_, err = update_forum_cache_stmt.Exec(topic_name, lastId, user.Name, user.ID, 1)
if err != nil {
InternalError(err,w,r,user)
return
}
if success != 1 {
errmsg := "Unable to create the topic"
pi := Page{"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)
} else {
http.Redirect(w, r, "/topic/" + strconv.FormatInt(lastId, 10), http.StatusSeeOther)
http.Redirect(w, r, "/topic/" + strconv.FormatInt(lastId,10), http.StatusSeeOther)
wcount := word_count(content)
err = increase_post_user_stats(wcount, user.ID, true, user)
if err != nil {
InternalError(err,w,r,user)
return
}
}
@ -589,7 +584,6 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
LocalError("Bad Form", w, r, user)
return
}
tid, err := strconv.Atoi(r.PostFormValue("tid"))
if err != nil {
LocalError("Failed to convert the TopicID", w, r, user)
@ -597,7 +591,7 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
}
content := preparse_message(html.EscapeString(r.PostFormValue("reply-content")))
log.Print(content)
//log.Print(content)
_, err = create_reply_stmt.Exec(tid,content,parse_message(content),user.ID)
if err != nil {
InternalError(err,w,r,user)
@ -621,6 +615,12 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
}
http.Redirect(w, r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
wcount := word_count(content)
err = increase_post_user_stats(wcount, user.ID, false, user)
if err != nil {
InternalError(err,w,r,user)
return
}
}
func route_profile_reply_create(w http.ResponseWriter, r *http.Request) {
@ -638,52 +638,29 @@ func route_profile_reply_create(w http.ResponseWriter, r *http.Request) {
LocalError("Bad Form", w, r, user)
return
}
success := 1
uid, err := strconv.Atoi(r.PostFormValue("uid"))
if err != nil {
log.Print(err)
success = 0
errmsg := "Unable to create the reply"
pi := Page{"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)
LocalError("Invalid UID",w,r,user)
return
}
_, err = create_profile_reply_stmt.Exec(uid,html.EscapeString(preparse_message(r.PostFormValue("reply-content"))),parse_message(html.EscapeString(preparse_message(r.PostFormValue("reply-content")))),user.ID)
if err != nil {
log.Print(err)
success = 0
InternalError(err,w,r,user)
return
}
var user_name string
err = db.QueryRow("select name from users where uid = ?", uid).Scan(&user_name)
if err == sql.ErrNoRows {
log.Print(err)
success = 0
LocalError("The profile you're trying to post on doesn't exist.",w,r,user)
return
} else if err != nil {
InternalError(err,w,r,user)
return
}
if success != 1 {
errmsg := "Unable to create the reply"
pi := Page{"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)
} else {
http.Redirect(w, r, "/user/" + strconv.Itoa(uid), http.StatusSeeOther)
}
http.Redirect(w, r, "/user/" + strconv.Itoa(uid), http.StatusSeeOther)
}
func route_report_submit(w http.ResponseWriter, r *http.Request) {
@ -691,7 +668,6 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Loggedin {
LoginRequired(w,r,user)
return
@ -872,13 +848,7 @@ func route_account_own_edit_critical_submit(w http.ResponseWriter, r *http.Reque
err = get_password_stmt.QueryRow(user.ID).Scan(&real_password, &salt)
if err == sql.ErrNoRows {
pi := Page{"Error","error",user,nList,tList,"Your account doesn't exist."}
var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(500)
fmt.Fprintln(w,errpage)
LocalError("Your account no longer exists.",w,r,user)
return
} else if err != nil {
InternalError(err,w,r,user)
@ -888,26 +858,14 @@ func route_account_own_edit_critical_submit(w http.ResponseWriter, r *http.Reque
current_password = current_password + salt
err = bcrypt.CompareHashAndPassword([]byte(real_password), []byte(current_password))
if err == bcrypt.ErrMismatchedHashAndPassword {
pi := Page{"Error","error",user,nList,tList,"That's not the correct password."}
var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(500)
fmt.Fprintln(w,errpage)
LocalError("That's not the correct password.",w,r,user)
return
} else if err != nil {
InternalError(err,w,r,user)
return
}
if new_password != confirm_password {
pi := Page{"Error","error",user,nList,tList,"The two passwords don't match."}
var b bytes.Buffer
templates.ExecuteTemplate(&b,"error.html", pi)
errpage := b.String()
w.WriteHeader(500)
fmt.Fprintln(w,errpage)
LocalError("The two passwords don't match.",w,r,user)
return
}
SetPassword(user.ID, new_password)
@ -1192,16 +1150,8 @@ func route_logout(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Loggedin {
errmsg := "You can't logout without logging in first."
pi := Page{"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)
LocalError("You can't logout without logging in first.",w,r,user)
return
}
@ -1218,19 +1168,10 @@ func route_login(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if user.Loggedin {
errmsg := "You're already logged in."
pi := Page{"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)
LocalError("You're already logged in.",w,r,user)
return
}
pi := Page{"Login","login",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"login.html", pi)
}
@ -1240,16 +1181,8 @@ func route_login_submit(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if user.Loggedin {
errmsg := "You're already logged in."
pi := Page{"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)
LocalError("You're already logged in.",w,r,user)
return
}
@ -1268,14 +1201,7 @@ func route_login_submit(w http.ResponseWriter, r *http.Request) {
err = login_stmt.QueryRow(username).Scan(&uid, &username, &real_password, &salt)
if err == sql.ErrNoRows {
errmsg := "That username doesn't exist."
pi := Page{"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)
LocalError("That username doesn't exist.",w,r,user)
return
} else if err != nil {
InternalError(err,w,r,user)
@ -1285,14 +1211,7 @@ func route_login_submit(w http.ResponseWriter, r *http.Request) {
// Emergency password reset mechanism..
if salt == "" {
if password != real_password {
errmsg := "That's not the correct password."
pi := Page{"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)
LocalError("That's not the correct password.",w,r,user)
return
}
@ -1307,14 +1226,7 @@ func route_login_submit(w http.ResponseWriter, r *http.Request) {
err := bcrypt.CompareHashAndPassword([]byte(real_password), []byte(password))
if err == bcrypt.ErrMismatchedHashAndPassword {
errmsg := "That's not the correct password."
pi := Page{"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)
LocalError("That's not the correct password.",w,r,user)
return
} else if err != nil {
InternalError(err,w,r,user)
@ -1347,17 +1259,9 @@ func route_register(w http.ResponseWriter, r *http.Request) {
return
}
if user.Loggedin {
errmsg := "You're already logged in."
pi := Page{"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)
LocalError("You're already logged in.",w,r,user)
return
}
pi := Page{"Registration","register",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"register.html", pi)
}
@ -1367,7 +1271,6 @@ func route_register_submit(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
err := r.ParseForm()
if err != nil {
LocalError("Bad Form", w, r, user)
@ -1400,14 +1303,7 @@ func route_register_submit(w http.ResponseWriter, r *http.Request) {
// Do the two inputted passwords match..?
if password != confirm_password {
errmsg := "The two passwords don't match."
pi := Page{"Password Mismatch","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)
LocalError("The two passwords don't match.",w,r,user)
return
}
@ -1417,14 +1313,7 @@ func route_register_submit(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r,user)
return
} else if err != sql.ErrNoRows {
errmsg := "This username isn't available. Try another."
pi := Page{"Username Taken","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)
LocalError("This username isn't available. Try another.",w,r,user)
return
}
@ -1433,7 +1322,6 @@ func route_register_submit(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r,user)
return
}
session, err := GenerateSafeString(sessionLength)
if err != nil {
InternalError(err,w,r,user)

View File

@ -1,3 +1,8 @@
@echo off
go build
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
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 "io"
import "strconv"
import "io"
func init() {
template_profile_handle = template_profile

View File

@ -120,10 +120,14 @@ w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128p
}
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 />
<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(`
`))
if tmpl_topic_vars.Topic.Tag != "" {
w.Write([]byte(`<a class="username hide_on_micro" style="float: right;">` + tmpl_topic_vars.Topic.Tag + `</a>`))
} else {
@ -151,6 +155,11 @@ 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(`
`))
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>`))
}

View File

@ -304,7 +304,6 @@ func (c *CTemplateSet) compile_subswitch(varholder string, holdreflect reflect.V
} else {
varbit += "." + id
}
if debug {
fmt.Println("End Cycle")
}
@ -331,9 +330,8 @@ func (c *CTemplateSet) compile_subswitch(varholder string, holdreflect reflect.V
fmt.Println(n.String())
fmt.Println(n.Ident)
}
out, _ = c.compile_if_varsub(n.String(), varholder, template_name, holdreflect)
return "w.Write([]byte(" + out + "))\n"
varname, reflectVal := c.compile_if_varsub(n.String(), varholder, template_name, holdreflect)
return c.compile_varsub(varname, reflectVal)
case *parse.StringNode:
return n.Quoted
default:
@ -429,6 +427,21 @@ func (c *CTemplateSet) compile_identswitch(varholder string, holdreflect reflect
case "le":
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " <= " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
break ArgLoop
case "lt":
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " < " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
break ArgLoop
case "gt":
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " > " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
break ArgLoop
case "ge":
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " >= " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
break ArgLoop
case "eq":
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " == " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
break ArgLoop
case "ne":
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " != " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
break ArgLoop
default:
if debug {
fmt.Println("Variable!")

View File

@ -23,9 +23,9 @@
<div class="rowblock post_container">
<div class="rowitem passive editable_parent post_item" style="border-bottom: none;{{ if .Topic.Avatar }}background-image: url({{ .Topic.Avatar }}), url(/static/white-dot.jpg);background-position: 0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Topic.Css}}{{end}}">
<p class="hide_on_edit topic_content user_content" style="margin: 0;padding: 0;">{{.Topic.Content}}</p>
<textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea>
<br /><br />
<textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea><br /><br />
<a href="/user/{{.Topic.CreatedBy}}" class="username real_username">{{.Topic.CreatedByName}}</a>
{{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}}
</div>
@ -34,6 +34,7 @@
<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}}
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" class="mod_button"><button class="username report_item">Report</button></a>

View File

@ -34,4 +34,5 @@ type TopicUser struct
URL string
URLPrefix string
URLName string
Level int
}

View File

@ -1,3 +1,13 @@
@echo off
go get -u github.com/go-sql-driver/mysql
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
go get -u golang.org/x/crypto/bcrypt
if %errorlevel% neq 0 (
pause
exit /b %errorlevel%
)
echo The dependencies were successfully updated
pause

83
user.go
View File

@ -1,4 +1,5 @@
package main
import "fmt"
import "strings"
import "strconv"
import "net/http"
@ -26,6 +27,8 @@ type User struct
URLPrefix string
URLName string
Tag string
Level int
Score int
}
type Email struct
@ -92,7 +95,7 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList
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)
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)
if err == sql.ErrNoRows {
user.ID = 0
user.Session = ""
@ -154,7 +157,7 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, succ
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)
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)
if err == sql.ErrNoRows {
user.ID = 0
user.Session = ""
@ -189,3 +192,79 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, succ
}
return user, true
}
func increase_post_user_stats(wcount int, uid int, topic bool, user User) error {
var mod int
base_score := 1
if topic {
_, err := increment_user_topics_stmt.Exec(1, uid)
if err != nil {
return err
}
base_score = 2
}
if wcount > settings["megapost_min_chars"].(int) {
_, err := increment_user_megaposts_stmt.Exec(1,1,1,uid)
if err != nil {
return err
}
mod = 4
} else if wcount > settings["bigpost_min_chars"].(int) {
_, err := increment_user_bigposts_stmt.Exec(1,1,uid)
if err != nil {
return err
}
mod = 1
} else {
_, err := increment_user_posts_stmt.Exec(1,uid)
if err != nil {
return err
}
}
_, err := increment_user_score_stmt.Exec(base_score + mod, uid)
if err != nil {
return err
}
fmt.Println(user.Score + base_score + mod)
fmt.Println(getLevel(user.Score + base_score + mod))
_, err = update_user_level_stmt.Exec(getLevel(user.Score + base_score + mod), uid)
return err
}
func decrease_post_user_stats(wcount int, uid int, topic bool, user User) error {
var mod int
base_score := -1
if topic {
_, err := increment_user_topics_stmt.Exec(-1, uid)
if err != nil {
return err
}
base_score = -2
}
if wcount > settings["megapost_min_chars"].(int) {
_, err := increment_user_megaposts_stmt.Exec(-1,-1,-1,uid)
if err != nil {
return err
}
mod = 4
} else if wcount > settings["bigpost_min_chars"].(int) {
_, err := increment_user_bigposts_stmt.Exec(-1,-1,uid)
if err != nil {
return err
}
mod = 1
} else {
_, err := increment_user_posts_stmt.Exec(-1,uid)
if err != nil {
return err
}
}
_, err := increment_user_score_stmt.Exec(base_score - mod, uid)
if err != nil {
return err
}
_, err = update_user_level_stmt.Exec(getLevel(user.Score - base_score - mod), uid)
return err
}

View File

@ -3,6 +3,9 @@ import "log"
import "fmt"
import "time"
import "os"
import "math"
import "strings"
import "unicode"
import "encoding/base64"
import "crypto/rand"
import "net/smtp"
@ -103,3 +106,84 @@ func write_file(name string, content string) {
f.Sync()
f.Close()
}
func word_count(input string) int {
input = strings.TrimSpace(input)
count := 0
in_space := false
for _, value := range input {
if unicode.IsSpace(value) {
if !in_space {
in_space = true
}
} else if in_space {
count++
in_space = false
}
}
return count
}
func getLevel(score int) (level int) {
var base float64 = 25
var current float64
var prev float64
exp_factor := 2.8
for i := 1;;i++ {
_, bit := math.Modf(float64(i) / 10)
if bit == 0 {
exp_factor += 0.1
}
current = base + math.Pow(float64(i), exp_factor) + (prev / 3)
prev = current
if float64(score) < current {
break
} else {
level++
}
}
return level
}
func getLevelScore(getLevel int) (score int) {
var base float64 = 25
var current float64
var prev float64
var level int
exp_factor := 2.8
for i := 1;;i++ {
_, bit := math.Modf(float64(i) / 10)
if bit == 0 {
exp_factor += 0.1
}
current = base + math.Pow(float64(i), exp_factor) + (prev / 3)
prev = current
level++
if level <= getLevel {
break
}
}
return int(math.Ceil(current))
}
func getLevels(maxLevel int) []float64 {
var base float64 = 25
var current float64 = 0
var prev float64 = 0
exp_factor := 2.8
var out []float64
out = append(out, 0)
for i := 1;i <= maxLevel;i++ {
_, bit := math.Modf(float64(i) / 10)
if bit == 0 {
exp_factor += 0.1
}
current = base + math.Pow(float64(i), exp_factor) + (prev / 3)
prev = current
out = append(out, current)
}
return out
}