Added support for Live Likes, the first step towards Live Alerts.
Moved 26 queries into the query generator. Added support for sime replace queries in the query generator. The alert list can only have eight entries now. Users can no longer like their own posts. Renamed the bigpost_min_chars setting to bigpost_min_words. Renamed the megapost_min_chars setting to megapost_min_words. Moved the alert building logic into it's own file. Fixed a bug in the megapost and bigpost algorithms where only posts larger than the minimum would be considered. Renamed the GuestCount and UserCount methods for WebSockets to guest_count and user_count. Added the broadcast_message, push_message, and push_alert methods to the WebSockets Hub.
This commit is contained in:
parent
47259fcf71
commit
81af085c7a
113
alerts.go
Normal file
113
alerts.go
Normal file
@ -0,0 +1,113 @@
|
||||
package main
|
||||
|
||||
import "strings"
|
||||
import "strconv"
|
||||
import "errors"
|
||||
|
||||
/*
|
||||
"You received a friend invite from {user}"
|
||||
"{x}{mentioned you on}{user}{'s profile}"
|
||||
"{x}{mentioned you in}{topic}"
|
||||
"{x}{likes}{you}"
|
||||
"{x}{liked}{your topic}{topic}"
|
||||
"{x}{liked}{your post on}{user}{'s profile}" todo
|
||||
"{x}{liked}{your post in}{topic}"
|
||||
"{x}{replied to}{your post in}{topic}" todo
|
||||
"{x}{replied to}{topic}"
|
||||
"{x}{replied to}{your topic}{topic}"
|
||||
"{x}{created a new topic}{topic}"
|
||||
*/
|
||||
|
||||
func build_alert(event string, elementType string, actor_id int, targetUser_id int, elementID int, user User /* The current user */) (string, error) {
|
||||
var targetUser *User
|
||||
|
||||
actor, err := users.CascadeGet(actor_id)
|
||||
if err != nil {
|
||||
return "", errors.New("Unable to find the actor")
|
||||
}
|
||||
|
||||
/*if elementType != "forum" {
|
||||
targetUser, err = users.CascadeGet(targetUser_id)
|
||||
if err != nil {
|
||||
LocalErrorJS("Unable to find the target user",w,r)
|
||||
return
|
||||
}
|
||||
}*/
|
||||
|
||||
if event == "friend_invite" {
|
||||
return `{"msg":"You received a friend invite from {0}","sub":["` + actor.Name + `"],"path":"\/user\/`+strconv.Itoa(actor.ID)+`","avatar":"`+strings.Replace(actor.Avatar,"/","\\/",-1)+`"}`, nil
|
||||
}
|
||||
|
||||
var act, post_act, url, area string
|
||||
var start_frag, end_frag string
|
||||
switch(elementType) {
|
||||
case "forum":
|
||||
if event == "reply" {
|
||||
act = "created a new topic"
|
||||
topic, err := topics.CascadeGet(elementID)
|
||||
if err != nil {
|
||||
return "", errors.New("Unable to find the linked topic")
|
||||
}
|
||||
url = build_topic_url(elementID)
|
||||
area = topic.Title
|
||||
// Store the forum ID in the targetUser column instead of making a new one? o.O
|
||||
// Add an additional column for extra information later on when we add the ability to link directly to posts. We don't need the forum data for now...
|
||||
} else {
|
||||
act = "did something in a forum"
|
||||
}
|
||||
case "topic":
|
||||
topic, err := topics.CascadeGet(elementID)
|
||||
if err != nil {
|
||||
return "", errors.New("Unable to find the linked topic")
|
||||
}
|
||||
url = build_topic_url(elementID)
|
||||
area = topic.Title
|
||||
|
||||
if targetUser_id == user.ID {
|
||||
post_act = " your topic"
|
||||
}
|
||||
case "user":
|
||||
targetUser, err = users.CascadeGet(elementID)
|
||||
if err != nil {
|
||||
return "", errors.New("Unable to find the target user")
|
||||
}
|
||||
area = targetUser.Name
|
||||
end_frag = "'s profile"
|
||||
url = build_profile_url(elementID)
|
||||
case "post":
|
||||
topic, err := get_topic_by_reply(elementID)
|
||||
if err != nil {
|
||||
return "", errors.New("Unable to find the linked reply or parent topic")
|
||||
}
|
||||
url = build_topic_url(topic.ID)
|
||||
area = topic.Title
|
||||
if targetUser_id == user.ID {
|
||||
post_act = " your post in"
|
||||
}
|
||||
default:
|
||||
return "", errors.New("Invalid elementType")
|
||||
}
|
||||
|
||||
switch(event) {
|
||||
case "like":
|
||||
if elementType == "user" {
|
||||
act = "likes"
|
||||
end_frag = ""
|
||||
if targetUser.ID == user.ID {
|
||||
area = "you"
|
||||
}
|
||||
} else {
|
||||
act = "liked"
|
||||
}
|
||||
case "mention":
|
||||
if elementType == "user" {
|
||||
act = "mentioned you on"
|
||||
} else {
|
||||
act = "mentioned you in"
|
||||
post_act = ""
|
||||
}
|
||||
case "reply": act = "replied to"
|
||||
}
|
||||
|
||||
return `{"msg":"{0} ` + start_frag + act + post_act + ` {1}` + end_frag + `","sub":["` + actor.Name + `","` + area + `"],"path":"` + url + `","avatar":"` + actor.Avatar + `"}`, nil
|
||||
}
|
182
gen_mysql.go
182
gen_mysql.go
@ -40,7 +40,17 @@ var create_reply_stmt *sql.Stmt
|
||||
var create_action_reply_stmt *sql.Stmt
|
||||
var create_like_stmt *sql.Stmt
|
||||
var add_activity_stmt *sql.Stmt
|
||||
var notify_one_stmt *sql.Stmt
|
||||
var register_stmt *sql.Stmt
|
||||
var create_profile_reply_stmt *sql.Stmt
|
||||
var create_forum_stmt *sql.Stmt
|
||||
var add_forum_perms_to_forum_stmt *sql.Stmt
|
||||
var add_plugin_stmt *sql.Stmt
|
||||
var add_theme_stmt *sql.Stmt
|
||||
var create_group_stmt *sql.Stmt
|
||||
var add_modlog_entry_stmt *sql.Stmt
|
||||
var add_adminlog_entry_stmt *sql.Stmt
|
||||
var add_forum_perms_to_group_stmt *sql.Stmt
|
||||
var add_replies_to_topic_stmt *sql.Stmt
|
||||
var remove_replies_from_topic_stmt *sql.Stmt
|
||||
var add_topics_to_forum_stmt *sql.Stmt
|
||||
@ -60,6 +70,22 @@ var set_avatar_stmt *sql.Stmt
|
||||
var set_username_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 edit_profile_reply_stmt *sql.Stmt
|
||||
var delete_forum_stmt *sql.Stmt
|
||||
var update_forum_stmt *sql.Stmt
|
||||
var update_setting_stmt *sql.Stmt
|
||||
var update_plugin_stmt *sql.Stmt
|
||||
var update_theme_stmt *sql.Stmt
|
||||
var update_user_stmt *sql.Stmt
|
||||
var update_group_perms_stmt *sql.Stmt
|
||||
var update_group_rank_stmt *sql.Stmt
|
||||
var update_group_stmt *sql.Stmt
|
||||
|
||||
func gen_mysql() (err error) {
|
||||
if debug {
|
||||
@ -270,12 +296,72 @@ func gen_mysql() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing notify_one statement.")
|
||||
notify_one_stmt, err = db.Prepare("INSERT INTO `activity_stream_matches`(`watcher`,`asid`) VALUES (?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing register statement.")
|
||||
register_stmt, err = db.Prepare("INSERT INTO `users`(`name`,`email`,`password`,`salt`,`group`,`is_super_admin`,`session`,`active`,`message`) VALUES (?,?,?,?,?,0,?,?,'')")
|
||||
if err != nil {
|
||||
return 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 {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing create_forum statement.")
|
||||
create_forum_stmt, err = db.Prepare("INSERT INTO `forums`(`name`,`desc`,`active`,`preset`) VALUES (?,?,?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_forum_perms_to_forum statement.")
|
||||
add_forum_perms_to_forum_stmt, err = db.Prepare("INSERT INTO `forums_permissions`(`gid`,`fid`,`preset`,`permissions`) VALUES (?,?,?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_plugin statement.")
|
||||
add_plugin_stmt, err = db.Prepare("INSERT INTO `plugins`(`uname`,`active`) VALUES (?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_theme statement.")
|
||||
add_theme_stmt, err = db.Prepare("INSERT INTO `themes`(`uname`,`default`) VALUES (?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing create_group statement.")
|
||||
create_group_stmt, err = db.Prepare("INSERT INTO `users_groups`(`name`,`tag`,`is_admin`,`is_mod`,`is_banned`,`permissions`) VALUES (?,?,?,?,?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_modlog_entry statement.")
|
||||
add_modlog_entry_stmt, err = db.Prepare("INSERT INTO `moderation_logs`(`action`,`elementID`,`elementType`,`ipaddress`,`actorID`,`doneAt`) VALUES (?,?,?,?,?,NOW())")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_adminlog_entry statement.")
|
||||
add_adminlog_entry_stmt, err = db.Prepare("INSERT INTO `administration_logs`(`action`,`elementID`,`elementType`,`ipaddress`,`actorID`,`doneAt`) VALUES (?,?,?,?,?,NOW())")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_forum_perms_to_group statement.")
|
||||
add_forum_perms_to_group_stmt, err = db.Prepare("REPLACE INTO `forums_permissions`(`gid`,`fid`,`preset`,`permissions`) VALUES (?,?,?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_replies_to_topic statement.")
|
||||
add_replies_to_topic_stmt, err = db.Prepare("UPDATE `topics` SET `postCount` = `postCount` + ?,`lastReplyAt` = NOW() WHERE `tid` = ? ")
|
||||
if err != nil {
|
||||
@ -389,6 +475,102 @@ func gen_mysql() (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_user_level statement.")
|
||||
update_user_level_stmt, err = db.Prepare("UPDATE `users` SET `level` = ? WHERE `uid` = ? ")
|
||||
if err != nil {
|
||||
return 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 {
|
||||
return 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 {
|
||||
return 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 {
|
||||
return 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 {
|
||||
return 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 {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing edit_profile_reply statement.")
|
||||
edit_profile_reply_stmt, err = db.Prepare("UPDATE `users_replies` SET `content` = ?,`parsed_content` = ? WHERE `rid` = ? ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing delete_forum statement.")
|
||||
delete_forum_stmt, err = db.Prepare("UPDATE `forums` SET `name` = '',`active` = 0 WHERE `fid` = ? ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_forum statement.")
|
||||
update_forum_stmt, err = db.Prepare("UPDATE `forums` SET `name` = ?,`desc` = ?,`active` = ?,`preset` = ? WHERE `fid` = ? ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_setting statement.")
|
||||
update_setting_stmt, err = db.Prepare("UPDATE `settings` SET `content` = ? WHERE `name` = ? ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_plugin statement.")
|
||||
update_plugin_stmt, err = db.Prepare("UPDATE `plugins` SET `active` = ? WHERE `uname` = ? ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_theme statement.")
|
||||
update_theme_stmt, err = db.Prepare("UPDATE `themes` SET `default` = ? WHERE `uname` = ? ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_user statement.")
|
||||
update_user_stmt, err = db.Prepare("UPDATE `users` SET `name` = ?,`email` = ?,`group` = ? WHERE `uid` = ? ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_group_perms statement.")
|
||||
update_group_perms_stmt, err = db.Prepare("UPDATE `users_groups` SET `permissions` = ? WHERE `gid` = ? ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_group_rank statement.")
|
||||
update_group_rank_stmt, err = db.Prepare("UPDATE `users_groups` SET `is_admin` = ?,`is_mod` = ?,`is_banned` = ? WHERE `gid` = ? ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_group statement.")
|
||||
update_group_stmt, err = db.Prepare("UPDATE `users_groups` SET `name` = ?,`tag` = ? WHERE `gid` = ? ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
118
general_test.go
118
general_test.go
@ -1,34 +1,40 @@
|
||||
package main
|
||||
import "os"
|
||||
import "fmt"
|
||||
import "log"
|
||||
import "bytes"
|
||||
import "strings"
|
||||
import "strconv"
|
||||
import "math/rand"
|
||||
import "testing"
|
||||
import "net/http"
|
||||
import "net/http/httptest"
|
||||
import "io/ioutil"
|
||||
import "database/sql"
|
||||
import "runtime/pprof"
|
||||
|
||||
//import _ "github.com/go-sql-driver/mysql"
|
||||
//import "github.com/erikstmartin/go-testdb"
|
||||
//import "github.com/husobee/vestigo"
|
||||
import (
|
||||
"os"
|
||||
"fmt"
|
||||
"log"
|
||||
"bytes"
|
||||
"strings"
|
||||
"strconv"
|
||||
//"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"io/ioutil"
|
||||
"database/sql"
|
||||
"runtime/pprof"
|
||||
|
||||
//_ "github.com/go-sql-driver/mysql"
|
||||
//"github.com/erikstmartin/go-testdb"
|
||||
//"github.com/husobee/vestigo"
|
||||
)
|
||||
|
||||
var db_test *sql.DB
|
||||
var db_prod *sql.DB
|
||||
var db_test, db_prod *sql.DB
|
||||
var gloinited bool = false
|
||||
|
||||
func gloinit() {
|
||||
debug = false
|
||||
nogrouplog = true
|
||||
//nogrouplog = true
|
||||
|
||||
// init_database is a little noisy for a benchmark
|
||||
//discard := ioutil.Discard
|
||||
//log.SetOutput(discard)
|
||||
|
||||
startTime = time.Now()
|
||||
timeLocation = startTime.Location()
|
||||
|
||||
init_themes()
|
||||
err := init_database()
|
||||
if err != nil {
|
||||
@ -352,7 +358,7 @@ func BenchmarkForumsGuestRouteParallel(b *testing.B) {
|
||||
}
|
||||
|
||||
|
||||
func BenchmarkRoutesSerial(b *testing.B) {
|
||||
/*func BenchmarkRoutesSerial(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
admin, err := users.CascadeGet(1)
|
||||
if err != nil {
|
||||
@ -404,13 +410,13 @@ func BenchmarkRoutesSerial(b *testing.B) {
|
||||
gloinit()
|
||||
}
|
||||
|
||||
/*f, err := os.Create("routes_bench_cpu.prof")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
pprof.StartCPUProfile(f)*/
|
||||
//defer pprof.StopCPUProfile()
|
||||
//pprof.StopCPUProfile()
|
||||
//f, err := os.Create("routes_bench_cpu.prof")
|
||||
//if err != nil {
|
||||
// log.Fatal(err)
|
||||
//}
|
||||
//pprof.StartCPUProfile(f)
|
||||
///defer pprof.StopCPUProfile()
|
||||
///pprof.StopCPUProfile()
|
||||
|
||||
b.Run("static_recorder", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
@ -490,11 +496,11 @@ func BenchmarkRoutesSerial(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)*/
|
||||
//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()
|
||||
@ -508,11 +514,11 @@ func BenchmarkRoutesSerial(b *testing.B) {
|
||||
}
|
||||
|
||||
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)*/
|
||||
//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()
|
||||
@ -525,11 +531,11 @@ func BenchmarkRoutesSerial(b *testing.B) {
|
||||
//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)*/
|
||||
//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()
|
||||
@ -573,11 +579,11 @@ func BenchmarkRoutesSerial(b *testing.B) {
|
||||
}
|
||||
})
|
||||
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)*/
|
||||
//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()
|
||||
@ -585,7 +591,7 @@ func BenchmarkRoutesSerial(b *testing.B) {
|
||||
}
|
||||
//pprof.StopCPUProfile()
|
||||
})
|
||||
}
|
||||
}*/
|
||||
|
||||
func BenchmarkQueryTopicParallel(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
@ -1224,7 +1230,7 @@ func TestStaticRoute(t *testing.T) {
|
||||
fmt.Println("No problems found in the static route!")
|
||||
}
|
||||
|
||||
func TestTopicAdminRoute(t *testing.T) {
|
||||
/*func TestTopicAdminRoute(t *testing.T) {
|
||||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
@ -1256,9 +1262,9 @@ func TestTopicAdminRoute(t *testing.T) {
|
||||
panic("HTTP Error!")
|
||||
}
|
||||
fmt.Println("No problems found in the topic-admin route!")
|
||||
}
|
||||
}*/
|
||||
|
||||
func TestTopicGuestRoute(t *testing.T) {
|
||||
/*func TestTopicGuestRoute(t *testing.T) {
|
||||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
@ -1276,7 +1282,7 @@ func TestTopicGuestRoute(t *testing.T) {
|
||||
panic("HTTP Error!")
|
||||
}
|
||||
fmt.Println("No problems found in the topic-guest route!")
|
||||
}
|
||||
}*/
|
||||
|
||||
func TestForumsAdminRoute(t *testing.T) {
|
||||
if !gloinited {
|
||||
@ -1331,7 +1337,7 @@ func TestForumsGuestRoute(t *testing.T) {
|
||||
fmt.Println("No problems found in the forums-guest route!")
|
||||
}
|
||||
|
||||
func TestForumAdminRoute(t *testing.T) {
|
||||
/*func TestForumAdminRoute(t *testing.T) {
|
||||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
@ -1362,9 +1368,9 @@ func TestForumAdminRoute(t *testing.T) {
|
||||
panic("HTTP Error!")
|
||||
}
|
||||
fmt.Println("No problems found in the forum-admin route!")
|
||||
}
|
||||
}*/
|
||||
|
||||
func TestForumGuestRoute(t *testing.T) {
|
||||
/*func TestForumGuestRoute(t *testing.T) {
|
||||
if !gloinited {
|
||||
gloinit()
|
||||
}
|
||||
@ -1382,7 +1388,7 @@ func TestForumGuestRoute(t *testing.T) {
|
||||
panic("HTTP Error!")
|
||||
}
|
||||
fmt.Println("No problems found in the forum-guest route!")
|
||||
}
|
||||
}*/
|
||||
|
||||
/*func TestAlerts(t *testing.T) {
|
||||
if !gloinited {
|
||||
|
193
mysql.go
193
mysql.go
@ -16,49 +16,23 @@ var db_collation string = "utf8mb4_general_ci"
|
||||
var get_topic_replies_offset_stmt *sql.Stmt // I'll need to rewrite this one to stop it hard-coding the per page setting before moving it to the query generator
|
||||
var get_forum_topics_offset_stmt *sql.Stmt
|
||||
var notify_watchers_stmt *sql.Stmt
|
||||
var notify_one_stmt *sql.Stmt
|
||||
var add_subscription_stmt *sql.Stmt
|
||||
var delete_reply_stmt *sql.Stmt
|
||||
var delete_topic_stmt *sql.Stmt
|
||||
var get_activity_feed_by_watcher_stmt *sql.Stmt
|
||||
var get_activity_count_by_watcher_stmt *sql.Stmt
|
||||
var add_email_stmt *sql.Stmt
|
||||
var update_email_stmt *sql.Stmt
|
||||
var verify_email_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
|
||||
|
||||
var create_forum_stmt *sql.Stmt
|
||||
var delete_forum_stmt *sql.Stmt
|
||||
var update_forum_stmt *sql.Stmt
|
||||
var forum_entry_exists_stmt *sql.Stmt
|
||||
var group_entry_exists_stmt *sql.Stmt
|
||||
var delete_forum_perms_by_forum_stmt *sql.Stmt
|
||||
var add_forum_perms_to_forum_stmt *sql.Stmt
|
||||
var add_forum_perms_to_forum_admins_stmt *sql.Stmt
|
||||
var add_forum_perms_to_forum_staff_stmt *sql.Stmt
|
||||
var add_forum_perms_to_forum_members_stmt *sql.Stmt
|
||||
var add_forum_perms_to_group_stmt *sql.Stmt
|
||||
//var forum_perm_exists_for_group_stmt *sql.Stmt
|
||||
var update_forum_perms_for_group_stmt *sql.Stmt
|
||||
var update_setting_stmt *sql.Stmt
|
||||
var add_plugin_stmt *sql.Stmt
|
||||
var update_plugin_stmt *sql.Stmt
|
||||
var update_user_stmt *sql.Stmt
|
||||
var update_group_perms_stmt *sql.Stmt
|
||||
var update_group_rank_stmt *sql.Stmt
|
||||
var update_group_stmt *sql.Stmt
|
||||
var create_group_stmt *sql.Stmt
|
||||
var add_theme_stmt *sql.Stmt
|
||||
var update_theme_stmt *sql.Stmt
|
||||
var add_modlog_entry_stmt *sql.Stmt
|
||||
var add_adminlog_entry_stmt *sql.Stmt
|
||||
var todays_post_count_stmt *sql.Stmt
|
||||
var todays_topic_count_stmt *sql.Stmt
|
||||
var todays_report_count_stmt *sql.Stmt
|
||||
@ -112,12 +86,6 @@ func init_database() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing notify_one statement.")
|
||||
notify_one_stmt, err = db.Prepare("INSERT INTO activity_stream_matches(watcher,asid) VALUES(?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_subscription statement.")
|
||||
add_subscription_stmt, err = db.Prepare("INSERT INTO activity_subscriptions(user,targetID,targetType,level) VALUES(?,?,?,2)")
|
||||
if err != nil {
|
||||
@ -137,7 +105,13 @@ func init_database() (err error) {
|
||||
}
|
||||
|
||||
log.Print("Preparing get_activity_feed_by_watcher statement.")
|
||||
get_activity_feed_by_watcher_stmt, err = db.Prepare("SELECT activity_stream_matches.asid, activity_stream.actor, activity_stream.targetUser, activity_stream.event, activity_stream.elementType, activity_stream.elementID FROM `activity_stream_matches` INNER JOIN `activity_stream` ON activity_stream_matches.asid = activity_stream.asid AND activity_stream_matches.watcher != activity_stream.actor WHERE `watcher` = ?")
|
||||
get_activity_feed_by_watcher_stmt, err = db.Prepare("SELECT activity_stream_matches.asid, activity_stream.actor, activity_stream.targetUser, activity_stream.event, activity_stream.elementType, activity_stream.elementID FROM `activity_stream_matches` INNER JOIN `activity_stream` ON activity_stream_matches.asid = activity_stream.asid AND activity_stream_matches.watcher != activity_stream.actor WHERE `watcher` = ? ORDER BY activity_stream.asid ASC LIMIT 8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing get_activity_count_by_watcher statement.")
|
||||
get_activity_count_by_watcher_stmt, err = db.Prepare("SELECT count(*) FROM `activity_stream_matches` INNER JOIN `activity_stream` ON activity_stream_matches.asid = activity_stream.asid AND activity_stream_matches.watcher != activity_stream.actor WHERE `watcher` = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -160,79 +134,12 @@ func init_database() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_user_level statement.")
|
||||
update_user_level_stmt, err = db.Prepare("UPDATE users SET level = ? WHERE uid = ?")
|
||||
if err != nil {
|
||||
return 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 {
|
||||
return 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 {
|
||||
return 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 {
|
||||
return 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 {
|
||||
return 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 {
|
||||
return 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 {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing edit_profile_reply statement.")
|
||||
edit_profile_reply_stmt, err = db.Prepare("UPDATE users_replies SET content = ?, parsed_content = ? WHERE rid = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing delete_profile_reply statement.")
|
||||
delete_profile_reply_stmt, err = db.Prepare("DELETE FROM users_replies WHERE rid = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing create_forum statement.")
|
||||
create_forum_stmt, err = db.Prepare("INSERT INTO forums(`name`,`desc`,`active`,`preset`) VALUES(?,?,?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing delete_forum statement.")
|
||||
//delete_forum_stmt, err = db.Prepare("delete from forums where fid = ?")
|
||||
delete_forum_stmt, err = db.Prepare("update forums set name= '', active = 0 where fid = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_forum statement.")
|
||||
update_forum_stmt, err = db.Prepare("update forums set `name` = ?, `desc` = ?, `active` = ?, `preset` = ? where fid = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing forum_entry_exists statement.")
|
||||
forum_entry_exists_stmt, err = db.Prepare("SELECT `fid` FROM `forums` WHERE `name` = '' order by fid asc limit 1")
|
||||
if err != nil {
|
||||
@ -251,12 +158,6 @@ func init_database() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_forum_perms_to_forum statement.")
|
||||
add_forum_perms_to_forum_stmt, err = db.Prepare("INSERT INTO forums_permissions(gid,fid,preset,permissions) VALUES(?,?,?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_forum_perms_to_forum_admins statement.")
|
||||
add_forum_perms_to_forum_admins_stmt, err = db.Prepare("INSERT INTO forums_permissions(gid,fid,preset,permissions) SELECT `gid`,? AS fid,? AS preset,? AS permissions FROM users_groups WHERE is_admin = 1")
|
||||
if err != nil {
|
||||
@ -275,84 +176,6 @@ func init_database() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_forum_perms_to_group statement.")
|
||||
add_forum_perms_to_group_stmt, err = db.Prepare("REPLACE INTO forums_permissions(gid,fid,preset,permissions) VALUES(?,?,?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_setting statement.")
|
||||
update_setting_stmt, err = db.Prepare("UPDATE settings SET content = ? WHERE name = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_plugin statement.")
|
||||
add_plugin_stmt, err = db.Prepare("INSERT INTO plugins(uname,active) VALUES(?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_plugin statement.")
|
||||
update_plugin_stmt, err = db.Prepare("UPDATE plugins SET active = ? WHERE uname = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_theme statement.")
|
||||
add_theme_stmt, err = db.Prepare("INSERT INTO `themes`(`uname`,`default`) VALUES(?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_theme statement.")
|
||||
update_theme_stmt, err = db.Prepare("update `themes` set `default` = ? where `uname` = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_user statement.")
|
||||
update_user_stmt, err = db.Prepare("update `users` set `name` = ?,`email` = ?,`group` = ? where `uid` = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_group_rank statement.")
|
||||
update_group_perms_stmt, err = db.Prepare("update `users_groups` set `permissions` = ? where `gid` = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_group_rank statement.")
|
||||
update_group_rank_stmt, err = db.Prepare("update `users_groups` set `is_admin` = ?, `is_mod` = ?, `is_banned` = ? where `gid` = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing update_group statement.")
|
||||
update_group_stmt, err = db.Prepare("update `users_groups` set `name` = ?, `tag` = ? where `gid` = ?")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing create_group statement.")
|
||||
create_group_stmt, err = db.Prepare("INSERT INTO users_groups(name,tag,is_admin,is_mod,is_banned,permissions) VALUES(?,?,?,?,?,?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_modlog_entry statement.")
|
||||
add_modlog_entry_stmt, err = db.Prepare("INSERT INTO moderation_logs(action,elementID,elementType,ipaddress,actorID,doneAt) VALUES(?,?,?,?,?,NOW())")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing add_adminlog_entry statement.")
|
||||
add_adminlog_entry_stmt, err = db.Prepare("INSERT INTO moderation_logs(action,elementID,elementType,ipaddress,actorID,doneAt) VALUES(?,?,?,?,?,NOW())")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Print("Preparing todays_post_count statement.")
|
||||
todays_post_count_stmt, err = db.Prepare("select count(*) from replies where createdAt BETWEEN (now() - interval 1 day) and now()")
|
||||
if err != nil {
|
||||
|
@ -193,8 +193,8 @@ CREATE TABLE `administration_logs`(
|
||||
|
||||
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 settings(`name`,`content`,`type`) VALUES ('bigpost_min_words','250','int');
|
||||
INSERT INTO settings(`name`,`content`,`type`) VALUES ('megapost_min_words','1000','int');
|
||||
INSERT INTO themes(`uname`,`default`) VALUES ('tempra-simple',1);
|
||||
|
||||
INSERT INTO users(`name`,`password`,`email`,`group`,`is_super_admin`,`createdAt`,`lastActiveAt`,`message`,`last_ip`)
|
||||
|
@ -2,21 +2,35 @@
|
||||
|
||||
package main
|
||||
|
||||
import "errors"
|
||||
import "net/http"
|
||||
|
||||
var ws_hub WS_Hub
|
||||
var ws_nouser error = errors.New("This user isn't connected via WebSockets")
|
||||
|
||||
type WS_Hub struct
|
||||
{
|
||||
}
|
||||
|
||||
func (_ *WS_Hub) GuestCount() int {
|
||||
func (_ *WS_Hub) guest_count() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *WS_Hub) UserCount() int {
|
||||
func (_ *WS_Hub) user_count() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (hub *WS_Hub) broadcast_message(_ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hub *WS_Hub) push_message(_ int, _ string) error {
|
||||
return ws_nouser
|
||||
}
|
||||
|
||||
func(hub *WS_Hub) push_alert(_ int, _ string, _ string, _ int, _ int, _ int) error {
|
||||
return ws_nouser
|
||||
}
|
||||
|
||||
func route_websockets(_ http.ResponseWriter, _ *http.Request) {
|
||||
}
|
||||
|
@ -137,8 +137,8 @@ func route_panel(w http.ResponseWriter, r *http.Request){
|
||||
}
|
||||
|
||||
if enable_websockets {
|
||||
uonline := ws_hub.UserCount()
|
||||
gonline := ws_hub.GuestCount()
|
||||
uonline := ws_hub.user_count()
|
||||
gonline := ws_hub.guest_count()
|
||||
totonline := uonline + gonline
|
||||
|
||||
var onlineColour string
|
||||
@ -489,7 +489,6 @@ func route_panel_forums_edit_perms_submit(w http.ResponseWriter, r *http.Request
|
||||
return
|
||||
}
|
||||
|
||||
//_, err = update_forum_perms_for_group_stmt.Exec(perm_preset,perms,gid,fid)
|
||||
_, err = add_forum_perms_to_group_stmt.Exec(gid,fid,perm_preset,perms)
|
||||
if err != nil {
|
||||
InternalErrorJSQ(err,w,r,is_js)
|
||||
|
@ -1,4 +1,6 @@
|
||||
var form_vars = {};
|
||||
var alertList = [];
|
||||
var alertCount = 0;
|
||||
|
||||
function post_link(event)
|
||||
{
|
||||
@ -17,7 +19,6 @@ function load_alerts(menu_alerts)
|
||||
url:'/api/?action=get&module=alerts&format=json',
|
||||
success: function(data) {
|
||||
if("errmsg" in data) {
|
||||
//console.log(data.errmsg);
|
||||
menu_alerts.find(".alertList").html("<div class='alertItem'>"+data.errmsg+"</div>");
|
||||
return;
|
||||
}
|
||||
@ -36,12 +37,14 @@ function load_alerts(menu_alerts)
|
||||
}
|
||||
}
|
||||
|
||||
if("avatar" in msg)
|
||||
{
|
||||
if("avatar" in msg) {
|
||||
alist += "<div class='alertItem withAvatar' style='background-image:url(\""+msg.avatar+"\");'><a class='text' href=\""+msg.path+"\">"+mmsg+"</a></div>";
|
||||
alertList.push("<div class='alertItem withAvatar' style='background-image:url(\""+msg.avatar+"\");'><a class='text' href=\""+msg.path+"\">"+mmsg+"</a></div>");
|
||||
anyAvatar = true
|
||||
} else {
|
||||
alist += "<div class='alertItem'><a href=\""+msg.path+"\" class='text'>"+mmsg+"</a></div>";
|
||||
alertList.push("<div class='alertItem'><a href=\""+msg.path+"\" class='text'>"+mmsg+"</a></div>");
|
||||
}
|
||||
else alist += "<div class='alertItem'><a href=\""+msg.path+"\" class='text'>"+mmsg+"</a></div>";
|
||||
//console.log(msg);
|
||||
//console.log(mmsg);
|
||||
}
|
||||
@ -52,14 +55,19 @@ function load_alerts(menu_alerts)
|
||||
//if(anyAvatar) menu_alerts.addClass("hasAvatars");
|
||||
}
|
||||
menu_alerts.find(".alertList").html(alist);
|
||||
if(data.msgs.length != 0) menu_alerts.find(".alert_counter").text(data.msgs.length);
|
||||
if(data.msgCount != 0) menu_alerts.find(".alert_counter").text(data.msgCount);
|
||||
alertCount = data.msgCount;
|
||||
},
|
||||
error: function(magic,theStatus,error) {
|
||||
try {
|
||||
var data = JSON.parse(magic.responseText);
|
||||
if("errmsg" in data) errtxt = data.errmsg;
|
||||
else errtxt = "Unable to get the alerts";
|
||||
} catch(e) { errtxt = "Unable to get the alerts"; }
|
||||
} catch(err) {
|
||||
errtxt = "Unable to get the alerts";
|
||||
console.log(magic.responseText);
|
||||
console.log(err);
|
||||
}
|
||||
menu_alerts.find(".alertList").html("<div class='alertItem'>"+errtxt+"</div>");
|
||||
}
|
||||
});
|
||||
@ -81,9 +89,7 @@ $(document).ready(function(){
|
||||
lastN++;
|
||||
}
|
||||
}
|
||||
if(data.length > lastIndex) {
|
||||
out[out.length - 1] += data.substring(lastIndex);
|
||||
}
|
||||
if(data.length > lastIndex) out[out.length - 1] += data.substring(lastIndex);
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -96,8 +102,37 @@ $(document).ready(function(){
|
||||
conn = false;
|
||||
}
|
||||
conn.onmessage = function(event) {
|
||||
//console.log("WS_Message:");
|
||||
//console.log(event.data);
|
||||
//console.log("WS_Message: ",event.data);
|
||||
if(event.data[0] == "{") {
|
||||
try {
|
||||
var data = JSON.parse(event.data);
|
||||
} catch(err) { console.log(err); }
|
||||
|
||||
if ("msg" in data) {
|
||||
var msg = data.msg
|
||||
if("sub" in data) {
|
||||
for(var i = 0; i < data.sub.length; i++) {
|
||||
msg = msg.replace("\{"+i+"\}", data.sub[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if("avatar" in data) alertList.push("<div class='alertItem withAvatar' style='background-image:url(\""+data.avatar+"\");'><a class='text' href=\""+data.path+"\">"+msg+"</a></div>");
|
||||
else alertList.push("<div class='alertItem'><a href=\""+data.path+"\" class='text'>"+msg+"</a></div>");
|
||||
if(alertList.length > 8) alertList.shift();
|
||||
//console.log("post alertList",alertList);
|
||||
alertCount++;
|
||||
|
||||
var alist = ""
|
||||
for (var i = 0; i < alertList.length; i++) {
|
||||
alist += alertList[i];
|
||||
}
|
||||
|
||||
//console.log(alist);
|
||||
$("#general_alerts").find(".alertList").html(alist); // Add support for other alert feeds like PM Alerts
|
||||
$("#general_alerts").find(".alert_counter").text(alertCount);
|
||||
}
|
||||
}
|
||||
|
||||
var messages = event.data.split('\r');
|
||||
for(var i = 0; i < messages.length; i++) {
|
||||
//console.log("Message:");
|
||||
@ -266,9 +301,6 @@ $(document).ready(function(){
|
||||
var newContent = $(this).find('input').eq(0).val();
|
||||
this.innerHTML = newContent;
|
||||
}
|
||||
//console.log("field_name",field_name);
|
||||
//console.log("field_type",field_type);
|
||||
//console.log("newContent",newContent);
|
||||
this.setAttribute("data-value",newContent);
|
||||
out_data[field_name] = newContent;
|
||||
});
|
||||
|
@ -61,7 +61,7 @@ type DB_Setter struct {
|
||||
type DB_Adapter interface {
|
||||
get_name() string
|
||||
simple_insert(string,string,string,string) error
|
||||
//simple_replace(string,string,[]string,string) error
|
||||
simple_replace(string,string,string,string) error
|
||||
simple_update(string,string,string,string) error
|
||||
simple_select(string,string,string,string,string/*,int,int*/) error
|
||||
simple_left_join(string,string,string,string,string,string,string/*,int,int*/) error
|
||||
@ -79,6 +79,30 @@ func main() {
|
||||
}
|
||||
|
||||
func write_statements(adapter DB_Adapter) error {
|
||||
err := write_selects(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = write_joins(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = write_inserts(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = write_replaces(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = write_updates(adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func write_selects(adapter DB_Adapter) error {
|
||||
// url_prefix and url_name will be removed from this query in a later commit
|
||||
adapter.simple_select("get_user","users","name, group, is_super_admin, avatar, message, url_prefix, url_name, level","uid = ?","")
|
||||
|
||||
@ -124,7 +148,10 @@ func write_statements(adapter DB_Adapter) error {
|
||||
adapter.simple_select("get_emails_by_user","emails","email, validated","uid = ?","")
|
||||
|
||||
adapter.simple_select("get_topic_basic","topics","title, content","tid = ?","")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func write_joins(adapter DB_Adapter) error {
|
||||
adapter.simple_left_join("get_topic_list","topics","users","topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar","topics.createdBy = users.uid","","topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC")
|
||||
|
||||
adapter.simple_left_join("get_topic_user","topics","users","topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level","topics.createdBy = users.uid","tid = ?","")
|
||||
@ -136,7 +163,10 @@ func write_statements(adapter DB_Adapter) error {
|
||||
adapter.simple_left_join("get_forum_topics","topics","users","topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, users.name, users.avatar","topics.createdBy = users.uid","topics.parentID = ?","topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy desc")
|
||||
|
||||
adapter.simple_left_join("get_profile_replies","users_replies","users","users_replies.rid, users_replies.content, users_replies.createdBy, users_replies.createdAt, users_replies.lastEdit, users_replies.lastEditBy, users.avatar, users.name, users.group","users_replies.createdBy = users.uid","users_replies.uid = ?","")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func write_inserts(adapter DB_Adapter) error {
|
||||
adapter.simple_insert("create_topic","topics","parentID,title,content,parsed_content,createdAt,lastReplyAt,ipaddress,words,createdBy","?,?,?,?,NOW(),NOW(),?,?,?")
|
||||
|
||||
adapter.simple_insert("create_report","topics","title,content,parsed_content,createdAt,lastReplyAt,createdBy,data,parentID,css_class","?,?,?,NOW(),NOW(),?,?,1,'report'")
|
||||
@ -149,11 +179,39 @@ func write_statements(adapter DB_Adapter) error {
|
||||
|
||||
adapter.simple_insert("add_activity","activity_stream","actor,targetUser,event,elementType,elementID","?,?,?,?,?")
|
||||
|
||||
adapter.simple_insert("notify_one","activity_stream_matches","watcher,asid","?,?")
|
||||
|
||||
// Add an admin version of register_stmt with more flexibility?
|
||||
// create_account_stmt, err = db.Prepare("INSERT INTO
|
||||
adapter.simple_insert("register","users","name, email, password, salt, group, is_super_admin, session, active, message","?,?,?,?,?,0,?,?,''")
|
||||
|
||||
adapter.simple_insert("create_profile_reply","users_replies","uid,content,parsed_content,createdAt,createdBy","?,?,?,NOW(),?")
|
||||
|
||||
adapter.simple_insert("create_forum","forums","name, desc, active, preset","?,?,?,?")
|
||||
|
||||
adapter.simple_insert("add_forum_perms_to_forum","forums_permissions","gid,fid,preset,permissions","?,?,?,?")
|
||||
|
||||
adapter.simple_insert("add_plugin","plugins","uname,active","?,?")
|
||||
|
||||
adapter.simple_insert("add_theme","themes","uname,default","?,?")
|
||||
|
||||
|
||||
adapter.simple_insert("create_group","users_groups","name, tag, is_admin, is_mod, is_banned, permissions","?,?,?,?,?,?")
|
||||
|
||||
adapter.simple_insert("add_modlog_entry","moderation_logs","action, elementID, elementType, ipaddress, actorID, doneAt","?,?,?,?,?,NOW()")
|
||||
|
||||
adapter.simple_insert("add_adminlog_entry","administration_logs","action, elementID, elementType, ipaddress, actorID, doneAt","?,?,?,?,?,NOW()")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func write_replaces(adapter DB_Adapter) error {
|
||||
adapter.simple_replace("add_forum_perms_to_group","forums_permissions","gid,fid,preset,permissions","?,?,?,?")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func write_updates(adapter DB_Adapter) error {
|
||||
adapter.simple_update("add_replies_to_topic","topics","postCount = postCount + ?, lastReplyAt = NOW()","tid = ?")
|
||||
|
||||
adapter.simple_update("remove_replies_from_topic","topics","postCount = postCount - ?","tid = ?")
|
||||
@ -192,6 +250,39 @@ func write_statements(adapter DB_Adapter) error {
|
||||
|
||||
adapter.simple_update("activate_user","users","active = 1","uid = ?")
|
||||
|
||||
adapter.simple_update("update_user_level","users","level = ?","uid = ?")
|
||||
|
||||
adapter.simple_update("increment_user_score","users","score = score + ?","uid = ?")
|
||||
|
||||
adapter.simple_update("increment_user_posts","users","posts = posts + ?","uid = ?")
|
||||
|
||||
adapter.simple_update("increment_user_bigposts","users","posts = posts + ?, bigposts = bigposts + ?","uid = ?")
|
||||
|
||||
adapter.simple_update("increment_user_megaposts","users","posts = posts + ?, bigposts = bigposts + ?, megaposts = megaposts + ?","uid = ?")
|
||||
|
||||
adapter.simple_update("increment_user_topics","users","topics = topics + ?","uid = ?")
|
||||
|
||||
adapter.simple_update("edit_profile_reply","users_replies","content = ?, parsed_content = ?","rid = ?")
|
||||
|
||||
//delete_forum_stmt, err = db.Prepare("delete from forums where fid = ?")
|
||||
adapter.simple_update("delete_forum","forums","name= '', active = 0","fid = ?")
|
||||
|
||||
adapter.simple_update("update_forum","forums","name = ?, desc = ?, active = ?, preset = ?","fid = ?")
|
||||
|
||||
adapter.simple_update("update_setting","settings","content = ?","name = ?")
|
||||
|
||||
adapter.simple_update("update_plugin","plugins","active = ?","uname = ?")
|
||||
|
||||
adapter.simple_update("update_theme","themes","default = ?","uname = ?")
|
||||
|
||||
adapter.simple_update("update_user","users","name = ?, email = ?, group = ?","uid = ?")
|
||||
|
||||
adapter.simple_update("update_group_perms","users_groups","permissions = ?","gid = ?")
|
||||
|
||||
adapter.simple_update("update_group_rank","users_groups","is_admin = ?, is_mod = ?, is_banned = ?","gid = ?")
|
||||
|
||||
adapter.simple_update("update_group","users_groups","name = ?, tag = ?","gid = ?")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,44 @@ func (adapter *Mysql_Adapter) simple_insert(name string, table string, columns s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) simple_replace(name string, table string, columns string, fields string) error {
|
||||
if name == "" {
|
||||
return errors.New("You need a name for this statement")
|
||||
}
|
||||
if table == "" {
|
||||
return errors.New("You need a name for this table")
|
||||
}
|
||||
if len(columns) == 0 {
|
||||
return errors.New("No columns found for simple_insert")
|
||||
}
|
||||
if len(fields) == 0 {
|
||||
return errors.New("No input data found for simple_insert")
|
||||
}
|
||||
|
||||
var querystr string = "REPLACE INTO `" + table + "`("
|
||||
|
||||
// Escape the column names, just in case we've used a reserved keyword
|
||||
for _, column := range _process_columns(columns) {
|
||||
if column.Type == "function" {
|
||||
querystr += column.Left + ","
|
||||
} else {
|
||||
querystr += "`" + column.Left + "`,"
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the trailing comma
|
||||
querystr = querystr[0:len(querystr) - 1]
|
||||
|
||||
querystr += ") VALUES ("
|
||||
for _, field := range _process_fields(fields) {
|
||||
querystr += field.Name + ","
|
||||
}
|
||||
querystr = querystr[0:len(querystr) - 1]
|
||||
|
||||
adapter.write_statement(name,querystr + ")")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (adapter *Mysql_Adapter) simple_update(name string, table string, set string, where string) error {
|
||||
if name == "" {
|
||||
return errors.New("You need a name for this statement")
|
||||
|
165
routes.go
165
routes.go
@ -3,7 +3,7 @@ package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
// "fmt"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"bytes"
|
||||
"regexp"
|
||||
@ -705,12 +705,12 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = add_replies_to_topic_stmt.Exec(1, tid)
|
||||
_, err = add_replies_to_topic_stmt.Exec(1,tid)
|
||||
if err != nil {
|
||||
InternalError(err,w,r)
|
||||
return
|
||||
}
|
||||
_, err = update_forum_cache_stmt.Exec(topic_name, tid, user.Name, user.ID, 1)
|
||||
_, err = update_forum_cache_stmt.Exec(topic_name,tid,user.Name,user.ID,1)
|
||||
if err != nil {
|
||||
InternalError(err,w,r)
|
||||
return
|
||||
@ -783,6 +783,11 @@ func route_like_topic(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if createdBy == user.ID {
|
||||
LocalError("You can't like your own topics",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
err = has_liked_topic_stmt.QueryRow(user.ID, tid).Scan(&tid)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
InternalError(err,w,r)
|
||||
@ -801,7 +806,6 @@ func route_like_topic(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
//score := words_to_score(words,true)
|
||||
score := 1
|
||||
_, err = create_like_stmt.Exec(score,tid,"topics",user.ID)
|
||||
if err != nil {
|
||||
@ -826,17 +830,15 @@ func route_like_topic(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
/*_, err = notify_watchers_stmt.Exec(lastId)
|
||||
if err != nil {
|
||||
InternalError(err,w,r)
|
||||
return
|
||||
}*/
|
||||
_, err = notify_one_stmt.Exec(createdBy,lastId)
|
||||
if err != nil {
|
||||
InternalError(err,w,r)
|
||||
return
|
||||
}
|
||||
|
||||
// Live alerts, if the poster is online and WebSockets is enabled
|
||||
_ = ws_hub.push_alert(createdBy,"like","topic",user.ID,createdBy,tid)
|
||||
|
||||
// Reload the topic...
|
||||
err = topics.Load(tid)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
@ -892,6 +894,11 @@ func route_reply_like_submit(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if createdBy == user.ID {
|
||||
LocalError("You can't like your own replies",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
err = has_liked_reply_stmt.QueryRow(user.ID, rid).Scan(&rid)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
InternalError(err,w,r)
|
||||
@ -910,7 +917,6 @@ func route_reply_like_submit(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
//score := words_to_score(words,false)
|
||||
score := 1
|
||||
_, err = create_like_stmt.Exec(score,rid,"replies",user.ID)
|
||||
if err != nil {
|
||||
@ -941,6 +947,13 @@ func route_reply_like_submit(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Live alerts, if the poster is online and WebSockets is enabled
|
||||
fmt.Println("Calling push_alert")
|
||||
err = ws_hub.push_alert(createdBy,"like","post",user.ID,createdBy,rid)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
|
||||
http.Redirect(w,r,"/topic/" + strconv.Itoa(tid),http.StatusSeeOther)
|
||||
}
|
||||
|
||||
@ -1764,12 +1777,18 @@ func route_api(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var msglist string
|
||||
var asid, actor_id, targetUser_id int
|
||||
var event, elementType string
|
||||
var elementID int
|
||||
//---
|
||||
var targetUser *User
|
||||
var msglist, event, elementType string
|
||||
var asid, actor_id, targetUser_id, elementID int
|
||||
var msgCount int
|
||||
|
||||
err = get_activity_count_by_watcher_stmt.QueryRow(user.ID).Scan(&msgCount)
|
||||
if err == sql.ErrNoRows {
|
||||
PreError("Couldn't find the parent topic",w,r)
|
||||
return
|
||||
} else if err != nil {
|
||||
InternalError(err,w,r)
|
||||
return
|
||||
}
|
||||
|
||||
rows, err := get_activity_feed_by_watcher_stmt.Query(user.ID)
|
||||
if err != nil {
|
||||
@ -1783,116 +1802,12 @@ func route_api(w http.ResponseWriter, r *http.Request) {
|
||||
InternalErrorJS(err,w,r)
|
||||
return
|
||||
}
|
||||
|
||||
actor, err := users.CascadeGet(actor_id)
|
||||
res, err := build_alert(event, elementType, actor_id, targetUser_id, elementID, user)
|
||||
if err != nil {
|
||||
LocalErrorJS("Unable to find the actor",w,r)
|
||||
LocalErrorJS(err.Error(),w,r)
|
||||
return
|
||||
}
|
||||
|
||||
/*if elementType != "forum" {
|
||||
targetUser, err = users.CascadeGet(targetUser_id)
|
||||
if err != nil {
|
||||
LocalErrorJS("Unable to find the target user",w,r)
|
||||
return
|
||||
}
|
||||
}*/
|
||||
|
||||
if event == "friend_invite" {
|
||||
msglist += `{"msg":"You received a friend invite from {0}","sub":["` + actor.Name + `"],"path":"\/user\/`+strconv.Itoa(actor.ID)+`","avatar":"`+strings.Replace(actor.Avatar,"/","\\/",-1)+`"},`
|
||||
continue
|
||||
}
|
||||
|
||||
/*
|
||||
"You received a friend invite from {user}"
|
||||
"{x}{mentioned you on}{user}{'s profile}"
|
||||
"{x}{mentioned you in}{topic}"
|
||||
"{x}{likes}{you}"
|
||||
"{x}{liked}{your topic}{topic}"
|
||||
"{x}{liked}{your post on}{user}{'s profile}" todo
|
||||
"{x}{liked}{your post in}{topic}"
|
||||
"{x}{replied to}{your post in}{topic}" todo
|
||||
"{x}{replied to}{topic}"
|
||||
"{x}{replied to}{your topic}{topic}"
|
||||
"{x}{created a new topic}{topic}"
|
||||
*/
|
||||
|
||||
var act, post_act, url, area string
|
||||
var start_frag, end_frag string
|
||||
switch(elementType) {
|
||||
case "forum":
|
||||
if event == "reply" {
|
||||
act = "created a new topic"
|
||||
topic, err := topics.CascadeGet(elementID)
|
||||
if err != nil {
|
||||
LocalErrorJS("Unable to find the linked topic",w,r)
|
||||
return
|
||||
}
|
||||
url = build_topic_url(elementID)
|
||||
area = topic.Title
|
||||
// Store the forum ID in the targetUser column instead of making a new one? o.O
|
||||
// Add an additional column for extra information later on when we add the ability to link directly to posts. We don't need the forum data for now..
|
||||
} else {
|
||||
act = "did something in a forum"
|
||||
}
|
||||
case "topic":
|
||||
topic, err := topics.CascadeGet(elementID)
|
||||
if err != nil {
|
||||
LocalErrorJS("Unable to find the linked topic",w,r)
|
||||
return
|
||||
}
|
||||
url = build_topic_url(elementID)
|
||||
area = topic.Title
|
||||
|
||||
if targetUser_id == user.ID {
|
||||
post_act = " your topic"
|
||||
}
|
||||
case "user":
|
||||
targetUser, err = users.CascadeGet(elementID)
|
||||
if err != nil {
|
||||
LocalErrorJS("Unable to find the target user",w,r)
|
||||
return
|
||||
}
|
||||
area = targetUser.Name
|
||||
end_frag = "'s profile"
|
||||
url = build_profile_url(elementID)
|
||||
case "post":
|
||||
topic, err := get_topic_by_reply(elementID)
|
||||
if err != nil {
|
||||
LocalErrorJS("Unable to find the target reply or parent topic",w,r)
|
||||
return
|
||||
}
|
||||
url = build_topic_url(topic.ID)
|
||||
area = topic.Title
|
||||
if targetUser_id == user.ID {
|
||||
post_act = " your post in"
|
||||
}
|
||||
default:
|
||||
LocalErrorJS("Invalid elementType",w,r)
|
||||
}
|
||||
|
||||
switch(event) {
|
||||
case "like":
|
||||
if elementType == "user" {
|
||||
act = "likes"
|
||||
end_frag = ""
|
||||
if targetUser.ID == user.ID {
|
||||
area = "you"
|
||||
}
|
||||
} else {
|
||||
act = "liked"
|
||||
}
|
||||
case "mention":
|
||||
if elementType == "user" {
|
||||
act = "mentioned you on"
|
||||
} else {
|
||||
act = "mentioned you in"
|
||||
post_act = ""
|
||||
}
|
||||
case "reply": act = "replied to"
|
||||
}
|
||||
|
||||
msglist += `{"msg":"{0} ` + start_frag + act + post_act + ` {1}` + end_frag + `","sub":["` + actor.Name + `","` + area + `"],"path":"` + url + `","avatar":"` + actor.Avatar + `"},`
|
||||
msglist += res + ","
|
||||
}
|
||||
|
||||
err = rows.Err()
|
||||
@ -1905,8 +1820,8 @@ func route_api(w http.ResponseWriter, r *http.Request) {
|
||||
if len(msglist) != 0 {
|
||||
msglist = msglist[0:len(msglist)-1]
|
||||
}
|
||||
w.Write([]byte(`{"msgs":[`+msglist+`]}`))
|
||||
//fmt.Println(`{"msgs":[`+msglist+`]}`)
|
||||
w.Write([]byte(`{"msgs":[` + msglist + `],"msgCount":` + strconv.Itoa(msgCount) + `}`))
|
||||
//fmt.Println(`{"msgs":[` + msglist + `],"msgCount":` + strconv.Itoa(msgCount) + `}`)
|
||||
//case "topics":
|
||||
//case "forums":
|
||||
//case "users":
|
||||
|
@ -43,7 +43,7 @@ func parseSetting(sname string, scontent string, stype string, constraint string
|
||||
if len(cons) < 2 {
|
||||
return "Invalid constraint! The second field wasn't set!"
|
||||
}
|
||||
|
||||
|
||||
con1, err := strconv.Atoi(cons[0])
|
||||
if err != nil {
|
||||
return "Invalid contraint! The constraint field wasn't an integer!"
|
||||
@ -52,12 +52,12 @@ func parseSetting(sname string, scontent string, stype string, constraint string
|
||||
if err != nil {
|
||||
return "Invalid contraint! The constraint field wasn't an integer!"
|
||||
}
|
||||
|
||||
|
||||
value, err := strconv.Atoi(scontent)
|
||||
if err != nil {
|
||||
return "Only integers are allowed in this setting x.x\nType mismatch in " + sname
|
||||
}
|
||||
|
||||
|
||||
if value < con1 || value > con2 {
|
||||
return "Only integers between a certain range are allowed in this setting"
|
||||
}
|
||||
@ -66,4 +66,4 @@ func parseSetting(sname string, scontent string, stype string, constraint string
|
||||
settings[sname] = scontent
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ var menu_6 []byte = []byte(`
|
||||
<li class="menu_left menu_login"><a href="/accounts/login/">Login</a></li>
|
||||
`)
|
||||
var menu_7 []byte = []byte(`
|
||||
<li class="menu_right menu_alerts">
|
||||
<li id="general_alerts" class="menu_right menu_alerts">
|
||||
<div class="alert_bell">🔔︎</div>
|
||||
<div class="alert_counter"></div>
|
||||
<div class="alertList"></div>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<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>
|
||||
{{end}}
|
||||
<li class="menu_right menu_alerts">
|
||||
<li id="general_alerts" class="menu_right menu_alerts">
|
||||
<div class="alert_bell">🔔︎</div>
|
||||
<div class="alert_counter"></div>
|
||||
<div class="alertList"></div>
|
||||
|
12
user.go
12
user.go
@ -484,9 +484,9 @@ func words_to_score(wcount int, topic bool) (score int) {
|
||||
score = 1
|
||||
}
|
||||
|
||||
if wcount > settings["megapost_min_chars"].(int) {
|
||||
if wcount >= settings["megapost_min_words"].(int) {
|
||||
score += 4
|
||||
} else if wcount > settings["bigpost_min_chars"].(int) {
|
||||
} else if wcount >= settings["bigpost_min_words"].(int) {
|
||||
score += 1
|
||||
}
|
||||
return score
|
||||
@ -503,13 +503,13 @@ func increase_post_user_stats(wcount int, uid int, topic bool, user User) error
|
||||
base_score = 2
|
||||
}
|
||||
|
||||
if wcount > settings["megapost_min_chars"].(int) {
|
||||
if wcount >= settings["megapost_min_words"].(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) {
|
||||
} else if wcount >= settings["bigpost_min_words"].(int) {
|
||||
_, err := increment_user_bigposts_stmt.Exec(1,1,uid)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -542,13 +542,13 @@ func decrease_post_user_stats(wcount int, uid int, topic bool, user User) error
|
||||
base_score = -2
|
||||
}
|
||||
|
||||
if wcount > settings["megapost_min_chars"].(int) {
|
||||
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) {
|
||||
} else if wcount >= settings["bigpost_min_chars"].(int) {
|
||||
_, err := increment_user_bigposts_stmt.Exec(-1,-1,uid)
|
||||
if err != nil {
|
||||
return err
|
||||
|
165
websockets.go
165
websockets.go
@ -2,17 +2,20 @@
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
import "sync"
|
||||
import "time"
|
||||
import "bytes"
|
||||
import "strconv"
|
||||
import "runtime"
|
||||
import "net/http"
|
||||
import(
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
"bytes"
|
||||
"strconv"
|
||||
"errors"
|
||||
"runtime"
|
||||
"net/http"
|
||||
|
||||
import "github.com/gorilla/websocket"
|
||||
import "github.com/shirou/gopsutil/cpu"
|
||||
import "github.com/shirou/gopsutil/mem"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
"github.com/shirou/gopsutil/mem"
|
||||
)
|
||||
|
||||
type WS_User struct
|
||||
{
|
||||
@ -30,6 +33,7 @@ type WS_Hub struct
|
||||
|
||||
var ws_hub WS_Hub
|
||||
var ws_upgrader = websocket.Upgrader{ReadBufferSize:1024,WriteBufferSize:1024}
|
||||
var ws_nouser error = errors.New("This user isn't connected via WebSockets")
|
||||
|
||||
func init() {
|
||||
enable_websockets = true
|
||||
@ -40,18 +44,76 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func (hub *WS_Hub) GuestCount() int {
|
||||
func (hub *WS_Hub) guest_count() int {
|
||||
defer hub.guests.RUnlock()
|
||||
hub.guests.RLock()
|
||||
return len(hub.online_guests)
|
||||
}
|
||||
|
||||
func (hub *WS_Hub) UserCount() int {
|
||||
func (hub *WS_Hub) user_count() int {
|
||||
defer hub.users.RUnlock()
|
||||
hub.users.RLock()
|
||||
return len(hub.online_users)
|
||||
}
|
||||
|
||||
func (hub *WS_Hub) broadcast_message(msg string) error {
|
||||
hub.users.RLock()
|
||||
for _, ws_user := range hub.online_users {
|
||||
w, err := ws_user.conn.NextWriter(websocket.TextMessage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.Write([]byte(msg))
|
||||
}
|
||||
hub.users.RUnlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hub *WS_Hub) push_message(targetUser int, msg string) error {
|
||||
hub.users.RLock()
|
||||
ws_user, ok := hub.online_users[targetUser]
|
||||
hub.users.RUnlock()
|
||||
if !ok {
|
||||
return ws_nouser
|
||||
}
|
||||
|
||||
w, err := ws_user.conn.NextWriter(websocket.TextMessage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.Write([]byte(msg))
|
||||
w.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func(hub *WS_Hub) push_alert(targetUser int, event string, elementType string, actor_id int, targetUser_id int, elementID int) error {
|
||||
//fmt.Println("In push_alert")
|
||||
hub.users.RLock()
|
||||
ws_user, ok := hub.online_users[targetUser]
|
||||
hub.users.RUnlock()
|
||||
if !ok {
|
||||
return ws_nouser
|
||||
}
|
||||
|
||||
//fmt.Println("Building alert")
|
||||
alert, err := build_alert(event, elementType, actor_id, targetUser_id, elementID, *ws_user.User)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//fmt.Println("Getting WS Writer")
|
||||
w, err := ws_user.conn.NextWriter(websocket.TextMessage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//fmt.Println("Writing to the client")
|
||||
w.Write([]byte(alert))
|
||||
w.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func route_websockets(w http.ResponseWriter, r *http.Request) {
|
||||
user, ok := SimpleSessionCheck(w,r)
|
||||
if !ok {
|
||||
@ -65,7 +127,7 @@ func route_websockets(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil && err != ErrStoreCapacityOverflow {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
ws_user := &WS_User{conn,userptr}
|
||||
if user.ID == 0 {
|
||||
ws_hub.guests.Lock()
|
||||
@ -76,7 +138,7 @@ func route_websockets(w http.ResponseWriter, r *http.Request) {
|
||||
ws_hub.online_users[user.ID] = ws_user
|
||||
ws_hub.users.Unlock()
|
||||
}
|
||||
|
||||
|
||||
//conn.SetReadLimit(/* put the max request size from earlier here? */)
|
||||
//conn.SetReadDeadline(time.Now().Add(60 * time.Second))
|
||||
var current_page []byte
|
||||
@ -94,7 +156,7 @@ func route_websockets(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
//fmt.Println("Message",message)
|
||||
//fmt.Println("Message",string(message))
|
||||
messages := bytes.Split(message,[]byte("\r"))
|
||||
@ -106,7 +168,7 @@ func route_websockets(w http.ResponseWriter, r *http.Request) {
|
||||
if len(msgblocks) < 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
if !bytes.Equal(msgblocks[1],current_page) {
|
||||
ws_leave_page(ws_user, current_page)
|
||||
current_page = msgblocks[1]
|
||||
@ -116,9 +178,9 @@ func route_websockets(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
/*if bytes.Equal(message,[]byte(`start-view`)) {
|
||||
|
||||
|
||||
} else if bytes.Equal(message,[]byte(`end-view`)) {
|
||||
|
||||
|
||||
}*/
|
||||
}
|
||||
}
|
||||
@ -134,17 +196,17 @@ func ws_page_responses(ws_user *WS_User, page []byte) {
|
||||
//fmt.Println(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
fmt.Println(ws_hub.online_users)
|
||||
uonline := ws_hub.UserCount()
|
||||
gonline := ws_hub.GuestCount()
|
||||
uonline := ws_hub.user_count()
|
||||
gonline := ws_hub.guest_count()
|
||||
totonline := uonline + gonline
|
||||
|
||||
|
||||
w.Write([]byte("set #dash-totonline " + strconv.Itoa(totonline) + " online\r"))
|
||||
w.Write([]byte("set #dash-gonline " + strconv.Itoa(gonline) + " guests online\r"))
|
||||
w.Write([]byte("set #dash-uonline " + strconv.Itoa(uonline) + " users online\r"))
|
||||
w.Close()*/
|
||||
|
||||
|
||||
// Listen for changes and inform the admins...
|
||||
admin_stats_mutex.Lock()
|
||||
watchers := len(admin_stats_watchers)
|
||||
@ -169,7 +231,7 @@ var admin_stats_watchers map[*WS_User]bool
|
||||
var admin_stats_mutex sync.RWMutex
|
||||
func admin_stats_ticker() {
|
||||
time.Sleep(time.Second)
|
||||
|
||||
|
||||
var last_uonline int = -1
|
||||
var last_gonline int = -1
|
||||
var last_totonline int = -1
|
||||
@ -177,30 +239,29 @@ func admin_stats_ticker() {
|
||||
var last_available_ram int64 = -1
|
||||
var no_stat_updates bool = false
|
||||
var no_ram_updates bool = false
|
||||
|
||||
|
||||
var onlineColour, onlineGuestsColour, onlineUsersColour, cpustr, cpuColour, ramstr, ramColour string
|
||||
var cpuerr, ramerr error
|
||||
var memres *mem.VirtualMemoryStat
|
||||
var cpu_perc []float64
|
||||
|
||||
|
||||
var totunit, uunit, gunit string
|
||||
|
||||
|
||||
AdminStatLoop:
|
||||
for {
|
||||
//fmt.Println("tick tock")
|
||||
admin_stats_mutex.RLock()
|
||||
watch_count := len(admin_stats_watchers)
|
||||
admin_stats_mutex.RUnlock()
|
||||
if watch_count == 0 {
|
||||
break AdminStatLoop
|
||||
}
|
||||
|
||||
|
||||
cpu_perc, cpuerr = cpu.Percent(time.Duration(time.Second),true)
|
||||
memres, ramerr = mem.VirtualMemory()
|
||||
uonline := ws_hub.UserCount()
|
||||
gonline := ws_hub.GuestCount()
|
||||
uonline := ws_hub.user_count()
|
||||
gonline := ws_hub.guest_count()
|
||||
totonline := uonline + gonline
|
||||
|
||||
|
||||
// It's far more likely that the CPU Usage will change than the other stats, so we'll optimise them seperately...
|
||||
no_stat_updates = (uonline == last_uonline && gonline == last_gonline && totonline == last_totonline)
|
||||
no_ram_updates = (last_available_ram == int64(memres.Available))
|
||||
@ -208,7 +269,7 @@ AdminStatLoop:
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
if !no_stat_updates {
|
||||
if totonline > 10 {
|
||||
onlineColour = "stat_green"
|
||||
@ -217,7 +278,7 @@ AdminStatLoop:
|
||||
} else {
|
||||
onlineColour = "stat_red"
|
||||
}
|
||||
|
||||
|
||||
if gonline > 10 {
|
||||
onlineGuestsColour = "stat_green"
|
||||
} else if gonline > 1 {
|
||||
@ -225,7 +286,7 @@ AdminStatLoop:
|
||||
} else {
|
||||
onlineGuestsColour = "stat_red"
|
||||
}
|
||||
|
||||
|
||||
if uonline > 5 {
|
||||
onlineUsersColour = "stat_green"
|
||||
} else if uonline > 1 {
|
||||
@ -233,12 +294,12 @@ AdminStatLoop:
|
||||
} else {
|
||||
onlineUsersColour = "stat_red"
|
||||
}
|
||||
|
||||
|
||||
totonline, totunit = convert_friendly_unit(totonline)
|
||||
uonline, uunit = convert_friendly_unit(uonline)
|
||||
gonline, gunit = convert_friendly_unit(gonline)
|
||||
}
|
||||
|
||||
|
||||
if cpuerr != nil {
|
||||
cpustr = "Unknown"
|
||||
} else {
|
||||
@ -252,14 +313,14 @@ AdminStatLoop:
|
||||
cpuColour = "stat_red"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if !no_ram_updates {
|
||||
if ramerr != nil {
|
||||
ramstr = "Unknown"
|
||||
} else {
|
||||
total_count, total_unit := convert_byte_unit(float64(memres.Total))
|
||||
used_count := convert_byte_in_unit(float64(memres.Total - memres.Available),total_unit)
|
||||
|
||||
|
||||
// Round totals with .9s up, it's how most people see it anyway. Floats are notoriously imprecise, so do it off 0.85
|
||||
var totstr string
|
||||
if (total_count - float64(int(total_count))) > 0.85 {
|
||||
@ -268,12 +329,12 @@ AdminStatLoop:
|
||||
} else {
|
||||
totstr = fmt.Sprintf("%.1f",total_count)
|
||||
}
|
||||
|
||||
|
||||
if used_count > total_count {
|
||||
used_count = total_count
|
||||
}
|
||||
ramstr = fmt.Sprintf("%.1f",used_count) + " / " + totstr + total_unit
|
||||
|
||||
|
||||
ramperc := ((memres.Total - memres.Available) * 100) / memres.Total
|
||||
if ramperc < 50 {
|
||||
ramColour = "stat_green"
|
||||
@ -284,48 +345,48 @@ AdminStatLoop:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
admin_stats_mutex.RLock()
|
||||
watchers := admin_stats_watchers
|
||||
admin_stats_mutex.RUnlock()
|
||||
|
||||
|
||||
for watcher, _ := range watchers {
|
||||
w, err := watcher.conn.NextWriter(websocket.TextMessage)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
//fmt.Println(err.Error())
|
||||
admin_stats_mutex.Lock()
|
||||
delete(admin_stats_watchers,watcher)
|
||||
admin_stats_mutex.Unlock()
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
if !no_stat_updates {
|
||||
w.Write([]byte("set #dash-totonline " + strconv.Itoa(totonline) + totunit + " online\r"))
|
||||
w.Write([]byte("set #dash-gonline " + strconv.Itoa(gonline) + gunit + " guests online\r"))
|
||||
w.Write([]byte("set #dash-uonline " + strconv.Itoa(uonline) + uunit + " users online\r"))
|
||||
|
||||
|
||||
w.Write([]byte("set-class #dash-totonline grid_item grid_stat " + onlineColour + "\r"))
|
||||
w.Write([]byte("set-class #dash-gonline grid_item grid_stat " + onlineGuestsColour + "\r"))
|
||||
w.Write([]byte("set-class #dash-uonline grid_item grid_stat " + onlineUsersColour + "\r"))
|
||||
}
|
||||
|
||||
|
||||
w.Write([]byte("set #dash-cpu CPU: " + cpustr + "%\r"))
|
||||
w.Write([]byte("set-class #dash-cpu grid_item grid_istat " + cpuColour + "\r"))
|
||||
|
||||
|
||||
if !no_ram_updates {
|
||||
w.Write([]byte("set #dash-ram RAM: " + ramstr + "\r"))
|
||||
w.Write([]byte("set-class #dash-ram grid_item grid_istat " + ramColour + "\r"))
|
||||
}
|
||||
|
||||
|
||||
w.Close()
|
||||
}
|
||||
|
||||
|
||||
last_uonline = uonline
|
||||
last_gonline = gonline
|
||||
last_totonline = totonline
|
||||
last_cpu_perc = int(cpu_perc[0])
|
||||
last_available_ram = int64(memres.Available)
|
||||
|
||||
|
||||
//time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user