Added the BBCode plugin.
Restructured the plugin system. Multiple plugins can bind to the same hook now (not available for variadic hooks yet!) The parser is now benchmarked. The bench_round4 is run with both plugin_markdown and plugin_bbcode enabled. Added a benchmark for the BBCode plugin. Moved some of the template writing logic into a more generalised function. URLs are now recognised by the system and linked. Converted more custom errors into LocalError calls. Faster and less bandwidth intensive Emojis on Edge. Fixed a bug with replies not working.
This commit is contained in:
parent
33c2f4ccb0
commit
e90d96961f
85
extend.go
85
extend.go
|
@ -2,8 +2,8 @@
|
||||||
package main
|
package main
|
||||||
import "log"
|
import "log"
|
||||||
|
|
||||||
var plugins map[string]Plugin = make(map[string]Plugin)
|
var plugins map[string]*Plugin = make(map[string]*Plugin)
|
||||||
var hooks map[string]func(interface{})interface{} = make(map[string]func(interface{})interface{})
|
var hooks map[string][]func(interface{})interface{} = make(map[string][]func(interface{})interface{})
|
||||||
var vhooks map[string]func(...interface{})interface{} = make(map[string]func(...interface{})interface{})
|
var vhooks map[string]func(...interface{})interface{} = make(map[string]func(...interface{})interface{})
|
||||||
|
|
||||||
type Plugin struct
|
type Plugin struct
|
||||||
|
@ -19,11 +19,64 @@ type Plugin struct
|
||||||
Init func()
|
Init func()
|
||||||
Activate func()error
|
Activate func()error
|
||||||
Deactivate func()
|
Deactivate func()
|
||||||
|
|
||||||
|
Hooks map[string]int
|
||||||
}
|
}
|
||||||
|
|
||||||
/*func add_hook(name string, handler func(interface{})interface{}) {
|
func NewPlugin(uname string, name string, author string, url string, settings string, tag string, ptype string, init func(), activate func()error, deactivate func()) *Plugin {
|
||||||
hooks[name] = handler
|
return &Plugin{
|
||||||
}*/
|
UName: uname,
|
||||||
|
Name: name,
|
||||||
|
Author: author,
|
||||||
|
URL: url,
|
||||||
|
Settings: settings,
|
||||||
|
Tag: tag,
|
||||||
|
Type: ptype,
|
||||||
|
Init: init,
|
||||||
|
Activate: activate,
|
||||||
|
Deactivate: deactivate,
|
||||||
|
|
||||||
|
/*
|
||||||
|
The Active field should never be altered by a plugin. It's used internally by the software to determine whether an admin has enabled a plugin or not and whether to run it. This will be overwritten by the user's preference.
|
||||||
|
*/
|
||||||
|
Active: false,
|
||||||
|
Hooks: make(map[string]int),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (plugin *Plugin) AddHook(name string, handler interface{}) {
|
||||||
|
switch h := handler.(type) {
|
||||||
|
case func(interface{})interface{}:
|
||||||
|
if len(hooks[name]) == 0 {
|
||||||
|
var hookSlice []func(interface{})interface{}
|
||||||
|
hookSlice = append(hookSlice, h)
|
||||||
|
hooks[name] = hookSlice
|
||||||
|
} else {
|
||||||
|
hooks[name] = append(hooks[name], h)
|
||||||
|
}
|
||||||
|
plugin.Hooks[name] = len(hooks[name])
|
||||||
|
case func(...interface{}) interface{}:
|
||||||
|
vhooks[name] = h
|
||||||
|
plugin.Hooks[name] = 0
|
||||||
|
default:
|
||||||
|
panic("I don't recognise this kind of handler!") // Should this be an error for the plugin instead of a panic()?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (plugin *Plugin) RemoveHook(name string, handler interface{}) {
|
||||||
|
switch handler.(type) {
|
||||||
|
case func(interface{})interface{}:
|
||||||
|
key := plugin.Hooks[name]
|
||||||
|
hook := hooks[name]
|
||||||
|
hook = append(hook[:key], hook[key + 1:]...)
|
||||||
|
hooks[name] = hook
|
||||||
|
case func(...interface{}) interface{}:
|
||||||
|
delete(vhooks, name)
|
||||||
|
default:
|
||||||
|
panic("I don't recognise this kind of handler!") // Should this be an error for the plugin instead of a panic()?
|
||||||
|
}
|
||||||
|
delete(plugin.Hooks, name)
|
||||||
|
}
|
||||||
|
|
||||||
func init_plugins() {
|
func init_plugins() {
|
||||||
for name, body := range plugins {
|
for name, body := range plugins {
|
||||||
|
@ -35,27 +88,11 @@ func init_plugins() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func add_hook(name string, handler interface{}) {
|
|
||||||
switch h := handler.(type) {
|
|
||||||
case func(interface{})interface{}:
|
|
||||||
hooks[name] = h
|
|
||||||
case func(...interface{}) interface{}:
|
|
||||||
vhooks[name] = h
|
|
||||||
default:
|
|
||||||
panic("I don't recognise this kind of handler!") // Should this be an error for the plugin instead of a panic()?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func remove_hook(name string/*, plugin string */) {
|
|
||||||
delete(hooks, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func run_hook(name string, data interface{}) interface{} {
|
func run_hook(name string, data interface{}) interface{} {
|
||||||
return hooks[name](data)
|
for _, hook := range hooks[name] {
|
||||||
|
data = hook(data)
|
||||||
}
|
}
|
||||||
|
return data
|
||||||
func remove_vhook(name string) {
|
|
||||||
delete(vhooks, name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func run_vhook(name string, data ...interface{}) interface{} {
|
func run_vhook(name string, data ...interface{}) interface{} {
|
||||||
|
|
132
general_test.go
132
general_test.go
|
@ -714,6 +714,138 @@ func BenchmarkCustomRouter(b *testing.B) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkParser(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.Run("empty_post", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = parse_message("")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("short_post", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = parse_message("Hey everyone, how's it going?")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("one_smily", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = parse_message("Hey everyone, how's it going? :)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("five_smilies", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = parse_message("Hey everyone, how's it going? :):):):):)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("ten_smilies", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = parse_message("Hey everyone, how's it going? :):):):):):):):):):)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("twenty_smilies", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = parse_message("Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkBBCodePluginWithRegexp(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.Run("empty_post", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse("")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("short_post", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse("Hey everyone, how's it going?")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("one_smily", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse("Hey everyone, how's it going? :)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("five_smilies", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse("Hey everyone, how's it going? :):):):):)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("ten_smilies", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse("Hey everyone, how's it going? :):):):):):):):):):)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("twenty_smilies", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse("Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("one_bold", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse("[b]H[/b]ey everyone, how's it going?")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("five_bold", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse("[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("ten_bold", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse("[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkBBCodePluginWithCustomParser(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.Run("empty_post", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse2("")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("short_post", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse2("Hey everyone, how's it going?")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("one_smily", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse2("Hey everyone, how's it going? :)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("five_smilies", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse2("Hey everyone, how's it going? :):):):):)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("ten_smilies", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse2("Hey everyone, how's it going? :):):):):):):):):):)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("twenty_smilies", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse2("Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("one_bold", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse2("[b]H[/b]ey everyone, how's it going?")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("five_bold", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse2("[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("ten_bold", func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_ = bbcode_parse2("[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/*func TestRoute(t *testing.T) {
|
/*func TestRoute(t *testing.T) {
|
||||||
|
|
||||||
}*/
|
}*/
|
Binary file not shown.
After Width: | Height: | Size: 106 KiB |
Binary file not shown.
After Width: | Height: | Size: 127 KiB |
93
main.go
93
main.go
|
@ -33,7 +33,6 @@ var forums map[int]Forum = make(map[int]Forum)
|
||||||
var static_files map[string]SFile = make(map[string]SFile)
|
var static_files map[string]SFile = make(map[string]SFile)
|
||||||
|
|
||||||
var template_topic_handle func(TopicPage,io.Writer) = nil
|
var template_topic_handle func(TopicPage,io.Writer) = nil
|
||||||
var template_topic_origin_handle func(TopicPage,io.Writer) = nil
|
|
||||||
var template_topic_alt_handle func(TopicPage,io.Writer) = nil
|
var template_topic_alt_handle func(TopicPage,io.Writer) = nil
|
||||||
var template_topics_handle func(TopicsPage,io.Writer) = nil
|
var template_topics_handle func(TopicsPage,io.Writer) = nil
|
||||||
var template_forum_handle func(ForumPage,io.Writer) = nil
|
var template_forum_handle func(ForumPage,io.Writer) = nil
|
||||||
|
@ -75,7 +74,6 @@ func compile_templates() {
|
||||||
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,"","","",""})
|
||||||
topics_page := TopicsPage{"Topic List",user,noticeList,topicList,""}
|
topics_page := TopicsPage{"Topic List",user,noticeList,topicList,""}
|
||||||
topics_tmpl := c.compile_template("topics.html","templates/","TopicsPage", topics_page, varList)
|
topics_tmpl := c.compile_template("topics.html","templates/","TopicsPage", topics_page, varList)
|
||||||
//topics_tmpl := c.compile_template("topics.html","templates/","Page", pi, varList)
|
|
||||||
|
|
||||||
forum_page := ForumPage{"General Forum",user,noticeList,topicList,"There aren't any topics in this forum yet."}
|
forum_page := ForumPage{"General Forum",user,noticeList,topicList,"There aren't any topics in this forum yet."}
|
||||||
forum_tmpl := c.compile_template("forum.html","templates/","ForumPage", forum_page, varList)
|
forum_tmpl := c.compile_template("forum.html","templates/","ForumPage", forum_page, varList)
|
||||||
|
@ -90,17 +88,7 @@ func compile_templates() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func write_template(name string, content string) {
|
func write_template(name string, content string) {
|
||||||
f, err := os.Create("./template_" + name + ".go")
|
write_file("./template_" + name + ".go", content)
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = f.WriteString(content)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
f.Sync()
|
|
||||||
f.Close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main(){
|
func main(){
|
||||||
|
@ -137,84 +125,8 @@ func main(){
|
||||||
|
|
||||||
init_plugins()
|
init_plugins()
|
||||||
|
|
||||||
// In a directory to stop it clashing with the other paths
|
|
||||||
/*http.HandleFunc("/static/", route_static)
|
|
||||||
|
|
||||||
fs_u := http.FileServer(http.Dir("./uploads"))
|
|
||||||
http.Handle("/uploads/", http.StripPrefix("/uploads/",fs_u))
|
|
||||||
|
|
||||||
http.HandleFunc("/overview/", route_overview)
|
|
||||||
http.HandleFunc("/topics/create/", route_topic_create)
|
|
||||||
http.HandleFunc("/topics/", route_topics)
|
|
||||||
http.HandleFunc("/forums/", route_forums)
|
|
||||||
http.HandleFunc("/forum/", route_forum)
|
|
||||||
http.HandleFunc("/topic/create/submit/", route_create_topic)
|
|
||||||
http.HandleFunc("/topic/", route_topic_id)
|
|
||||||
http.HandleFunc("/reply/create/", route_create_reply)
|
|
||||||
//http.HandleFunc("/reply/edit/", route_reply_edit)
|
|
||||||
//http.HandleFunc("/reply/delete/", route_reply_delete)
|
|
||||||
http.HandleFunc("/reply/edit/submit/", route_reply_edit_submit)
|
|
||||||
http.HandleFunc("/reply/delete/submit/", route_reply_delete_submit)
|
|
||||||
http.HandleFunc("/report/submit/", route_report_submit)
|
|
||||||
http.HandleFunc("/topic/edit/submit/", route_edit_topic)
|
|
||||||
http.HandleFunc("/topic/delete/submit/", route_delete_topic)
|
|
||||||
http.HandleFunc("/topic/stick/submit/", route_stick_topic)
|
|
||||||
http.HandleFunc("/topic/unstick/submit/", route_unstick_topic)
|
|
||||||
|
|
||||||
// Custom Pages
|
|
||||||
http.HandleFunc("/pages/", route_custom_page)
|
|
||||||
|
|
||||||
// Accounts
|
|
||||||
http.HandleFunc("/accounts/login/", route_login)
|
|
||||||
http.HandleFunc("/accounts/create/", route_register)
|
|
||||||
http.HandleFunc("/accounts/logout/", route_logout)
|
|
||||||
http.HandleFunc("/accounts/login/submit/", route_login_submit)
|
|
||||||
http.HandleFunc("/accounts/create/submit/", route_register_submit)
|
|
||||||
|
|
||||||
//http.HandleFunc("/accounts/list/", route_login) // Redirect /accounts/ and /user/ to here..
|
|
||||||
//http.HandleFunc("/accounts/create/full/", route_logout)
|
|
||||||
//http.HandleFunc("/user/edit/", route_logout)
|
|
||||||
http.HandleFunc("/user/edit/critical/", route_account_own_edit_critical) // Password & Email
|
|
||||||
http.HandleFunc("/user/edit/critical/submit/", route_account_own_edit_critical_submit)
|
|
||||||
http.HandleFunc("/user/edit/avatar/", route_account_own_edit_avatar)
|
|
||||||
http.HandleFunc("/user/edit/avatar/submit/", route_account_own_edit_avatar_submit)
|
|
||||||
http.HandleFunc("/user/edit/username/", route_account_own_edit_username)
|
|
||||||
http.HandleFunc("/user/edit/username/submit/", route_account_own_edit_username_submit)
|
|
||||||
http.HandleFunc("/user/edit/email/token/", route_account_own_edit_email_token_submit)
|
|
||||||
http.HandleFunc("/user/", route_profile)
|
|
||||||
http.HandleFunc("/profile/reply/create/", route_profile_reply_create)
|
|
||||||
http.HandleFunc("/profile/reply/edit/submit/", route_profile_reply_edit_submit)
|
|
||||||
http.HandleFunc("/profile/reply/delete/submit/", route_profile_reply_delete_submit)
|
|
||||||
//http.HandleFunc("/user/edit/submit/", route_logout)
|
|
||||||
http.HandleFunc("/users/ban/", route_ban)
|
|
||||||
http.HandleFunc("/users/ban/submit/", route_ban_submit)
|
|
||||||
http.HandleFunc("/users/unban/", route_unban)
|
|
||||||
http.HandleFunc("/users/activate/", route_activate)
|
|
||||||
|
|
||||||
// Admin
|
|
||||||
http.HandleFunc("/panel/", route_panel)
|
|
||||||
http.HandleFunc("/panel/forums/", route_panel_forums)
|
|
||||||
http.HandleFunc("/panel/forums/create/", route_panel_forums_create_submit)
|
|
||||||
http.HandleFunc("/panel/forums/delete/", route_panel_forums_delete)
|
|
||||||
http.HandleFunc("/panel/forums/delete/submit/", route_panel_forums_delete_submit)
|
|
||||||
http.HandleFunc("/panel/forums/edit/submit/", route_panel_forums_edit_submit)
|
|
||||||
http.HandleFunc("/panel/settings/", route_panel_settings)
|
|
||||||
http.HandleFunc("/panel/settings/edit/", route_panel_setting)
|
|
||||||
http.HandleFunc("/panel/settings/edit/submit/", route_panel_setting_edit)
|
|
||||||
http.HandleFunc("/panel/themes/", route_panel_themes)
|
|
||||||
http.HandleFunc("/panel/themes/default/", route_panel_themes_default)
|
|
||||||
http.HandleFunc("/panel/plugins/", route_panel_plugins)
|
|
||||||
http.HandleFunc("/panel/plugins/activate/", route_panel_plugins_activate)
|
|
||||||
http.HandleFunc("/panel/plugins/deactivate/", route_panel_plugins_deactivate)
|
|
||||||
http.HandleFunc("/panel/users/", route_panel_users)
|
|
||||||
http.HandleFunc("/panel/users/edit/", route_panel_users_edit)
|
|
||||||
http.HandleFunc("/panel/users/edit/submit/", route_panel_users_edit_submit)
|
|
||||||
http.HandleFunc("/panel/groups/", route_panel_groups)
|
|
||||||
|
|
||||||
http.HandleFunc("/", default_route)*/
|
|
||||||
|
|
||||||
router := NewRouter()
|
router := NewRouter()
|
||||||
router.HandleFunc("/static/", route_static)
|
router.HandleFunc("/static/", route_static) // In a directory to stop it clashing with the other paths
|
||||||
|
|
||||||
fs_u := http.FileServer(http.Dir("./uploads"))
|
fs_u := http.FileServer(http.Dir("./uploads"))
|
||||||
router.Handle("/uploads/", http.StripPrefix("/uploads/",fs_u))
|
router.Handle("/uploads/", http.StripPrefix("/uploads/",fs_u))
|
||||||
|
@ -295,7 +207,6 @@ func main(){
|
||||||
if server_port == "" {
|
if server_port == "" {
|
||||||
server_port = "80"
|
server_port = "80"
|
||||||
}
|
}
|
||||||
//http.ListenAndServe(":" + server_port, nil)
|
|
||||||
http.ListenAndServe(":" + server_port, router)
|
http.ListenAndServe(":" + server_port, router)
|
||||||
} else {
|
} else {
|
||||||
if server_port == "" {
|
if server_port == "" {
|
||||||
|
|
10
pages.go
10
pages.go
|
@ -1,6 +1,6 @@
|
||||||
package main
|
package main
|
||||||
import "strings"
|
import "strings"
|
||||||
//import "regexp"
|
import "regexp"
|
||||||
|
|
||||||
type Page struct
|
type Page struct
|
||||||
{
|
{
|
||||||
|
@ -71,6 +71,13 @@ type AreYouSure struct
|
||||||
Message string
|
Message string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var urlpattern string = `(?s)([ {1}])((http|https|ftp|mailto)*)(:{??)\/\/([\.a-zA-Z\/]+)([ {1}])`
|
||||||
|
var url_reg *regexp.Regexp
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
url_reg = regexp.MustCompile(urlpattern)
|
||||||
|
}
|
||||||
|
|
||||||
func shortcode_to_unicode(msg string) string {
|
func shortcode_to_unicode(msg string) string {
|
||||||
//re := regexp.MustCompile(":(.):")
|
//re := regexp.MustCompile(":(.):")
|
||||||
msg = strings.Replace(msg,":grinning:","😀",-1)
|
msg = strings.Replace(msg,":grinning:","😀",-1)
|
||||||
|
@ -126,6 +133,7 @@ func parse_message(msg string) string {
|
||||||
msg = strings.Replace(msg,":)","😀",-1)
|
msg = strings.Replace(msg,":)","😀",-1)
|
||||||
msg = strings.Replace(msg,":D","😃",-1)
|
msg = strings.Replace(msg,":D","😃",-1)
|
||||||
msg = strings.Replace(msg,":P","😛",-1)
|
msg = strings.Replace(msg,":P","😛",-1)
|
||||||
|
msg = url_reg.ReplaceAllString(msg,"<a href=\"$2$3//$4\" rel=\"nofollow\">$2$3//$4</a>")
|
||||||
msg = strings.Replace(msg,"\n","<br>",-1)
|
msg = strings.Replace(msg,"\n","<br>",-1)
|
||||||
if hooks["parse_assign"] != nil {
|
if hooks["parse_assign"] != nil {
|
||||||
out := run_hook("parse_assign", msg)
|
out := run_hook("parse_assign", msg)
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
package main
|
||||||
|
//import "log"
|
||||||
|
//import "fmt"
|
||||||
|
import "regexp"
|
||||||
|
|
||||||
|
var bbcode_bold *regexp.Regexp
|
||||||
|
var bbcode_italic *regexp.Regexp
|
||||||
|
var bbcode_underline *regexp.Regexp
|
||||||
|
var bbcode_url *regexp.Regexp
|
||||||
|
var bbcode_url_label *regexp.Regexp
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
plugins["bbcode"] = NewPlugin("bbcode","BBCode","Azareal","http://github.com/Azareal","","","",init_bbcode,nil,deactivate_bbcode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init_bbcode() {
|
||||||
|
plugins["bbcode"].AddHook("parse_assign", bbcode_parse2)
|
||||||
|
bbcode_bold = regexp.MustCompile(`(?s)\[b\](.*)\[/b\]`)
|
||||||
|
bbcode_italic = regexp.MustCompile(`(?s)\[i\](.*)\[/i\]`)
|
||||||
|
bbcode_underline = regexp.MustCompile(`(?s)\[u\](.*)\[/u\]`)
|
||||||
|
urlpattern := `(http|https|ftp|mailto*)(:??)\/\/([\.a-zA-Z\/]+)`
|
||||||
|
bbcode_url = regexp.MustCompile(`\[url\]` + urlpattern + `\[/url\]`)
|
||||||
|
bbcode_url_label = regexp.MustCompile(`(?s)\[url=` + urlpattern + `\](.*)\[/url\]`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func deactivate_bbcode() {
|
||||||
|
plugins["bbcode"].RemoveHook("parse_assign", bbcode_parse2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func bbcode_parse(data interface{}) interface{} {
|
||||||
|
msg := data.(string)
|
||||||
|
msg = bbcode_bold.ReplaceAllString(msg,"<b>$1</b>")
|
||||||
|
msg = bbcode_italic.ReplaceAllString(msg,"<i>$1</i>")
|
||||||
|
msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>")
|
||||||
|
msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>")
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func bbcode_parse2(data interface{}) interface{} {
|
||||||
|
msg := data.(string)
|
||||||
|
msgbytes := []byte(msg)
|
||||||
|
has_u := false
|
||||||
|
has_b := false
|
||||||
|
has_i := false
|
||||||
|
complex_bbc := false
|
||||||
|
for i := 0; i < len(msgbytes); i++ {
|
||||||
|
//log.Print(msgbytes[i])
|
||||||
|
//fmt.Println(string(msgbytes[i]))
|
||||||
|
//continue
|
||||||
|
if msgbytes[i] == '[' {
|
||||||
|
if msgbytes[i + 2] != ']' {
|
||||||
|
if msgbytes[i + 1] == '/' {
|
||||||
|
if msgbytes[i + 3] == ']' {
|
||||||
|
if msgbytes[i + 2] == 'u' {
|
||||||
|
msgbytes[i] = '<'
|
||||||
|
msgbytes[i + 3] = '>'
|
||||||
|
has_u = false
|
||||||
|
}
|
||||||
|
if msgbytes[i + 2] == 'b' {
|
||||||
|
msgbytes[i] = '<'
|
||||||
|
msgbytes[i + 3] = '>'
|
||||||
|
has_b = false
|
||||||
|
}
|
||||||
|
if msgbytes[i + 2] == 'i' {
|
||||||
|
msgbytes[i] = '<'
|
||||||
|
msgbytes[i + 3] = '>'
|
||||||
|
has_i = false
|
||||||
|
}
|
||||||
|
i += 3
|
||||||
|
} else {
|
||||||
|
complex_bbc = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
complex_bbc = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if msgbytes[i + 1] == 'u' {
|
||||||
|
msgbytes[i] = '<'
|
||||||
|
msgbytes[i + 2] = '>'
|
||||||
|
has_u = true
|
||||||
|
}
|
||||||
|
if msgbytes[i + 1] == 'b' {
|
||||||
|
msgbytes[i] = '<'
|
||||||
|
msgbytes[i + 2] = '>'
|
||||||
|
has_b = true
|
||||||
|
}
|
||||||
|
if msgbytes[i + 1] == 'i' {
|
||||||
|
msgbytes[i] = '<'
|
||||||
|
msgbytes[i + 2] = '>'
|
||||||
|
has_i = true
|
||||||
|
}
|
||||||
|
i += 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// There's an unclosed tag in there x.x
|
||||||
|
if has_i || has_u || has_b {
|
||||||
|
closer := []byte("</u></i></b>")
|
||||||
|
msgbytes = append(msgbytes, closer...)
|
||||||
|
}
|
||||||
|
msg = string(msgbytes)
|
||||||
|
//fmt.Println(msg)
|
||||||
|
|
||||||
|
if complex_bbc {
|
||||||
|
msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>")
|
||||||
|
msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>")
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
|
@ -2,16 +2,16 @@ package main
|
||||||
import "html/template"
|
import "html/template"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugins["helloworld"] = Plugin{"helloworld","Hello World","Azareal","http://github.com/Azareal","",false,"","",init_helloworld,nil,deactivate_helloworld}
|
plugins["helloworld"] = NewPlugin("helloworld","Hello World","Azareal","http://github.com/Azareal","","","",init_helloworld,nil,deactivate_helloworld)
|
||||||
}
|
}
|
||||||
|
|
||||||
// init_helloworld is separate from init() as we don't want the plugin to run if the plugin is disabled
|
// init_helloworld is separate from init() as we don't want the plugin to run if the plugin is disabled
|
||||||
func init_helloworld() {
|
func init_helloworld() {
|
||||||
add_hook("rrow_assign", helloworld_reply)
|
plugins["helloworld"].AddHook("rrow_assign", helloworld_reply)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deactivate_helloworld() {
|
func deactivate_helloworld() {
|
||||||
remove_hook("rrow_assign")
|
plugins["helloworld"].RemoveHook("rrow_assign", helloworld_reply)
|
||||||
}
|
}
|
||||||
|
|
||||||
func helloworld_reply(data interface{}) interface{} {
|
func helloworld_reply(data interface{}) interface{} {
|
||||||
|
|
|
@ -1,30 +1,29 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "regexp"
|
import "regexp"
|
||||||
|
|
||||||
var bold_italic *regexp.Regexp
|
var markdown_bold_italic *regexp.Regexp
|
||||||
var bold *regexp.Regexp
|
var markdown_bold *regexp.Regexp
|
||||||
var italic *regexp.Regexp
|
var markdown_italic *regexp.Regexp
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugins["markdown"] = Plugin{"markdown","Markdown","Azareal","http://github.com/Azareal","",false,"","",init_markdown,nil,deactivate_markdown}
|
plugins["markdown"] = NewPlugin("markdown","Markdown","Azareal","http://github.com/Azareal","","","",init_markdown,nil,deactivate_markdown)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init_markdown() {
|
func init_markdown() {
|
||||||
add_hook("parse_assign", markdown_parse)
|
plugins["markdown"].AddHook("parse_assign", markdown_parse)
|
||||||
bold_italic = regexp.MustCompile(`\*\*\*(.*)\*\*\*`)
|
markdown_bold_italic = regexp.MustCompile(`\*\*\*(.*)\*\*\*`)
|
||||||
bold = regexp.MustCompile(`\*\*(.*)\*\*`)
|
markdown_bold = regexp.MustCompile(`\*\*(.*)\*\*`)
|
||||||
italic = regexp.MustCompile(`\*(.*)\*`)
|
markdown_italic = regexp.MustCompile(`\*(.*)\*`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deactivate_markdown() {
|
func deactivate_markdown() {
|
||||||
remove_hook("parse_assign")
|
plugins["markdown"].RemoveHook("parse_assign", markdown_parse)
|
||||||
}
|
}
|
||||||
|
|
||||||
func markdown_parse(data interface{}) interface{} {
|
func markdown_parse(data interface{}) interface{} {
|
||||||
msg := data.(string)
|
msg := data.(string)
|
||||||
msg = bold_italic.ReplaceAllString(msg,"<i><b>$1</b></i>")
|
msg = markdown_bold_italic.ReplaceAllString(msg,"<i><b>$1</b></i>")
|
||||||
msg = bold.ReplaceAllString(msg,"<b>$1</b>")
|
msg = markdown_bold.ReplaceAllString(msg,"<b>$1</b>")
|
||||||
msg = italic.ReplaceAllString(msg,"<i>$1</i>")
|
msg = markdown_italic.ReplaceAllString(msg,"<i>$1</i>")
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
|
@ -12,8 +12,6 @@ func init() {
|
||||||
|
|
||||||
The Settings field points to the route for managing the settings for this plugin. Coming soon.
|
The Settings field points to the route for managing the settings for this plugin. Coming soon.
|
||||||
|
|
||||||
The Active field should always be set to false in the init() function of a plugin. It's used internally by the software to determine whether an admin has enabled a plugin or not and whether to run it. This will be overwritten by the user's preference.
|
|
||||||
|
|
||||||
The Tag field is for providing a tiny snippet of information separate from the description.
|
The Tag field is for providing a tiny snippet of information separate from the description.
|
||||||
|
|
||||||
The Type field is for the type of the plugin. This gets changed to "go" automatically and we would suggest leaving "".
|
The Type field is for the type of the plugin. This gets changed to "go" automatically and we would suggest leaving "".
|
||||||
|
@ -24,7 +22,7 @@ func init() {
|
||||||
|
|
||||||
The Deactivate field is for the handler which is called by the software when the admin hits the Deactivate button in the control panel. You should clean-up any resources you have allocated, remove any hooks, close any statements, etc. within this handler.
|
The Deactivate field is for the handler which is called by the software when the admin hits the Deactivate button in the control panel. You should clean-up any resources you have allocated, remove any hooks, close any statements, etc. within this handler.
|
||||||
*/
|
*/
|
||||||
plugins["skeleton"] = Plugin{"skeleton","Skeleton","Azareal","","",false,"","",init_skeleton, activate_skeleton, deactivate_skeleton}
|
plugins["skeleton"] = NewPlugin("skeleton","Skeleton","Azareal","","","","",init_skeleton, activate_skeleton, deactivate_skeleton)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init_skeleton() {}
|
func init_skeleton() {}
|
||||||
|
|
32
routes.go
32
routes.go
|
@ -605,20 +605,9 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
success := 1
|
|
||||||
tid, err := strconv.Atoi(r.PostFormValue("tid"))
|
tid, err := strconv.Atoi(r.PostFormValue("tid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
LocalError("Failed to convert the TopicID", w, r, user)
|
||||||
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)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,15 +615,15 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Print(content)
|
log.Print(content)
|
||||||
_, err = create_reply_stmt.Exec(tid,content,parse_message(content),user.ID)
|
_, err = create_reply_stmt.Exec(tid,content,parse_message(content),user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
InternalError(err,w,r,user)
|
||||||
success = 0
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var topic_name string
|
var topic_name string
|
||||||
err = db.QueryRow("select title from topics where tid = ?", tid).Scan(&topic_name)
|
err = db.QueryRow("select title from topics where tid = ?", tid).Scan(&topic_name)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
log.Print(err)
|
LocalError("Couldn't find the parent topic", w, r, user)
|
||||||
success = 0
|
return
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
InternalError(err,w,r,user)
|
InternalError(err,w,r,user)
|
||||||
return
|
return
|
||||||
|
@ -646,19 +635,8 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
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, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
|
http.Redirect(w, r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func route_profile_reply_create(w http.ResponseWriter, r *http.Request) {
|
func route_profile_reply_create(w http.ResponseWriter, r *http.Request) {
|
||||||
user, ok := SimpleSessionCheck(w,r)
|
user, ok := SimpleSessionCheck(w,r)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
|
||||||
package main
|
package main
|
||||||
import "strconv"
|
|
||||||
import "io"
|
import "io"
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
template_forum_handle = template_forum
|
template_forum_handle = template_forum
|
||||||
|
|
|
@ -130,19 +130,19 @@ w.Write([]byte(`
|
||||||
<div class="the_name" style="margin-top: 3px;text-align: center;color: #505050;">` + item.CreatedByName + `</div>
|
<div class="the_name" style="margin-top: 3px;text-align: center;color: #505050;">` + item.CreatedByName + `</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content_container" style="background: white;margin-left: 137px;min-height: 128px;margin-bottom: 0;margin-right: 3px;box-shadow:0 1px 2px rgba(0,0,0,.1);">
|
<div class="content_container" style="background: white;margin-left: 137px;min-height: 128px;margin-bottom: 0;margin-right: 3px;box-shadow:0 1px 2px rgba(0,0,0,.1);">
|
||||||
<div class="editable_block user_content" style="padding: 5px;margin-top: 3px;margin-bottom: 0;background: white;min-height: 133px;padding-bottom: 0;width: 100%;">` + string(item.ContentHtml) + `</div>
|
<div class="editable_block user_content">` + string(item.ContentHtml) + `</div>
|
||||||
<div class="button_container" style="border-top: solid 1px #eaeaea;border-spacing: 0px;border-collapse: collapse;padding: 0;margin: 0;display: block;">
|
<div class="button_container">
|
||||||
`))
|
`))
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.EditReply {
|
if tmpl_topic_alt_vars.CurrentUser.Perms.EditReply {
|
||||||
w.Write([]byte(`<a href="/reply/edit/submit/` + strconv.Itoa(item.ID) + `" style="border-right: solid 1px #eaeaea;color: #505050;font-size: 13px;padding-left: 5px;padding-right: 5px;">Edit</a>`))
|
w.Write([]byte(`<a href="/reply/edit/submit/` + strconv.Itoa(item.ID) + `" class="action_button">Edit</a>`))
|
||||||
}
|
}
|
||||||
w.Write([]byte(`
|
w.Write([]byte(`
|
||||||
`))
|
`))
|
||||||
if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteReply {
|
if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteReply {
|
||||||
w.Write([]byte(`<a href="/reply/delete/submit/` + strconv.Itoa(item.ID) + `" style="border-right: solid 1px #eaeaea;color: #505050;font-size: 13px;padding-left: 0;padding-right: 5px;">Delete</a>`))
|
w.Write([]byte(`<a href="/reply/delete/submit/` + strconv.Itoa(item.ID) + `" class="action_button">Delete</a>`))
|
||||||
}
|
}
|
||||||
w.Write([]byte(`
|
w.Write([]byte(`
|
||||||
<a href="/report/submit/` + strconv.Itoa(item.ID) + `?session=` + tmpl_topic_alt_vars.CurrentUser.Session + `&type=reply" style="border: none;border-right: solid 1px #eaeaea;padding-right: 6px;color: #505050;font-size: 13px;">Report</a>
|
<a href="/report/submit/` + strconv.Itoa(item.ID) + `?session=` + tmpl_topic_alt_vars.CurrentUser.Session + `&type=reply" class="action_button">Report</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,9 +1 @@
|
||||||
<!doctype html>
|
{{template "header.html" . }}{{template "$page_name" . }}{{template "footer.html" . }}
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
{{template "header.html" . }}
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -40,11 +40,11 @@
|
||||||
<div class="the_name" style="margin-top: 3px;text-align: center;color: #505050;">{{.CreatedByName}}</div>
|
<div class="the_name" style="margin-top: 3px;text-align: center;color: #505050;">{{.CreatedByName}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content_container" style="background: white;margin-left: 137px;min-height: 128px;margin-bottom: 0;margin-right: 3px;box-shadow:0 1px 2px rgba(0,0,0,.1);">
|
<div class="content_container" style="background: white;margin-left: 137px;min-height: 128px;margin-bottom: 0;margin-right: 3px;box-shadow:0 1px 2px rgba(0,0,0,.1);">
|
||||||
<div class="editable_block user_content" style="padding: 5px;margin-top: 3px;margin-bottom: 0;background: white;min-height: 133px;padding-bottom: 0;width: 100%;">{{.ContentHtml}}</div>
|
<div class="editable_block user_content">{{.ContentHtml}}</div>
|
||||||
<div class="button_container" style="border-top: solid 1px #eaeaea;border-spacing: 0px;border-collapse: collapse;padding: 0;margin: 0;display: block;">
|
<div class="button_container">
|
||||||
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" style="border-right: solid 1px #eaeaea;color: #505050;font-size: 13px;padding-left: 5px;padding-right: 5px;">Edit</a>{{end}}
|
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="action_button">Edit</a>{{end}}
|
||||||
{{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" style="border-right: solid 1px #eaeaea;color: #505050;font-size: 13px;padding-left: 0;padding-right: 5px;">Delete</a>{{end}}
|
{{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" class="action_button">Delete</a>{{end}}
|
||||||
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" style="border: none;border-right: solid 1px #eaeaea;padding-right: 6px;color: #505050;font-size: 13px;">Report</a>
|
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" class="action_button">Report</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,22 +9,11 @@ body
|
||||||
font-family: arial;
|
font-family: arial;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
/* Patch for Edge */
|
||||||
font-family: 'EmojiFont';
|
|
||||||
src: url('https://github.com/Ranks/emojione/raw/master/assets/fonts/emojione-svg.woff2') format('woff2'),
|
|
||||||
url('https://github.com/Ranks/emojione/raw/master/assets/fonts/emojione-svg.woff') format('woff'), local("arial");
|
|
||||||
}
|
|
||||||
|
|
||||||
@supports (-ms-ime-align:auto) {
|
@supports (-ms-ime-align:auto) {
|
||||||
.user_content
|
.user_content
|
||||||
{
|
{
|
||||||
font-family: EmojiFont, arial;
|
font-family: Segoe UI Emoji, arial;
|
||||||
}
|
|
||||||
}
|
|
||||||
@-moz-document url-prefix() {
|
|
||||||
.user_content
|
|
||||||
{
|
|
||||||
font-family: EmojiFont, arial;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,6 +319,41 @@ button.username
|
||||||
background-color: #FEB7CC;
|
background-color: #FEB7CC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tempra Conflux */
|
||||||
|
.user_content {
|
||||||
|
padding: 5px;
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
background: white;
|
||||||
|
min-height: 129px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_container {
|
||||||
|
border-top: solid 1px #eaeaea;
|
||||||
|
border-spacing: 0px;
|
||||||
|
border-collapse: collapse;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
margin-top: 3px;
|
||||||
|
display: block;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action_button {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
border-right: solid 1px #eaeaea;
|
||||||
|
color: #505050;
|
||||||
|
font-size: 13px;
|
||||||
|
padding-top: 2px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Media Queries from Simple. Probably useless in Conflux */
|
||||||
@media (max-width: 880px) {
|
@media (max-width: 880px) {
|
||||||
li
|
li
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,22 +9,11 @@ body
|
||||||
font-family: arial;
|
font-family: arial;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
/* Patch for Edge */
|
||||||
font-family: 'EmojiFont';
|
|
||||||
src: url('https://github.com/Ranks/emojione/raw/master/assets/fonts/emojione-svg.woff2') format('woff2'),
|
|
||||||
url('https://github.com/Ranks/emojione/raw/master/assets/fonts/emojione-svg.woff') format('woff'), local("arial");
|
|
||||||
}
|
|
||||||
|
|
||||||
@supports (-ms-ime-align:auto) {
|
@supports (-ms-ime-align:auto) {
|
||||||
.user_content
|
.user_content
|
||||||
{
|
{
|
||||||
font-family: EmojiFont, arial;
|
font-family: Segoe UI Emoji, arial;
|
||||||
}
|
|
||||||
}
|
|
||||||
@-moz-document url-prefix() {
|
|
||||||
.user_content
|
|
||||||
{
|
|
||||||
font-family: EmojiFont, arial;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
user.go
2
user.go
|
@ -154,7 +154,7 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, succ
|
||||||
user.Session = cookie.Value
|
user.Session = cookie.Value
|
||||||
|
|
||||||
// Is this session valid..?
|
// Is this session valid..?
|
||||||
err = get_session_stmt.QueryRow(user.ID,user.Session).Scan(&user.ID, &user.Name, &user.Group, &user.Is_Super_Admin, &user.Session, &user.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)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
user.ID = 0
|
user.ID = 0
|
||||||
user.Session = ""
|
user.Session = ""
|
||||||
|
|
16
utils.go
16
utils.go
|
@ -1,6 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
import "log"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
import "time"
|
import "time"
|
||||||
|
import "os"
|
||||||
import "encoding/base64"
|
import "encoding/base64"
|
||||||
import "crypto/rand"
|
import "crypto/rand"
|
||||||
import "net/smtp"
|
import "net/smtp"
|
||||||
|
@ -87,3 +89,17 @@ func SendEmail(email string, subject string, msg string) bool {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func write_file(name string, content string) {
|
||||||
|
f, err := os.Create(name)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = f.WriteString(content)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
f.Sync()
|
||||||
|
f.Close()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue