2017-05-07 08:31:41 +00:00
/* Copyright Azareal 2016 - 2018 */
2016-12-02 07:38:54 +00:00
package main
import (
"net/http"
2017-05-07 08:31:41 +00:00
"fmt"
2016-12-02 07:38:54 +00:00
"log"
2016-12-05 07:21:17 +00:00
"mime"
2017-06-05 11:57:27 +00:00
"time"
2016-12-08 14:11:18 +00:00
"strings"
2016-12-02 07:38:54 +00:00
"path/filepath"
2016-12-17 03:39:53 +00:00
"io"
2016-12-05 07:21:17 +00:00
"io/ioutil"
2016-12-09 13:46:29 +00:00
"os"
2016-12-02 07:38:54 +00:00
"html/template"
2017-01-17 07:55:46 +00:00
//"runtime/pprof"
2016-12-02 07:38:54 +00:00
)
2017-05-07 08:31:41 +00:00
var version Version = Version { Major : 0 , Minor : 1 , Patch : 0 , Tag : "dev" }
2016-12-02 07:38:54 +00:00
const hour int = 60 * 60
const day int = hour * 24
const month int = day * 30
const year int = day * 365
2016-12-02 15:03:31 +00:00
const kilobyte int = 1024
2017-04-12 10:10:36 +00:00
const megabyte int = kilobyte * 1024
2017-05-07 08:31:41 +00:00
const gigabyte int = megabyte * 1024
const terabyte int = gigabyte * 1024
2017-05-12 13:25:12 +00:00
//const thousand int = 1000
//const million int = 1_000_000
//const billion int = 1_000_000_000
2016-12-02 07:38:54 +00:00
const saltLength int = 32
const sessionLength int = 80
2017-05-11 13:04:43 +00:00
var enable_websockets bool = false // Don't change this, the value is overwritten by an initialiser
2016-12-04 06:16:59 +00:00
2017-06-05 11:57:27 +00:00
var startTime time . Time
var timeLocation * time . Location
2017-01-21 18:16:27 +00:00
var templates = template . New ( "" )
2016-12-04 06:16:59 +00:00
var no_css_tmpl = template . CSS ( "" )
var staff_css_tmpl = template . CSS ( staff_css )
2016-12-09 13:46:29 +00:00
var settings map [ string ] interface { } = make ( map [ string ] interface { } )
var external_sites map [ string ] string = make ( map [ string ] string )
2017-01-31 05:13:38 +00:00
var groups [ ] Group
var forums [ ] Forum // The IDs for a forum tend to be low and sequential for the most part, so we can get more performance out of using a slice instead of a map AND it has better concurrency
2017-02-04 06:19:55 +00:00
var forum_perms map [ int ] map [ int ] ForumPerms // [gid][fid]Perms
2017-06-15 11:40:35 +00:00
var fstore ForumStore // :soon:
2017-06-05 11:57:27 +00:00
var groupCapCount , forumCapCount int
2016-12-05 07:21:17 +00:00
var static_files map [ string ] SFile = make ( map [ string ] SFile )
2017-01-01 15:45:43 +00:00
2016-12-21 02:30:32 +00:00
var template_topic_handle func ( TopicPage , io . Writer ) = nil
2016-12-26 04:44:07 +00:00
var template_topic_alt_handle func ( TopicPage , io . Writer ) = nil
2017-01-01 15:45:43 +00:00
var template_topics_handle func ( TopicsPage , io . Writer ) = nil
var template_forum_handle func ( ForumPage , io . Writer ) = nil
var template_forums_handle func ( ForumsPage , io . Writer ) = nil
2016-12-26 04:44:07 +00:00
var template_profile_handle func ( ProfilePage , io . Writer ) = nil
2017-02-05 14:41:53 +00:00
var template_create_topic_handle func ( CreateTopicPage , io . Writer ) = nil
2016-12-16 10:37:42 +00:00
func compile_templates ( ) {
var c CTemplateSet
2017-01-17 07:55:46 +00:00
user := User { 62 , "" , "compiler@localhost" , 0 , false , false , false , false , false , false , GuestPerms , "" , false , "" , "" , "" , "" , "" , 0 , 0 , "0.0.0.0.0" }
2017-06-16 10:41:30 +00:00
headerVars := HeaderVars {
NoticeList : [ ] string { "test" } ,
Stylesheets : [ ] string { "panel" } ,
Scripts : [ ] string { "whatever" } ,
}
2017-06-05 11:57:27 +00:00
2016-12-16 10:37:42 +00:00
log . Print ( "Compiling the templates" )
2017-06-05 11:57:27 +00:00
2017-06-12 09:03:14 +00:00
topic := TopicUser { 1 , "Blah" , "Hey there!" , 0 , false , false , "Date" , "Date" , 0 , "" , "127.0.0.1" , 0 , 1 , "classname" , "" , "" , default_group , "" , no_css_tmpl , 0 , "" , "" , "" , "" , 58 , false }
2016-12-21 02:30:32 +00:00
var replyList [ ] Reply
2017-04-02 13:00:40 +00:00
replyList = append ( replyList , Reply { 0 , 0 , "" , "Yo!" , 0 , "" , default_group , "" , 0 , 0 , "" , no_css_tmpl , 0 , "" , "" , "" , "" , 0 , "127.0.0.1" , false , 1 , "" , "" } )
2017-06-05 11:57:27 +00:00
2016-12-21 02:30:32 +00:00
var varList map [ string ] VarItem = make ( map [ string ] VarItem )
2017-06-16 10:41:30 +00:00
tpage := TopicPage { "Title" , user , headerVars , replyList , topic , 1 , 1 , extData }
2016-12-21 02:30:32 +00:00
topic_id_tmpl := c . compile_template ( "topic.html" , "templates/" , "TopicPage" , tpage , varList )
2016-12-26 04:44:07 +00:00
topic_id_alt_tmpl := c . compile_template ( "topic_alt.html" , "templates/" , "TopicPage" , tpage , varList )
2017-06-05 11:57:27 +00:00
2016-12-16 10:37:42 +00:00
varList = make ( map [ string ] VarItem )
2017-06-16 10:41:30 +00:00
ppage := ProfilePage { "User 526" , user , headerVars , replyList , user , extData }
2016-12-26 04:44:07 +00:00
profile_tmpl := c . compile_template ( "profile.html" , "templates/" , "ProfilePage" , ppage , varList )
2017-06-05 11:57:27 +00:00
2017-01-01 15:45:43 +00:00
var forumList [ ] Forum
2016-12-18 12:56:06 +00:00
for _ , forum := range forums {
if forum . Active {
2017-02-10 13:39:13 +00:00
forumList = append ( forumList , forum )
2016-12-18 12:56:06 +00:00
}
}
varList = make ( map [ string ] VarItem )
2017-06-16 10:41:30 +00:00
forums_page := ForumsPage { "Forum List" , user , headerVars , forumList , extData }
2017-01-01 15:45:43 +00:00
forums_tmpl := c . compile_template ( "forums.html" , "templates/" , "ForumsPage" , forums_page , varList )
2017-06-05 11:57:27 +00:00
2017-02-06 04:52:19 +00:00
var topicsList [ ] TopicsRow
2017-06-05 11:57:27 +00:00
topicsList = append ( topicsList , TopicsRow { 1 , "Topic Title" , "The topic content." , 1 , false , false , "Date" , "Date" , 1 , "" , "127.0.0.1" , 0 , 1 , "classname" , "Admin" , "" , "" , 0 , "" , "" , "" , "" , 58 , "General" } )
2017-06-16 10:41:30 +00:00
topics_page := TopicsPage { "Topic List" , user , headerVars , topicsList , extData }
2017-01-01 15:45:43 +00:00
topics_tmpl := c . compile_template ( "topics.html" , "templates/" , "TopicsPage" , topics_page , varList )
2017-06-05 11:57:27 +00:00
2017-02-06 04:52:19 +00:00
var topicList [ ] TopicUser
2017-06-12 09:03:14 +00:00
topicList = append ( topicList , TopicUser { 1 , "Topic Title" , "The topic content." , 1 , false , false , "Date" , "Date" , 1 , "" , "127.0.0.1" , 0 , 1 , "classname" , "" , "Admin" , default_group , "" , "" , 0 , "" , "" , "" , "" , 58 , false } )
2017-06-05 11:57:27 +00:00
forum_item := Forum { 1 , "General Forum" , "Where the general stuff happens" , true , "all" , 0 , "" , 0 , "" , 0 , "" }
2017-06-16 10:41:30 +00:00
forum_page := ForumPage { "General Forum" , user , headerVars , topicList , forum_item , 1 , 1 , extData }
2017-01-01 15:45:43 +00:00
forum_tmpl := c . compile_template ( "forum.html" , "templates/" , "ForumPage" , forum_page , varList )
2017-06-05 11:57:27 +00:00
2016-12-16 10:37:42 +00:00
log . Print ( "Writing the templates" )
2017-01-17 07:55:46 +00:00
go write_template ( "topic" , topic_id_tmpl )
go write_template ( "topic_alt" , topic_id_alt_tmpl )
go write_template ( "profile" , profile_tmpl )
go write_template ( "forums" , forums_tmpl )
go write_template ( "topics" , topics_tmpl )
go write_template ( "forum" , forum_tmpl )
2017-02-10 13:39:13 +00:00
go write_file ( "./template_list.go" , "package main\n\n" + c . FragOut )
2016-12-16 10:37:42 +00:00
}
func write_template ( name string , content string ) {
2017-05-02 17:24:33 +00:00
err := write_file ( "./template_" + name + ".go" , content )
if err != nil {
log . Fatal ( err )
}
2016-12-16 10:37:42 +00:00
}
2016-12-02 07:38:54 +00:00
2017-01-21 18:16:27 +00:00
func init_templates ( ) {
2017-06-16 10:41:30 +00:00
if debug {
log . Print ( "Initialising the template system" )
}
2017-01-21 18:16:27 +00:00
compile_templates ( )
2017-06-05 11:57:27 +00:00
2017-01-21 18:16:27 +00:00
// Filler functions for now...
2017-05-07 08:31:41 +00:00
filler_func := func ( in interface { } , in2 interface { } ) interface { } {
2017-01-21 18:16:27 +00:00
return 1
}
2017-05-07 08:31:41 +00:00
fmap := make ( map [ string ] interface { } )
fmap [ "add" ] = filler_func
fmap [ "subtract" ] = filler_func
fmap [ "multiply" ] = filler_func
fmap [ "divide" ] = filler_func
2017-06-05 11:57:27 +00:00
2017-01-21 18:16:27 +00:00
// The interpreted templates...
2017-06-16 10:41:30 +00:00
if debug {
log . Print ( "Loading the template files..." )
}
2017-01-21 18:16:27 +00:00
templates . Funcs ( fmap )
template . Must ( templates . ParseGlob ( "templates/*" ) )
template . Must ( templates . ParseGlob ( "pages/*" ) )
}
2017-02-15 10:49:30 +00:00
func init_static_files ( ) {
log . Print ( "Loading the static files." )
err := filepath . Walk ( "./public" , func ( path string , f os . FileInfo , err error ) error {
if f . IsDir ( ) {
return nil
}
2017-06-05 11:57:27 +00:00
2017-02-15 10:49:30 +00:00
path = strings . Replace ( path , "\\" , "/" , - 1 )
data , err := ioutil . ReadFile ( path )
if err != nil {
return err
}
2017-06-05 11:57:27 +00:00
2017-02-15 10:49:30 +00:00
path = strings . TrimPrefix ( path , "public/" )
2017-05-07 08:31:41 +00:00
if debug {
log . Print ( "Added the '" + path + "' static file." )
}
2017-02-16 06:47:55 +00:00
gzip_data := compress_bytes_gzip ( data )
2017-06-05 11:57:27 +00:00
2017-02-16 06:47:55 +00:00
static_files [ "/static/" + path ] = SFile { data , gzip_data , 0 , int64 ( len ( data ) ) , int64 ( len ( gzip_data ) ) , mime . TypeByExtension ( filepath . Ext ( "/public/" + path ) ) , f , f . ModTime ( ) . UTC ( ) . Format ( http . TimeFormat ) }
2017-02-15 10:49:30 +00:00
return nil
} )
if err != nil {
log . Fatal ( err )
}
}
2016-12-02 07:38:54 +00:00
func main ( ) {
2017-01-17 07:55:46 +00:00
//if profiling {
// f, err := os.Create("startup_cpu.prof")
// if err != nil {
// log.Fatal(err)
// }
// pprof.StartCPUProfile(f)
//}
2017-06-05 11:57:27 +00:00
2017-05-07 08:31:41 +00:00
log . Print ( "Running Gosora v" + version . String ( ) )
fmt . Println ( "" )
2017-06-05 11:57:27 +00:00
startTime = time . Now ( )
timeLocation = startTime . Location ( )
2017-01-01 15:45:43 +00:00
init_themes ( )
2017-04-12 10:10:36 +00:00
err := init_database ( )
if err != nil {
log . Fatal ( err )
}
2017-06-05 11:57:27 +00:00
2017-01-21 18:16:27 +00:00
init_templates ( )
2017-01-17 07:55:46 +00:00
err = init_errors ( )
if err != nil {
log . Fatal ( err )
}
2017-06-05 11:57:27 +00:00
2017-02-11 14:51:16 +00:00
if cache_topicuser == CACHE_STATIC {
2017-06-15 11:40:35 +00:00
users = NewMemoryUserStore ( user_cache_capacity )
topics = NewMemoryTopicStore ( topic_cache_capacity )
2017-02-11 14:51:16 +00:00
} else {
users = NewSqlUserStore ( )
topics = NewSqlTopicStore ( )
}
2017-06-05 11:57:27 +00:00
2017-02-15 10:49:30 +00:00
init_static_files ( )
2016-12-09 13:46:29 +00:00
external_sites [ "YT" ] = "https://www.youtube.com/"
2016-12-11 16:06:17 +00:00
hooks [ "trow_assign" ] = nil
hooks [ "rrow_assign" ] = nil
2017-01-01 15:45:43 +00:00
init_plugins ( )
2017-06-05 11:57:27 +00:00
2017-04-13 09:26:40 +00:00
router := NewGenRouter ( http . FileServer ( http . Dir ( "./uploads" ) ) )
///router.HandleFunc("/static/", route_static)
///router.HandleFunc("/overview/", route_overview)
///router.HandleFunc("/topics/create/", route_topic_create)
///router.HandleFunc("/topics/", route_topics)
///router.HandleFunc("/forums/", route_forums)
2017-04-13 15:01:30 +00:00
///router.HandleFunc("/forum/", route_forum)
2017-01-03 07:47:31 +00:00
router . HandleFunc ( "/topic/create/submit/" , route_create_topic )
router . HandleFunc ( "/topic/" , route_topic_id )
router . HandleFunc ( "/reply/create/" , route_create_reply )
//router.HandleFunc("/reply/edit/", route_reply_edit)
//router.HandleFunc("/reply/delete/", route_reply_delete)
router . HandleFunc ( "/reply/edit/submit/" , route_reply_edit_submit )
router . HandleFunc ( "/reply/delete/submit/" , route_reply_delete_submit )
2017-02-10 13:39:13 +00:00
router . HandleFunc ( "/reply/like/submit/" , route_reply_like_submit )
2017-05-02 17:24:33 +00:00
///router.HandleFunc("/report/submit/", route_report_submit)
2017-01-03 07:47:31 +00:00
router . HandleFunc ( "/topic/edit/submit/" , route_edit_topic )
router . HandleFunc ( "/topic/delete/submit/" , route_delete_topic )
router . HandleFunc ( "/topic/stick/submit/" , route_stick_topic )
router . HandleFunc ( "/topic/unstick/submit/" , route_unstick_topic )
2017-02-10 13:39:13 +00:00
router . HandleFunc ( "/topic/like/submit/" , route_like_topic )
2017-06-05 11:57:27 +00:00
2017-01-03 07:47:31 +00:00
// Custom Pages
router . HandleFunc ( "/pages/" , route_custom_page )
2017-06-05 11:57:27 +00:00
2017-01-03 07:47:31 +00:00
// Accounts
router . HandleFunc ( "/accounts/login/" , route_login )
router . HandleFunc ( "/accounts/create/" , route_register )
router . HandleFunc ( "/accounts/logout/" , route_logout )
router . HandleFunc ( "/accounts/login/submit/" , route_login_submit )
router . HandleFunc ( "/accounts/create/submit/" , route_register_submit )
2017-06-05 11:57:27 +00:00
2017-01-03 07:47:31 +00:00
//router.HandleFunc("/accounts/list/", route_login) // Redirect /accounts/ and /user/ to here.. // Get a list of all of the accounts on the forum
//router.HandleFunc("/accounts/create/full/", route_logout) // Advanced account creator for admins?
//router.HandleFunc("/user/edit/", route_logout)
router . HandleFunc ( "/user/edit/critical/" , route_account_own_edit_critical ) // Password & Email
router . HandleFunc ( "/user/edit/critical/submit/" , route_account_own_edit_critical_submit )
router . HandleFunc ( "/user/edit/avatar/" , route_account_own_edit_avatar )
router . HandleFunc ( "/user/edit/avatar/submit/" , route_account_own_edit_avatar_submit )
router . HandleFunc ( "/user/edit/username/" , route_account_own_edit_username )
router . HandleFunc ( "/user/edit/username/submit/" , route_account_own_edit_username_submit )
router . HandleFunc ( "/user/edit/email/" , route_account_own_edit_email )
2017-03-18 07:23:02 +00:00
router . HandleFunc ( "/user/edit/token/" , route_account_own_edit_email_token_submit )
2017-01-03 07:47:31 +00:00
router . HandleFunc ( "/user/" , route_profile )
router . HandleFunc ( "/profile/reply/create/" , route_profile_reply_create )
router . HandleFunc ( "/profile/reply/edit/submit/" , route_profile_reply_edit_submit )
router . HandleFunc ( "/profile/reply/delete/submit/" , route_profile_reply_delete_submit )
//router.HandleFunc("/user/edit/submit/", route_logout)
router . HandleFunc ( "/users/ban/" , route_ban )
router . HandleFunc ( "/users/ban/submit/" , route_ban_submit )
router . HandleFunc ( "/users/unban/" , route_unban )
router . HandleFunc ( "/users/activate/" , route_activate )
2017-06-05 11:57:27 +00:00
2017-04-13 10:55:51 +00:00
// The Control Panel
///router.HandleFunc("/panel/", route_panel)
///router.HandleFunc("/panel/forums/", route_panel_forums)
///router.HandleFunc("/panel/forums/create/", route_panel_forums_create_submit)
///router.HandleFunc("/panel/forums/delete/", route_panel_forums_delete)
///router.HandleFunc("/panel/forums/delete/submit/", route_panel_forums_delete_submit)
///router.HandleFunc("/panel/forums/edit/", route_panel_forums_edit)
///router.HandleFunc("/panel/forums/edit/submit/", route_panel_forums_edit_submit)
2017-06-05 11:57:27 +00:00
///router.HandleFunc("/panel/forums/edit/perms/submit/", route_panel_forums_edit_perms_submit)
2017-04-13 15:01:30 +00:00
///router.HandleFunc("/panel/settings/", route_panel_settings)
///router.HandleFunc("/panel/settings/edit/", route_panel_setting)
///router.HandleFunc("/panel/settings/edit/submit/", route_panel_setting_edit)
///router.HandleFunc("/panel/themes/", route_panel_themes)
///router.HandleFunc("/panel/themes/default/", route_panel_themes_default)
///router.HandleFunc("/panel/plugins/", route_panel_plugins)
///router.HandleFunc("/panel/plugins/activate/", route_panel_plugins_activate)
///router.HandleFunc("/panel/plugins/deactivate/", route_panel_plugins_deactivate)
///router.HandleFunc("/panel/users/", route_panel_users)
///router.HandleFunc("/panel/users/edit/", route_panel_users_edit)
///router.HandleFunc("/panel/users/edit/submit/", route_panel_users_edit_submit)
///router.HandleFunc("/panel/groups/", route_panel_groups)
///router.HandleFunc("/panel/groups/edit/", route_panel_groups_edit)
///router.HandleFunc("/panel/groups/edit/perms/", route_panel_groups_edit_perms)
///router.HandleFunc("/panel/groups/edit/submit/", route_panel_groups_edit_submit)
///router.HandleFunc("/panel/groups/edit/perms/submit/", route_panel_groups_edit_perms_submit)
///router.HandleFunc("/panel/groups/create/", route_panel_groups_create_submit)
///router.HandleFunc("/panel/logs/mod/", route_panel_logs_mod)
2017-06-05 11:57:27 +00:00
2017-05-02 17:24:33 +00:00
///router.HandleFunc("/api/", route_api)
//router.HandleFunc("/exit/", route_exit)
2017-04-13 09:26:40 +00:00
///router.HandleFunc("/", default_route)
2017-05-11 13:04:43 +00:00
router . HandleFunc ( "/ws/" , route_websockets )
2016-12-02 07:38:54 +00:00
defer db . Close ( )
2017-06-05 11:57:27 +00:00
2017-01-17 07:55:46 +00:00
//if profiling {
// pprof.StopCPUProfile()
//}
2017-06-05 11:57:27 +00:00
2017-01-03 07:47:31 +00:00
if ! enable_ssl {
if server_port == "" {
server_port = "80"
}
http . ListenAndServe ( ":" + server_port , router )
} else {
if server_port == "" {
server_port = "443"
}
http . ListenAndServeTLS ( ":" + server_port , ssl_fullchain , ssl_privkey , router )
}
2017-04-13 15:01:30 +00:00
}