diff --git a/conf/config.go b/conf/config.go
deleted file mode 100644
index 5cf9336..0000000
--- a/conf/config.go
+++ /dev/null
@@ -1,101 +0,0 @@
-package conf
-
-import (
- "os"
- "sort"
-
- "fornaxian.com/pixeldrain-web/log"
- "github.com/spf13/viper"
-)
-
-var vi *viper.Viper
-
-var defaultConfig = `# Pixeldrain Web UI server configuration
-api_url_external = "https://sia.pixeldrain.com/api" # Used in the web browser, should be a full URL. Not ending with a slash
-api_url_internal = "http://127.0.0.1:8080/api" # Used for internal API requests to the pixeldrain server, not visible to users
-static_resource_dir = "res/static"
-template_dir = "res/template"
-debug_mode = false`
-
-// Init reads the config file
-func Init() {
- if vi != nil {
- log.Error("Config already initialized, can't ititialize again")
- return
- }
-
- vi = viper.New()
- vi.SetConfigType("toml")
- vi.SetConfigName("pdwebconf")
-
- vi.AddConfigPath(".")
- vi.AddConfigPath("./conf")
- vi.AddConfigPath("/etc")
- vi.AddConfigPath("/usr/local/etc")
-
- vi.SetDefault("api_url_external", "/api")
- vi.SetDefault("api_url_internal", "http://127.0.0.1:8080/api")
- vi.SetDefault("static_resource_dir", "./res/static")
- vi.SetDefault("template_dir", "./res/template")
- vi.SetDefault("debug_mode", false)
-
- err := vi.ReadInConfig()
-
- if err != nil {
- if _, ok := err.(viper.ConfigFileNotFoundError); ok {
- writeCfg()
- log.Warn("Generated config file \"pdwebconf.toml\", please edit and run again.")
- os.Exit(0)
- } else if _, ok := err.(viper.ConfigParseError); ok {
- log.Error("Could not parse config file: ", err)
- } else {
- log.Error("Unknown error occured while reading config file: ", err)
- }
- }
-
- log.Info("Web UI configuration:")
- keys := vi.AllKeys()
- numKeys := len(keys)
- sort.Strings(keys)
- for i, v := range keys {
- if i == numKeys-1 {
- log.Info("└%21s: %v", v, vi.Get(v))
- } else {
- log.Info("├%21s: %v", v, vi.Get(v))
- }
- }
-
- if DebugMode() {
- log.SetLogLevel(4)
- } else {
- log.SetLogLevel(3)
- }
-}
-
-func writeCfg() {
- file, err := os.Create("pdwebconf.toml")
-
- if err != nil {
- log.Error("Could not create config file: ", err)
- }
-
- file.WriteString(defaultConfig)
-
- file.Close()
-}
-
-func ApiUrlExternal() string {
- return vi.GetString("api_url_external")
-}
-func ApiUrlInternal() string {
- return vi.GetString("api_url_internal")
-}
-func StaticResourceDir() string {
- return vi.GetString("static_resource_dir")
-}
-func TemplateDir() string {
- return vi.GetString("template_dir")
-}
-func DebugMode() bool {
- return vi.GetBool("debug_mode")
-}
diff --git a/init/conf/config.go b/init/conf/config.go
new file mode 100644
index 0000000..d0491a2
--- /dev/null
+++ b/init/conf/config.go
@@ -0,0 +1,17 @@
+package conf
+
+type PixelWebConfig struct {
+ APIURLExternal string `toml:"api_url_external"`
+ APIURLInternal string `toml:"api_url_internal"`
+ StaticResourceDir string `toml:"static_resource_dir"`
+ TemplateDir string `toml:"template_dir"`
+ DebugMode bool `toml:"debug_mode"`
+}
+
+const DefaultConfig = `# Pixeldrain Web UI server configuration
+
+api_url_external = "https://sia.pixeldrain.com/api" # Used in the web browser, should be a full URL. Not ending with a slash
+api_url_internal = "http://127.0.0.1:8080/api" # Used for internal API requests to the pixeldrain server, not visible to users
+static_resource_dir = "res/static"
+template_dir = "res/template"
+debug_mode = false`
diff --git a/init/init.go b/init/init.go
index 7cb5cd5..22391ef 100644
--- a/init/init.go
+++ b/init/init.go
@@ -1,36 +1,31 @@
package init
import (
- "net/http"
"os"
- "fornaxian.com/pixeldrain-web/conf"
- "fornaxian.com/pixeldrain-web/log"
+ "fornaxian.com/pixeldrain-web/init/conf"
"fornaxian.com/pixeldrain-web/webcontroller"
- "fornaxian.com/pixeldrain-web/webcontroller/templates"
+ "github.com/Fornaxian/config"
+ "github.com/Fornaxian/log"
"github.com/julienschmidt/httprouter"
)
// Init initializes the Pixeldrain Web UI controllers
func Init(r *httprouter.Router, prefix string) {
- log.Init()
log.Info("Starting web UI server (PID %v)", os.Getpid())
- conf.Init()
- templates.ParseTemplates()
+ var webconf = &conf.PixelWebConfig{}
+ var _, err = config.New(
+ conf.DefaultConfig,
+ "",
+ "pdwebconf.toml",
+ webconf,
+ true,
+ )
+ if err != nil {
+ log.Error("Failed to load config file: %s", err)
+ os.Exit(1)
+ }
- // Serve static files
- r.ServeFiles(prefix+"/res/*filepath", http.Dir(conf.StaticResourceDir()+"/res"))
-
- r.GET(prefix+"/", webcontroller.ServeHome)
- r.GET(prefix+"/favicon.ico", webcontroller.ServeFavicon)
- r.GET(prefix+"/global.css", webcontroller.GlobalCSSHandler)
- r.GET(prefix+"/api", webcontroller.ServeAPIDoc)
- r.GET(prefix+"/history", webcontroller.ServeHistory)
- r.GET(prefix+"/u/:id", webcontroller.ServeFileViewer)
- r.GET(prefix+"/u/:id/preview", webcontroller.ServeFilePreview)
- r.GET(prefix+"/l/:id", webcontroller.ServeListViewer)
- r.GET(prefix+"/t", webcontroller.ServePaste)
-
- r.NotFound = http.HandlerFunc(webcontroller.ServeNotFound)
+ webcontroller.New(r, prefix, webconf)
}
diff --git a/log/log.go b/log/log.go
deleted file mode 100644
index 238c7ab..0000000
--- a/log/log.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package log
-
-import (
- "fmt"
- "log"
- "os"
- "runtime"
- "runtime/debug"
-)
-
-var logger *log.Logger
-
-const (
- LEVEL_DEBUG = 4
- LEVEL_INFO = 3
- LEVEL_WARNING = 2
- LEVEL_ERROR = 1
-)
-
-var logLevel = LEVEL_DEBUG
-
-// Init initializes the logger
-func Init() {
- logger = log.New(os.Stdout, "pdweb ", log.LUTC)
-}
-
-// SetLogLevel set the loggin verbosity. 0 is lowest (log nothing at all), 4 is
-// highest (log all debug messages)
-func SetLogLevel(level int) {
- if level < 0 || level > 4 {
- Error("Invalid log level %v", level)
- return
- }
- logLevel = level
-}
-
-// Debug logs a debug message
-func Debug(msgFmt string, v ...interface{}) {
- if logLevel < LEVEL_DEBUG {
- return
- }
- if len(v) == 0 {
- print("DBG", msgFmt)
- } else {
- print("DBG", msgFmt, v...)
- }
-}
-
-// Info logs an info message
-func Info(msgFmt string, v ...interface{}) {
- if logLevel < LEVEL_INFO {
- return
- }
- if len(v) == 0 {
- print("INF", msgFmt)
- } else {
- print("INF", msgFmt, v...)
- }
-}
-
-// Warn logs a warning message
-func Warn(msgFmt string, v ...interface{}) {
- if logLevel < LEVEL_WARNING {
- return
- }
- if len(v) == 0 {
- print("WRN", msgFmt)
- } else {
- print("WRN", msgFmt, v...)
- }
-}
-
-// Error logs an error message
-func Error(msgFmt string, v ...interface{}) {
- if logLevel < LEVEL_ERROR {
- return
- }
- if len(v) == 0 {
- print("ERR", msgFmt)
- } else {
- print("ERR", msgFmt, v...)
- }
-
- debug.PrintStack()
-}
-
-func print(lvl string, msgFmt string, v ...interface{}) {
- _, fn, line, _ := runtime.Caller(2)
-
- msg := fmt.Sprintf("[%s] …%s:%-3d %s", lvl, string(fn[len(fn)-20:]), line, msgFmt)
-
- if len(v) == 0 {
- logger.Println(msg)
- } else {
- logger.Printf(msg, v...)
- }
-}
diff --git a/main.go b/main.go
index 0951db8..34c1191 100644
--- a/main.go
+++ b/main.go
@@ -4,8 +4,8 @@ import (
"net/http"
web "fornaxian.com/pixeldrain-web/init"
- "fornaxian.com/pixeldrain-web/log"
+ "github.com/Fornaxian/log"
"github.com/julienschmidt/httprouter"
)
diff --git a/pixelapi/file.go b/pixelapi/file.go
index be92be5..554a13a 100644
--- a/pixelapi/file.go
+++ b/pixelapi/file.go
@@ -4,14 +4,13 @@ import (
"encoding/json"
"io"
- "fornaxian.com/pixeldrain-web/conf"
- "fornaxian.com/pixeldrain-web/log"
+ "github.com/Fornaxian/log"
)
// GetFile makes a file download request and returns a readcloser. Don't forget
// to close it!
-func GetFile(id string) (io.ReadCloser, error) {
- return getRaw(conf.ApiUrlInternal() + "/file/" + id)
+func (p *PixelAPI) GetFile(id string) (io.ReadCloser, error) {
+ return getRaw(p.apiEndpoint + "/file/" + id)
}
// FileInfo File information object from the pixeldrain API
@@ -30,8 +29,8 @@ type FileInfo struct {
}
// GetFileInfo gets the FileInfo from the pixeldrain API
-func GetFileInfo(id string) *FileInfo {
- body, err := getString(conf.ApiUrlInternal() + "/file/" + id + "/info")
+func (p *PixelAPI) GetFileInfo(id string) *FileInfo {
+ body, err := getString(p.apiEndpoint + "/file/" + id + "/info")
if err != nil {
log.Error("req failed: %v", err)
diff --git a/pixelapi/list.go b/pixelapi/list.go
index c1bc715..c658182 100644
--- a/pixelapi/list.go
+++ b/pixelapi/list.go
@@ -2,8 +2,6 @@ package pixelapi
import (
"encoding/json"
-
- "fornaxian.com/pixeldrain-web/conf"
)
// API error constants
@@ -34,9 +32,9 @@ type ListFile struct {
// GetList get a List from the pixeldrain API. Errors will be available through
// List.Error. Standard error checks apply.
-func GetList(id string) *List {
+func (p *PixelAPI) GetList(id string) *List {
var list = &List{}
- body, err := getString(conf.ApiUrlInternal() + "/list/" + id)
+ body, err := getString(p.apiEndpoint + "/list/" + id)
if err != nil {
list.Error = errorResponseFromError(err)
return list
diff --git a/pixelapi/pixelapi.go b/pixelapi/pixelapi.go
new file mode 100644
index 0000000..cc659a8
--- /dev/null
+++ b/pixelapi/pixelapi.go
@@ -0,0 +1,9 @@
+package pixelapi
+
+type PixelAPI struct {
+ apiEndpoint string
+}
+
+func New(apiEndpoint string) *PixelAPI {
+ return &PixelAPI{apiEndpoint}
+}
diff --git a/res/template/home.html b/res/template/home.html
index 2e9942e..c5e7026 100644
--- a/res/template/home.html
+++ b/res/template/home.html
@@ -13,13 +13,13 @@
-
+
{{template "bgpattern"}}
-
@@ -40,7 +40,7 @@
-
+
@@ -49,24 +49,24 @@
Pixeldrain Public Beta
- Note that this is an experimental version of Pixeldrain server,
- the Pixeldrain backend has been completely redesigned from the
- ground up to be more extensible, efficient and scalable. The
- server this web application runs on is considered a testing
+ Note that this is an experimental version of Pixeldrain server,
+ the Pixeldrain backend has been completely redesigned from the
+ ground up to be more extensible, efficient and scalable. The
+ server this web application runs on is considered a testing
environment. Database resets can happen when architectural
changes need to be applied.
- The Sia integration is still very experimental and could
+ The Sia integration is still very experimental and could
fail, resulting in data loss. Do not upload files to this server
- that you cannot afford to lose. Use the stable main server instead:
+ that you cannot afford to lose. Use the stable main server instead:
https://pixeldrain.com.
- But don't let all that stop you from trying the new Pixeldrain!
- The upload restrictions that the main site has haven't been
- implemented in this version yet, so you can upload as much as
- you want. The server only has 256 GiB of space available, if it
+ But don't let all that stop you from trying the new Pixeldrain!
+ The upload restrictions that the main site has haven't been
+ implemented in this version yet, so you can upload as much as
+ you want. The server only has 256 GiB of space available, if it
starts running out of space files will be purged from the local
filesystem and served from Sia on the next request.
@@ -105,16 +105,16 @@
Legality
- I cannot be held liable for any illegal and / or copyrighted
+ I cannot be held liable for any illegal and / or copyrighted
material that's uploaded by the users of this application.
- Files uploaded to this website are subjected to local laws. If
- laws are being broken, and I've been notified of the fact I'll
- have to delete the offending content (as the server does not
+ Files uploaded to this website are subjected to local laws. If
+ laws are being broken, and I've been notified of the fact I'll
+ have to delete the offending content (as the server does not
support geo filtering yet). If you find any files on this domain
that break the law, please contact me at
abuse@pixeldrain.com,
and I'll take care of it.
- Please share responsibly.
+ Please share responsibly.
Text file viewer (yes, you can upload text but not view it yet)
Some video formats (mime type detection is not complete)
Registration / Login system
Bandwidth Tracker
diff --git a/webcontroller/apidoc.go b/webcontroller/apidoc.go
deleted file mode 100644
index 4d5c598..0000000
--- a/webcontroller/apidoc.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package webcontroller
-
-import (
- "net/http"
-
- "fornaxian.com/pixeldrain-web/log"
- "fornaxian.com/pixeldrain-web/webcontroller/templates"
-
- "github.com/julienschmidt/httprouter"
-)
-
-// ServeAPIDoc serves the API docuementation
-func ServeAPIDoc(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
- err := templates.Get().ExecuteTemplate(w, "apidoc", nil)
- if err != nil {
- log.Error("Error executing template apidoc: %s", err)
- }
-}
diff --git a/webcontroller/favicon.go b/webcontroller/favicon.go
deleted file mode 100644
index a6ff59f..0000000
--- a/webcontroller/favicon.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package webcontroller
-
-import (
- "net/http"
-
- "github.com/julienschmidt/httprouter"
-
- "fornaxian.com/pixeldrain-web/conf"
-)
-
-// ServeFavicon yes we need a controller for this
-func ServeFavicon(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
- http.ServeFile(w, r, conf.StaticResourceDir()+"favicon.ico")
-}
diff --git a/webcontroller/filePreview.go b/webcontroller/filePreview.go
index 8bd5067..da3fe1e 100644
--- a/webcontroller/filePreview.go
+++ b/webcontroller/filePreview.go
@@ -10,7 +10,6 @@ import (
"path/filepath"
"strings"
- "fornaxian.com/pixeldrain-web/conf"
"fornaxian.com/pixeldrain-web/pixelapi"
"github.com/Fornaxian/log"
@@ -19,19 +18,22 @@ import (
)
// ServeFilePreview controller for GET /u/:id/preview
-func ServeFilePreview(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
+func (wc *WebController) serveFilePreview(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
if p.ByName("id") == "demo" {
- ServeFilePreviewDemo(w) // Required for a-ads.com quality check
+ serveFilePreviewDemo(w) // Required for a-ads.com quality check
return
}
- inf := pixelapi.GetFileInfo(p.ByName("id")) // TODO: Error handling
+ inf := wc.api.GetFileInfo(p.ByName("id")) // TODO: Error handling
if inf == nil {
- ServeNotFound(w, r)
+ wc.serveNotFound(w, r)
return
}
- var fp FilePreview
+ var fp = FilePreview{
+ APIURL: wc.conf.APIURLExternal,
+ PixelAPI: wc.api,
+ }
io.WriteString(w, fp.Run(inf))
}
@@ -39,12 +41,15 @@ type FilePreview struct {
FileInfo *pixelapi.FileInfo
FileURL string
DownloadURL string
+
+ APIURL string
+ PixelAPI *pixelapi.PixelAPI
}
func (f FilePreview) Run(inf *pixelapi.FileInfo) string {
f.FileInfo = inf
- f.FileURL = conf.ApiUrlExternal() + "/file/" + f.FileInfo.ID
- f.DownloadURL = conf.ApiUrlExternal() + "/file/" + f.FileInfo.ID + "/download"
+ f.FileURL = f.APIURL + "/file/" + f.FileInfo.ID
+ f.DownloadURL = f.APIURL + "/file/" + f.FileInfo.ID + "/download"
if strings.HasPrefix(f.FileInfo.MimeType, "image") {
return f.image()
@@ -139,7 +144,7 @@ func (f FilePreview) text() string {
)
}
- body, err := pixelapi.GetFile(f.FileInfo.ID)
+ body, err := f.PixelAPI.GetFile(f.FileInfo.ID)
if err != nil {
log.Error("Can't download text file for preview: %s", err)
return fmt.Sprintf(htmlOut, "",
@@ -189,6 +194,29 @@ func (f FilePreview) def() string {
f.FileInfo.FileName,
f.FileInfo.MimeType,
f.DownloadURL,
- conf.ApiUrlExternal()+f.FileInfo.ThumbnailHREF,
+ f.APIURL+f.FileInfo.ThumbnailHREF,
)
}
+
+// ServeFilePreviewDemo serves the content of the demo file. It contains a nice
+// message to the human reviewers of the a-ads ad network so they can properly
+// categorize the website.
+func serveFilePreviewDemo(w http.ResponseWriter) {
+ io.WriteString(w,
+ `
+
+ , __ _
+/|/ \o | | | o
+ |___/ _ | | __| ,_ __, _ _
+ | | /\/ |/ |/ / | / | / | | / |/ |
+ | |_/ /\_/|__/|__/\_/|_/ |_/\_/|_/|_/ | |_/
+
+This is a demonstration of Pixeldrain's file viewer.
+
+The website automatically detects what kind of file you requested and prepares a page for viewing it properly. This is what a text file would look like on Pixeldrain. You can upload your own text file at pixeldrain.com/t.
+
+Pixeldrain is a free service for sharing files with large or small groups of people. For more information visit the home page by pressing the home button on the toolbar at the left side of the screen.
+
+Press the Details button or "i" for more info about Pixeldrain's file viewer.
+
`)
+}
diff --git a/webcontroller/fileViewer.go b/webcontroller/fileViewer.go
index 40a6071..cf9fcdb 100644
--- a/webcontroller/fileViewer.go
+++ b/webcontroller/fileViewer.go
@@ -5,16 +5,15 @@ import (
"net/http"
"strings"
- "fornaxian.com/pixeldrain-web/log"
"fornaxian.com/pixeldrain-web/pixelapi"
- "fornaxian.com/pixeldrain-web/webcontroller/templates"
+ "github.com/Fornaxian/log"
"github.com/julienschmidt/httprouter"
)
// ServeFileViewer controller for GET /u/:id
-func ServeFileViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
+func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
if p.ByName("id") == "demo" {
- ServeFileViewerDemo(w) // Required for a-ads.com quality check
+ wc.serveFileViewerDemo(w) // Required for a-ads.com quality check
return
}
@@ -29,7 +28,7 @@ func ServeFileViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params
var finfo []*pixelapi.FileInfo
for _, id := range ids {
- inf := pixelapi.GetFileInfo(id)
+ inf := wc.api.GetFileInfo(id)
if inf == nil {
continue
}
@@ -37,7 +36,7 @@ func ServeFileViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params
}
if len(finfo) == 0 {
- ServeNotFound(w, r)
+ wc.serveNotFound(w, r)
return
}
@@ -51,14 +50,14 @@ func ServeFileViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params
"date_lastview": "now",
"views": 0,
}
- err = templates.Get().ExecuteTemplate(w, "file_viewer", map[string]interface{}{
+ err = wc.templates.Get().ExecuteTemplate(w, "file_viewer", map[string]interface{}{
"Title": fmt.Sprintf("%d files in Pixeldrain", len(finfo)),
"APIResponse": listdata,
"Type": "list",
"OGData": ogData.FromFile(*finfo[0]),
})
} else {
- err = templates.Get().ExecuteTemplate(w, "file_viewer", map[string]interface{}{
+ err = wc.templates.Get().ExecuteTemplate(w, "file_viewer", map[string]interface{}{
"Title": fmt.Sprintf("%s ~ Pixeldrain file", finfo[0].FileName),
"APIResponse": finfo[0],
"Type": "file",
@@ -69,3 +68,24 @@ func ServeFileViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params
log.Error("Error executing template file_viewer: %s", err)
}
}
+
+// ServeFileViewerDemo is a dummy API response that responds with info about a
+// non-existent demo file. This is required by the a-ads ad network to allow for
+// automatic checking of the presence of the ad unit on this page.
+func (wc *WebController) serveFileViewerDemo(w http.ResponseWriter) {
+ wc.templates.Get().ExecuteTemplate(w, "file_viewer", map[string]interface{}{
+ "APIResponse": map[string]interface{}{
+ "id": "demo",
+ "file_name": "Demo file",
+ "date_upload": "2017-01-01 12:34:56",
+ "date_lastview": "2017-01-01 12:34:56",
+ "file_size": 123456789,
+ "views": 1,
+ "mime_type": "text/demo",
+ "description": "A file to demonstrate the viewer page",
+ "mime_image": "/res/img/mime/text.png",
+ "thumbnail": "/res/img/mime/text.png",
+ },
+ "Type": "file",
+ })
+}
diff --git a/webcontroller/fileViewerDemo.go b/webcontroller/fileViewerDemo.go
deleted file mode 100644
index d1869ab..0000000
--- a/webcontroller/fileViewerDemo.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package webcontroller
-
-import (
- "io"
- "net/http"
-
- "fornaxian.com/pixeldrain-web/webcontroller/templates"
-)
-
-// ServeFileViewerDemo is a dummy API response that responds with info about a
-// non-existent demo file. This is required by the a-ads ad network to allow for
-// automatic checking of the presence of the ad unit on this page.
-func ServeFileViewerDemo(w http.ResponseWriter) {
- templates.Get().ExecuteTemplate(w, "file_viewer", map[string]interface{}{
- "APIResponse": map[string]interface{}{
- "id": "demo",
- "file_name": "Demo file",
- "date_upload": "2017-01-01 12:34:56",
- "date_lastview": "2017-01-01 12:34:56",
- "file_size": 123456789,
- "views": 1,
- "mime_type": "text/demo",
- "description": "A file to demonstrate the viewer page",
- "mime_image": "/res/img/mime/text.png",
- "thumbnail": "/res/img/mime/text.png",
- },
- "Type": "file",
- })
-}
-
-// ServeFilePreviewDemo serves the content of the demo file. It contains a nice
-// message to the human reviewers of the a-ads ad network so they can properly
-// categorize the website.
-func ServeFilePreviewDemo(w http.ResponseWriter) {
- io.WriteString(w,
- `
-
- , __ _
-/|/ \o | | | o
- |___/ _ | | __| ,_ __, _ _
- | | /\/ |/ |/ / | / | / | | / |/ |
- | |_/ /\_/|__/|__/\_/|_/ |_/\_/|_/|_/ | |_/
-
-This is a demonstration of Pixeldrain's file viewer.
-
-The website automatically detects what kind of file you requested and prepares a page for viewing it properly. This is what a text file would look like on Pixeldrain. You can upload your own text file at pixeldrain.com/t.
-
-Pixeldrain is a free service for sharing files with large or small groups of people. For more information visit the home page by pressing the home button on the toolbar at the left side of the screen.
-
-Press the Details button or "i" for more info about Pixeldrain's file viewer.
-
`)
-}
diff --git a/webcontroller/history.go b/webcontroller/history.go
deleted file mode 100644
index c75b882..0000000
--- a/webcontroller/history.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package webcontroller
-
-import (
- "net/http"
-
- "fornaxian.com/pixeldrain-web/log"
- "fornaxian.com/pixeldrain-web/webcontroller/templates"
- "github.com/julienschmidt/httprouter"
-)
-
-// ServeHistory is the controller for the upload history viewer
-func ServeHistory(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
- err := templates.Get().ExecuteTemplate(w, "history-cookies", nil)
- if err != nil {
- log.Error("Error executing template history: %s", err)
- }
-}
diff --git a/webcontroller/home.go b/webcontroller/home.go
deleted file mode 100644
index dd9479b..0000000
--- a/webcontroller/home.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package webcontroller
-
-import (
- "net/http"
-
- "fornaxian.com/pixeldrain-web/webcontroller/templates"
-
- "github.com/julienschmidt/httprouter"
-)
-
-// ServeHome serves the home page
-func ServeHome(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
- templates.Get().ExecuteTemplate(w, "home", nil)
-}
diff --git a/webcontroller/listViewer.go b/webcontroller/listViewer.go
index db89f7d..c51ef95 100644
--- a/webcontroller/listViewer.go
+++ b/webcontroller/listViewer.go
@@ -4,20 +4,18 @@ import (
"fmt"
"net/http"
- "fornaxian.com/pixeldrain-web/log"
- "fornaxian.com/pixeldrain-web/pixelapi"
- "fornaxian.com/pixeldrain-web/webcontroller/templates"
+ "github.com/Fornaxian/log"
"github.com/julienschmidt/httprouter"
)
// ServeListViewer controller for GET /l/:id
-func ServeListViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
- var list = pixelapi.GetList(p.ByName("id"))
+func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
+ var list = wc.api.GetList(p.ByName("id"))
if list.Error != nil {
if list.Error.ReqError {
log.Error("API request error occurred: %s", list.Error.Value)
}
- ServeNotFound(w, r)
+ wc.serveNotFound(w, r)
return
}
@@ -30,7 +28,7 @@ func ServeListViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params
"title": list.Title,
"views": 0,
}
- err = templates.Get().ExecuteTemplate(w, "file_viewer", map[string]interface{}{
+ err = wc.templates.Get().ExecuteTemplate(w, "file_viewer", map[string]interface{}{
"Title": fmt.Sprintf("%s ~ Pixeldrain list", list.Title),
"APIResponse": listdata,
"Type": "list",
diff --git a/webcontroller/notfound.go b/webcontroller/notfound.go
deleted file mode 100644
index 9e7b8af..0000000
--- a/webcontroller/notfound.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package webcontroller
-
-import (
- "net/http"
-
- "fornaxian.com/pixeldrain-web/log"
- "fornaxian.com/pixeldrain-web/webcontroller/templates"
-)
-
-func ServeNotFound(w http.ResponseWriter, r *http.Request) {
- log.Debug("Not Found: %s", r.URL)
- templates.Get().ExecuteTemplate(w, "error", nil)
-}
diff --git a/webcontroller/paste.go b/webcontroller/paste.go
deleted file mode 100644
index 0a03bd6..0000000
--- a/webcontroller/paste.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package webcontroller
-
-import (
- "net/http"
-
- "fornaxian.com/pixeldrain-web/webcontroller/templates"
-
- "github.com/julienschmidt/httprouter"
-)
-
-// ServePaste serves the page that is used to upload plain text files
-func ServePaste(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
- templates.Get().ExecuteTemplate(w, "paste", nil)
-}
diff --git a/webcontroller/style.go b/webcontroller/style.go
index ae84820..3632911 100644
--- a/webcontroller/style.go
+++ b/webcontroller/style.go
@@ -8,7 +8,7 @@ import (
"github.com/julienschmidt/httprouter"
)
-func GlobalCSSHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
+func (wc *WebController) globalCSSHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
w.Header().Add("Content-Type", "text/css; charset=utf-8")
var textColor = "hsl(0, 0%, 75%)"
diff --git a/webcontroller/templates/funcs.go b/webcontroller/templates/funcs.go
index 814e374..62a432b 100644
--- a/webcontroller/templates/funcs.go
+++ b/webcontroller/templates/funcs.go
@@ -3,24 +3,24 @@ package templates
import (
"html/template"
"time"
-
- "fornaxian.com/pixeldrain-web/conf"
)
-var funcMap = template.FuncMap{
- "bgPatternCount": bgPatternCount,
- "debugMode": debugMode,
- "apiUrl": apiURL,
+func (tm *TemplateManager) funcMap() template.FuncMap {
+ return template.FuncMap{
+ "bgPatternCount": tm.bgPatternCount,
+ "debugMode": tm.debugMode,
+ "apiUrl": tm.apiURL,
+ }
}
-func bgPatternCount() uint8 {
+func (tm *TemplateManager) bgPatternCount() uint8 {
return uint8(time.Now().UnixNano() % 17)
}
-func debugMode() bool {
- return conf.DebugMode()
+func (tm *TemplateManager) debugMode() bool {
+ return tm.debugModeEnabled
}
-func apiURL() string {
- return conf.ApiUrlExternal()
+func (tm *TemplateManager) apiURL() string {
+ return tm.externalAPIEndpoint
}
diff --git a/webcontroller/templates/manager.go b/webcontroller/templates/manager.go
new file mode 100644
index 0000000..16a7596
--- /dev/null
+++ b/webcontroller/templates/manager.go
@@ -0,0 +1,61 @@
+package templates
+
+import (
+ "html/template"
+ "os"
+ "path/filepath"
+
+ "github.com/Fornaxian/log"
+)
+
+type TemplateManager struct {
+ templates *template.Template
+
+ // Config
+ templateDir string
+ externalAPIEndpoint string
+ debugModeEnabled bool
+}
+
+func New(templateDir, externalAPIEndpoint string, debugMode bool) *TemplateManager {
+ return &TemplateManager{
+ templateDir: templateDir,
+ externalAPIEndpoint: externalAPIEndpoint,
+ debugModeEnabled: debugMode,
+ }
+}
+
+// ParseTemplates parses the templates in the template directory which is
+// defined in the config file
+func (tm *TemplateManager) ParseTemplates() {
+ var templatePaths []string
+
+ filepath.Walk(tm.templateDir, func(path string, f os.FileInfo, err error) error {
+ if f.IsDir() {
+ return nil
+ }
+ templatePaths = append(templatePaths, path)
+ log.Info("Template found: %s", path)
+ return nil
+ })
+
+ tpl := template.New("")
+
+ // Import template functions from funcs.go
+ tpl = tpl.Funcs(tm.funcMap())
+
+ var err error
+ tpl, err = tpl.ParseFiles(templatePaths...)
+ if err != nil {
+ log.Error("Template parsing failed: %v", err)
+ }
+
+ // Swap out the old templates with the new templates, to minimize
+ // modifications to the original variable.
+ tm.templates = tpl
+}
+
+// Get returns the templates, so they can be used to render views
+func (tm *TemplateManager) Get() *template.Template {
+ return tm.templates
+}
diff --git a/webcontroller/templates/parse.go b/webcontroller/templates/parse.go
deleted file mode 100644
index 98c303a..0000000
--- a/webcontroller/templates/parse.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package templates
-
-import (
- "html/template"
- "os"
- "path/filepath"
-
- "fornaxian.com/pixeldrain-web/conf"
- "fornaxian.com/pixeldrain-web/log"
-)
-
-var templates *template.Template
-var templatePaths []string
-
-// ParseTemplates parses the templates in the template directory which is
-// defined in the config file
-func ParseTemplates() {
- filepath.Walk(conf.TemplateDir(), func(path string, f os.FileInfo, err error) error {
- if f.IsDir() {
- return nil
- }
- templatePaths = append(templatePaths, path)
- log.Info("Template found: %s", path)
- return nil
- })
-
- tpl := template.New("")
-
- // Import template functions from funcs.go
- tpl = tpl.Funcs(funcMap)
-
- var err error
- tpl, err = tpl.ParseFiles(templatePaths...)
- if err != nil {
- log.Error("Template parsing failed: %v", err)
- }
-
- // Swap out the old templates with the new templates, to minimize
- // modifications to the original variable.
- templates = tpl
-}
-
-// Get returns the templates, so they can be used to render views
-func Get() *template.Template {
- return templates
-}
diff --git a/webcontroller/webcontroller.go b/webcontroller/webcontroller.go
new file mode 100644
index 0000000..f3c380c
--- /dev/null
+++ b/webcontroller/webcontroller.go
@@ -0,0 +1,81 @@
+package webcontroller
+
+import (
+ "net/http"
+
+ "fornaxian.com/pixeldrain-web/init/conf"
+ "fornaxian.com/pixeldrain-web/pixelapi"
+ "fornaxian.com/pixeldrain-web/webcontroller/templates"
+ "github.com/Fornaxian/log"
+ "github.com/julienschmidt/httprouter"
+)
+
+type WebController struct {
+ conf *conf.PixelWebConfig
+ api *pixelapi.PixelAPI
+ templates *templates.TemplateManager
+ staticResourceDir string
+}
+
+func New(r *httprouter.Router, prefix string, conf *conf.PixelWebConfig) *WebController {
+ var wc = &WebController{
+ conf: conf,
+ staticResourceDir: conf.StaticResourceDir,
+ }
+ wc.api = pixelapi.New(conf.APIURLInternal)
+ wc.templates = templates.New(
+ conf.TemplateDir,
+ conf.APIURLExternal,
+ conf.DebugMode,
+ )
+ wc.templates.ParseTemplates()
+
+ // Serve static files
+ r.ServeFiles(prefix+"/res/*filepath", http.Dir(wc.staticResourceDir+"/res"))
+
+ r.GET(prefix+"/" /* */, wc.serveTemplate("home"))
+ r.GET(prefix+"/favicon.ico" /* */, wc.serveFile("/favicon.ico"))
+ r.GET(prefix+"/global.css" /* */, wc.globalCSSHandler)
+ r.GET(prefix+"/api" /* */, wc.serveTemplate("apidoc"))
+ r.GET(prefix+"/history" /* */, wc.serveTemplate("history-cookies"))
+ r.GET(prefix+"/u/:id" /* */, wc.serveFileViewer)
+ r.GET(prefix+"/u/:id/preview" /**/, wc.serveFilePreview)
+ r.GET(prefix+"/l/:id" /* */, wc.serveListViewer)
+ r.GET(prefix+"/t" /* */, wc.serveTemplate("paste"))
+
+ r.NotFound = http.HandlerFunc(wc.serveNotFound)
+
+ return wc
+}
+
+func (wc *WebController) ReloadTemplates() {
+ wc.templates.ParseTemplates()
+}
+
+func (wc *WebController) serveTemplate(tpl string) httprouter.Handle {
+ return func(
+ w http.ResponseWriter,
+ r *http.Request,
+ p httprouter.Params,
+ ) {
+ err := wc.templates.Get().ExecuteTemplate(w, tpl, nil)
+ if err != nil {
+ log.Error("Error executing template '%s': %s", tpl, err)
+ }
+ }
+}
+
+func (wc *WebController) serveFile(path string) httprouter.Handle {
+ return func(
+ w http.ResponseWriter,
+ r *http.Request,
+ p httprouter.Params,
+ ) {
+ http.ServeFile(w, r, wc.staticResourceDir+"/favicon.ico")
+ }
+}
+
+func (wc *WebController) serveNotFound(w http.ResponseWriter, r *http.Request) {
+ log.Debug("Not Found: %s", r.URL)
+ wc.templates.Get().ExecuteTemplate(w, "error", nil)
+}