From 37ba7255fe7efed50daff7bb568361acad590fbe Mon Sep 17 00:00:00 2001 From: Tim Schuster Date: Wed, 15 Mar 2017 14:33:27 +0100 Subject: [PATCH] Embedded Resources --- config/config.go | 3 ++ http/admin/handler.go | 16 ++++------- http/admin/rice-box.go | 55 +++++++++++++++++++++++++++++++++++++ http/board/handler.go | 25 ++++++----------- http/board/rice-box.go | 62 ++++++++++++++++++++++++++++++++++++++++++ http/errw/handler.go | 20 +++++--------- http/errw/rice-box.go | 41 ++++++++++++++++++++++++++++ http/rice-box.go | 55 +++++++++++++++++++++++++++++++++++++ http/server.go | 23 ++++++++++++++-- 9 files changed, 257 insertions(+), 43 deletions(-) create mode 100644 http/admin/rice-box.go create mode 100644 http/board/rice-box.go create mode 100644 http/errw/rice-box.go create mode 100644 http/rice-box.go diff --git a/config/config.go b/config/config.go index 4a269fc..283622a 100644 --- a/config/config.go +++ b/config/config.go @@ -2,6 +2,7 @@ package config import ( "flag" + "github.com/GeertJohan/go.rice" "gopkg.in/yaml.v2" "io/ioutil" "os" @@ -25,6 +26,8 @@ type Config struct { const ( CaptchaRecaptcha = "recaptcha" + CaptchaInternal = "internal" + CaptchaHybrid = "hybrid" CaptchaDisabled = "disabled" ) diff --git a/http/admin/handler.go b/http/admin/handler.go index 763e4b4..a8e630a 100644 --- a/http/admin/handler.go +++ b/http/admin/handler.go @@ -11,24 +11,18 @@ import ( "time" ) -var riceConf = rice.Config{ - LocateOrder: []rice.LocateMethod{ - rice.LocateWorkingDirectory, - rice.LocateEmbedded, - rice.LocateAppended, - }, -} - -var box = riceConf.MustFindBox("http/admin/res/") - var ( panelTmpl = template.New("admin/panel") loginTmpl = template.New("admin/login") statusTmpl = template.New("admin/status") ) -func init() { +func LoadTemplates() error { var err error + box, err := rice.FindBox("res/") + if err != nil { + panic(err) + } panelTmpl, err = panelTmpl.Parse(box.MustString("panel.html")) if err != nil { panic(err) diff --git a/http/admin/rice-box.go b/http/admin/rice-box.go new file mode 100644 index 0000000..b3f834b --- /dev/null +++ b/http/admin/rice-box.go @@ -0,0 +1,55 @@ +package admin + +import ( + "github.com/GeertJohan/go.rice/embedded" + "time" +) + +func init() { + + // define files + file2 := &embedded.EmbeddedFile{ + Filename: `index.html`, + FileModTime: time.Unix(1489315188, 0), + Content: string("\n\n\n \n \n {{.Config.Site.Title}} Admin Login\n \n \n \n\n\n
\n
\n \n
\n \n
\n
\n \n
\n
\n \n \n
\n \n
\n\n"), + } + file3 := &embedded.EmbeddedFile{ + Filename: `panel.html`, + FileModTime: time.Unix(1489566364, 0), + Content: string("\n\n\n \n \n {{.Config.Site.Title}} Admin Panel\n \n \n \n\n\n
\n Welcome {{.Admin.Id}}
\n
\n \n \n \n
\n

\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n Action\n \n New Board\n \n
\n Short Name\n \n \n
\n Long Name\n \n \n
\n \n \n
\n
\n
\n

\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n Action\n \n New Administrator\n \n
\n ID\n \n \n
\n Password\n \n \n
\n \n \n
\n
\n
\n

\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n Action\n \n Delete Administrator\n \n
\n ID\n \n \n
\n \n \n
\n
\n
\n

\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n
\n Action\n \n Cleanup Database\n \n
\n \n \n
\n
\n
\n

\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n Action\n \n Set Board Rules\n \n
\n Board Name (Short)\n \n \n
\n Rules\n \n \n \n
\n \n \n
\n
\n
\n

\n\n"), + } + file4 := &embedded.EmbeddedFile{ + Filename: `status.html`, + FileModTime: time.Unix(1489525499, 0), + Content: string("\n\n\n \n \n {{.Config.Site.Title}} Status\n \n \n \n\n\n
\n

Runtime Statistics

\n
\n
\n
\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n Start Time\n \n {{.Uptime.human}}\n
\n Uptime (Precise)\n \n {{ .Uptime.hours | printf \"%.4f\"}} hours
\n {{ .Uptime.seconds | printf \"%.4f\"}} seconds\n
\n Num. CPU\n \n {{.GC.numcpu}}\n
\n Num. GoRoutines\n \n {{.GC.numgor}}\n
\n Go Version
\n Arch/OS/Compiler\n
\n {{.GC.version}}
\n {{.GC.arch}} / {{.GC.os}} / {{.GC.compiler}}\n
\n Current Allocs\n \n {{.GC.memory.alloc}}\n
\n Cumulative Allocs\n \n {{.GC.memory.calloc}}\n
\n Used Sys Memory\n \n {{.GC.memory.sysmem}}\n
\n Pointer Lookups\n \n {{.GC.memory.lookups}}\n
\n MAllocs\n \n {{.GC.memory.mallocs}}\n
\n MFrees\n \n {{.GC.memory.frees}}\n
\n Live Objects\n \n {{.GC.memory.liveobj}}\n
\n Heap Allocated\n \n {{.GC.memory.heapalloc}}\n
\n Heap Released\n \n {{.GC.memory.heaprelease}}\n
\n GC Metadata\n \n {{.GC.memory.gcmeta}}\n
\n GC Pause\n \n {{.GC.memory.pause}}\n
\n GC Invokations\n \n {{.GC.memory.gctimes}}\n
\n GC Forced\n \n {{.GC.memory.fgctimes}}\n
\n GC CPU Usage\n \n {{.GC.memory.cpufrac}}\n
\n
\n
\n

\n\n"), + } + + // define dirs + dir1 := &embedded.EmbeddedDir{ + Filename: ``, + DirModTime: time.Unix(1489566364, 0), + ChildFiles: []*embedded.EmbeddedFile{ + file2, // index.html + file3, // panel.html + file4, // status.html + + }, + } + + // link ChildDirs + dir1.ChildDirs = []*embedded.EmbeddedDir{} + + // register embeddedBox + embedded.RegisterEmbeddedBox(`res/`, &embedded.EmbeddedBox{ + Name: `res/`, + Time: time.Unix(1489566364, 0), + Dirs: map[string]*embedded.EmbeddedDir{ + "": dir1, + }, + Files: map[string]*embedded.EmbeddedFile{ + "index.html": file2, + "panel.html": file3, + "status.html": file4, + }, + }) +} diff --git a/http/board/handler.go b/http/board/handler.go index 71b5c2c..5f0fd18 100644 --- a/http/board/handler.go +++ b/http/board/handler.go @@ -15,16 +15,6 @@ import ( "time" ) -var riceConf = rice.Config{ - LocateOrder: []rice.LocateMethod{ - rice.LocateWorkingDirectory, - rice.LocateEmbedded, - rice.LocateAppended, - }, -} - -var box = riceConf.MustFindBox("http/board/res/") - var ( tmpls = template.New("base") @@ -57,24 +47,27 @@ var ( } ) -func init() { - var err error +func LoadTemplates() error { + box, err := rice.FindBox("res/") + if err != nil { + return err + } tmpls = tmpls.Funcs(hdlFMap) tmpls, err = tmpls.New("thread/postlists").Parse(box.MustString("thread.tmpl.html")) if err != nil { - panic(err) + return err } _, err = tmpls.New("board/dir").Parse(box.MustString("dir.html")) if err != nil { - panic(err) + return err } _, err = tmpls.New("board/board").Parse(box.MustString("board.html")) if err != nil { - panic(err) + return err } _, err = tmpls.New("board/thread").Parse(box.MustString("thread.html")) if err != nil { - panic(err) + return err } } diff --git a/http/board/rice-box.go b/http/board/rice-box.go new file mode 100644 index 0000000..4d3d51b --- /dev/null +++ b/http/board/rice-box.go @@ -0,0 +1,62 @@ +package board + +import ( + "github.com/GeertJohan/go.rice/embedded" + "time" +) + +func init() { + + // define files + file2 := &embedded.EmbeddedFile{ + Filename: `board.html`, + FileModTime: time.Unix(1489412682, 0), + Content: string("\n\n\n \n \n {{.Config.Site.Title}} - /{{.Board.ShortName}}/\n \n \n\n\n
\n \n

{{.Board.LongName}}

\n
\n{{ $boardlink := .Board.ShortName }}\n{{ if .Session }}\n{{ if eq (.Session.CAttr \"mode\") \"admin\" }}\nLogged in as Admin\n{{ end }}\n{{ if eq (.Session.CAttr \"mode\") \"mod\" }}\nLogged in as Mod for {{ .Session.CAttr \"board\" }}\n{{ end }}\n{{ end }}\n
\n{{ template \"thread/post\" . }}\n
\n {{ $board := .Board }}\n {{ $csrf := .CSRFToken }}\n {{ $session := .Session }}\n {{range .Threads}}\n {{ template \"thread/postlists\" dict \"Thread\" . \"Board\" $board \"CSRFToken\" $csrf \"Session\" $session }}\n {{end}}\n
\n\n"), + } + file3 := &embedded.EmbeddedFile{ + Filename: `dir.html`, + FileModTime: time.Unix(1489315156, 0), + Content: string("\n\n\n \n \n {{.Config.Site.Title}} Boards\n \n \n\n\n
\n

{{.Config.Site.Title}}

\n

{{.Config.Site.Description}}

\n
\n
\n
\n

Boards

\n
\n
\n \n
\n
\n\n"), + } + file4 := &embedded.EmbeddedFile{ + Filename: `thread.html`, + FileModTime: time.Unix(1489412660, 0), + Content: string("\n\n\n \n \n {{.Config.Site.Title}} - /{{.Board.ShortName}}/\n \n \n\n\n
\n \n

{{.Board.LongName}}

\n

{{.Thread.ID}}

\n
\n{{ $boardlink := .Board.ShortName }}\n
\n{{ template \"thread/post\" . }}\n{{ template \"thread/postlists\" . }}\n\n"), + } + file5 := &embedded.EmbeddedFile{ + Filename: `thread.tmpl.html`, + FileModTime: time.Unix(1489566591, 0), + Content: string("{{ define \"thread/post\" }}\n
\n {{ if .Thread }}\n
\n {{ else }}\n \n {{ end }}\n \n \n {{ if .PreviousError }}\n \n \n \n \n {{ end }}\n \n \n \n \n \n \n \n \n \n \n \n \n {{ if ne .Config.Captcha.Mode \"disabled\" }}\n \n \n \n \n {{ end }}\n {{ if (isModSession .Session) }}\n \n \n \n \n {{ end }}\n \n \n \n \n {{ if .Board.Metadata.rules }}\n \n \n \n \n {{ end }}\n \n
\n Error\n \n {{.PreviousError}}\n
\n TripCode\n \n \n \n
\n Comment\n \n \n
\n Image File\n \n \n
\n Captcha\n \n {{ $captchaId := makeCaptcha }}\n \"Captcha\n \n
\n \n \n
\n Mod Post\n \n \n {{ if (isAdminSession .Session) }}\n \n {{ end }}\n
\n\n \n \n
\n Rules\n \n {{ renderText .Board.Metadata.rules }}\n
\n
\n
\n
\n{{ end }}\n\n{{ define \"thread/reply\" }}\n \n {{dateFromID .Reply.ID | formatDate}}\n {{ if .Session }}\n {{ if eq (.Session.CAttr \"mode\") \"admin\" }}\n
\n \n \n \n \n \n \n {{ end }}\n {{ end }}\n \n {{ if not .Reply.Metadata.spamscore }}\n {{ $score := (rateSpam .Reply.Text) }}\n {{printf \"[SpamScore: %f]\" $score }}\n {{printf \"[Captcha: %.3f%%]\" (percentFloat (captchaProb $score)) }}\n {{printf \"[OLD]\"}}\n {{ else }}\n {{ printf \"[SpamScore: %s]\" .Reply.Metadata.spamscore }}\n {{ printf \"[Captcha: %s %%]\" .Reply.Metadata.captchaprob }}\n {{ end }}\n \n \n No.{{.Reply.ID}}\n \n {{ if .Reply.Thumbnail }}\n
\n \n \n \n {{ end }}\n {{ if .Reply.Metadata.deleted }}\n
\n {{ renderText .Reply.Text }}\n
\n {{ else }}\n
\n {{ renderText .Reply.Text}}\n
\n {{ end }}\n{{ end }}\n\n{{ define \"thread/main\" }}\n
\n {{ $boardlink := .Board.ShortName }}\n {{ $threadrid := .Thread.GetReply.ID }}\n {{ $threadid := .Thread.ID }}\n {{ $csrf := .CSRFToken }}\n {{ $session := .Session }}\n {{ with .Thread }}\n {{ with .GetReply }}\n {{ with dict \"Reply\" . \"Boardlink\" $boardlink \"CSRF\" $csrf \"ThreadID\" $threadid \"Session\" $session }}\n {{ template \"thread/reply\" . }}\n {{ end }}\n {{ end }}\n {{range .GetReplies}}\n {{ if ne .ID $threadrid }}\n \n \n
>>\n {{ with dict \"Reply\" . \"Boardlink\" $boardlink \"CSRF\" $csrf \"ThreadID\" $threadid \"Session\" $session }}\n {{ template \"thread/reply\" . }}\n {{ end }}\n
\n {{end}}\n {{end}}\n {{end}}\n

\n
\n{{ end }}\n\n{{ template \"thread/main\" . }}"), + } + + // define dirs + dir1 := &embedded.EmbeddedDir{ + Filename: ``, + DirModTime: time.Unix(1489566591, 0), + ChildFiles: []*embedded.EmbeddedFile{ + file2, // board.html + file3, // dir.html + file4, // thread.html + file5, // thread.tmpl.html + + }, + } + + // link ChildDirs + dir1.ChildDirs = []*embedded.EmbeddedDir{} + + // register embeddedBox + embedded.RegisterEmbeddedBox(`res/`, &embedded.EmbeddedBox{ + Name: `res/`, + Time: time.Unix(1489566591, 0), + Dirs: map[string]*embedded.EmbeddedDir{ + "": dir1, + }, + Files: map[string]*embedded.EmbeddedFile{ + "board.html": file2, + "dir.html": file3, + "thread.html": file4, + "thread.tmpl.html": file5, + }, + }) +} diff --git a/http/errw/handler.go b/http/errw/handler.go index a1c854d..9c436ee 100644 --- a/http/errw/handler.go +++ b/http/errw/handler.go @@ -9,26 +9,20 @@ import ( "net/http" ) -var riceConf = rice.Config{ - LocateOrder: []rice.LocateMethod{ - rice.LocateWorkingDirectory, - rice.LocateEmbedded, - rice.LocateAppended, - }, -} - -var box = riceConf.MustFindBox("http/errw/res/") - var ( errorTmpl = template.New("errw/error") ) -func init() { - var err error +func LoadTemplates() error { + box, err := rice.FindBox("res/") + if err != nil { + return err + } errorTmpl, err = errorTmpl.Parse(box.MustString("error.html")) if err != nil { - panic(err) + return err } + return nil } type ErrorWithTitle interface { diff --git a/http/errw/rice-box.go b/http/errw/rice-box.go new file mode 100644 index 0000000..dce39e3 --- /dev/null +++ b/http/errw/rice-box.go @@ -0,0 +1,41 @@ +package errw + +import ( + "github.com/GeertJohan/go.rice/embedded" + "time" +) + +func init() { + + // define files + file2 := &embedded.EmbeddedFile{ + Filename: `error.html`, + FileModTime: time.Unix(1489238440, 0), + Content: string("\n\n\n \n \n {{.Config.Site.Title}} Admin Login\n \n\n\n
\n

{{.Error.Title}}


\n

{{.Error.Code}}


\n

{{.Error.Description}}

\n
\n\n"), + } + + // define dirs + dir1 := &embedded.EmbeddedDir{ + Filename: ``, + DirModTime: time.Unix(1489240168, 0), + ChildFiles: []*embedded.EmbeddedFile{ + file2, // error.html + + }, + } + + // link ChildDirs + dir1.ChildDirs = []*embedded.EmbeddedDir{} + + // register embeddedBox + embedded.RegisterEmbeddedBox(`res/`, &embedded.EmbeddedBox{ + Name: `res/`, + Time: time.Unix(1489240168, 0), + Dirs: map[string]*embedded.EmbeddedDir{ + "": dir1, + }, + Files: map[string]*embedded.EmbeddedFile{ + "error.html": file2, + }, + }) +} diff --git a/http/rice-box.go b/http/rice-box.go new file mode 100644 index 0000000..c7f2fb1 --- /dev/null +++ b/http/rice-box.go @@ -0,0 +1,55 @@ +package http + +import ( + "github.com/GeertJohan/go.rice/embedded" + "time" +) + +func init() { + + // define files + file2 := &embedded.EmbeddedFile{ + Filename: `admin.css`, + FileModTime: time.Unix(1489250860, 0), + Content: string("/* CUSTOM CSS */\ndiv.admin.login {\n border: 1px solid black;\n width: 500px;\n margin: auto;\n margin-top: 100px;\n}\n.admin.form.row {\n margin: auto;\n padding: 5px;\n width: 90%;\n height: 22px;\n left: 0;\n right: 0;\n display: flex;\n}\n.admin.form.input {\n font-family: \"monospace\";\n width: 100%;\n height: 100%;\n padding: 2px;\n display: inline;\n}\n.admin.form.input.halfsize {\n width: 50%;\n}"), + } + file3 := &embedded.EmbeddedFile{ + Filename: `custom.css`, + FileModTime: time.Unix(1489426703, 0), + Content: string("h1 {\n font-size: 32px;\n}\n\nh2 {\n font-size: 24px;\n}\n\nh3 {\n font-size: 16px;\n}\n\ndiv {\n display: block;\n margin: 0;\n padding: 0;\n}\n\nblockquote blockquote {\n word-wrap: break-word;\n word-break: break-all;\n white-space: normal;\n padding: 2px;\n margin-bottom: 1em;\n margin-top: 1em;\n margin-left: 40px;\n margin-right: 40px;\n}\n\n\n.delform {\n display: inline;\n margin: 0;\n padding: 0;\n}\n.delform input {\n display: inline;\n}\n\n.deleted {\n color: #707070;\n}\n\n.reply-table {\n display: block;\n}\n\n.reply {\n display: table;\n}"), + } + file4 := &embedded.EmbeddedFile{ + Filename: `style.css`, + FileModTime: time.Unix(1489426859, 0), + Content: string("/* The following CSS is mostly taken from Wakaba, big thanks for the devs there! <3 */\n\nhtml, body {\n background:#FFFFEE;\n color:#800000;\n}\na {\n color:#0000EE;\n}\na:hover {\n color:#DD0000;\n}\n.adminbar {\n text-align:right;\n clear:both;\n float:right;\n}\n.logo {\n clear:both;\n text-align:center;\n font-size:2em;\n color:#800000;\n width:100%;\n}\n.theader {\n background:#E04000;\n text-align:center;\n padding:2px;\n color:#FFFFFF;\n width:100%;\n}\n.postarea {\n}\n.rules {\n font-size:0.7em;\n}\n.postblock {\n background:#EEAA88;\n color:#800000;\n font-weight:800;\n}\n.footer {\n text-align:center;\n font-size:12px;\n font-family:serif;\n}\n.passvalid {\n background:#EEAA88;\n text-align:center;\n width:100%;\n color:#ffffff;\n}\n.dellist {\n font-weight: bold;\n text-align:center;\n}\n.delbuttons {\n text-align:center;\n padding-bottom:4px;\n\n}\n.managehead {\n background:#AAAA66;\n color:#400000;\n padding:0px;\n}\n.postlists {\n background:#FFFFFF;\n width:100%;\n padding:0px;\n color:#800000;\n}\n.row1 {\n background:#EEEECC;\n color:#800000;\n}\n.row2 {\n background:#DDDDAA;\n color:#800000;\n}\n.unkfunc {\n background:inert;\n color:#789922;\n}\n.filesize {\n text-decoration:none;\n}\n.filetitle {\n background:inherit;\n font-size:1.2em;\n color:#CC1105;\n font-weight:800;\n}\n.postername {\n color:#117743;\n font-weight:bold;\n}\n.postertrip {\n color:#228854;\n}\n.oldpost {\n color:#CC1105;\n font-weight:800;\n}\n.omittedposts {\n color:#707070;\n}\n.reply {\n background:#F0E0D6;\n color:#800000;\n}\n.doubledash {\n vertical-align:top;\n clear:both;\n float:left;\n}\n.replytitle {\n font-size: 1.2em;\n color:#CC1105;\n font-weight:800;\n}\n.commentpostername {\n color:#117743;\n font-weight:800;\n}\n.thumbnailmsg {\n font-size: small;\n color:#800000;\n}\n\n\n\n.abbrev {\n color:#707070;\n}\n.highlight {\n background:#F0E0D6;\n color:#800000;\n border: 2px dashed #EEAA88;\n}\n\n/* From pl files */\n\n/* futaba_style.pl */\n\nform { margin-bottom: 0px }\nform .trap { display:none }\n.postarea { text-align: center }\n.postarea table { margin: 0px auto; text-align: left }\n.thumb { border: none; float: left; margin: 2px 20px }\n.nothumb { float: left; background: #eee; border: 2px dashed #aaa; text-align: center; margin: 2px 20px; padding: 1em 0.5em 1em 0.5em; }\n\n.reflink a { color: inherit; text-decoration: none }\n.reply .filesize { margin-left: 20px }\n.userdelete { float: right; text-align: center; white-space: nowrap }\n.replypage .replylink { display: none }"), + } + + // define dirs + dir1 := &embedded.EmbeddedDir{ + Filename: ``, + DirModTime: time.Unix(1489426859, 0), + ChildFiles: []*embedded.EmbeddedFile{ + file2, // admin.css + file3, // custom.css + file4, // style.css + + }, + } + + // link ChildDirs + dir1.ChildDirs = []*embedded.EmbeddedDir{} + + // register embeddedBox + embedded.RegisterEmbeddedBox(`res/`, &embedded.EmbeddedBox{ + Name: `res/`, + Time: time.Unix(1489426859, 0), + Dirs: map[string]*embedded.EmbeddedDir{ + "": dir1, + }, + Files: map[string]*embedded.EmbeddedFile{ + "admin.css": file2, + "custom.css": file3, + "style.css": file4, + }, + }) +} diff --git a/http/server.go b/http/server.go index 37f1888..4cc3d32 100644 --- a/http/server.go +++ b/http/server.go @@ -8,6 +8,7 @@ import ( "go.rls.moe/nyx/config" "go.rls.moe/nyx/http/admin" "go.rls.moe/nyx/http/board" + "go.rls.moe/nyx/http/errw" "go.rls.moe/nyx/http/middle" "net/http" "time" @@ -21,7 +22,20 @@ var riceConf = rice.Config{ }, } -func Start(config *config.Config) { +func Start(config *config.Config) error { + err := admin.LoadTemplates() + if err != nil { + return err + } + err = board.LoadTemplates() + if err != nil { + return err + } + err = errw.LoadTemplates() + if err != nil { + return err + } + r := chi.NewRouter() fmt.Println("Setting up Router") @@ -37,7 +51,7 @@ func Start(config *config.Config) { { mw, err := middle.Database(config) if err != nil { - panic(err) + return err } r.Use(mw) } @@ -45,7 +59,10 @@ func Start(config *config.Config) { r.Route("/admin/", admin.AdminRouter) r.Route("/mod/", admin.ModRouter) { - box := riceConf.MustFindBox("http/res") + box, err := rice.FindBox("res/") + if err != nil { + return err + } atFileServer := http.StripPrefix("/@/", http.FileServer(box.HTTPBox())) r.Mount("/@/", atFileServer) }