From 75197310bf468452c33234a56274083da08317bf Mon Sep 17 00:00:00 2001 From: Wim Brand Date: Sun, 17 Jun 2018 16:15:58 +0200 Subject: [PATCH] refactoring. remove global state, use new logging, config functions --- conf/config.go | 101 ----------------------------- init/conf/config.go | 17 +++++ init/init.go | 37 +++++------ log/log.go | 97 --------------------------- main.go | 2 +- pixelapi/file.go | 11 ++-- pixelapi/list.go | 6 +- pixelapi/pixelapi.go | 9 +++ res/template/home.html | 41 ++++++------ webcontroller/apidoc.go | 18 ----- webcontroller/favicon.go | 14 ---- webcontroller/filePreview.go | 48 +++++++++++--- webcontroller/fileViewer.go | 36 +++++++--- webcontroller/fileViewerDemo.go | 52 --------------- webcontroller/history.go | 17 ----- webcontroller/home.go | 14 ---- webcontroller/listViewer.go | 12 ++-- webcontroller/notfound.go | 13 ---- webcontroller/paste.go | 14 ---- webcontroller/style.go | 2 +- webcontroller/templates/funcs.go | 22 +++---- webcontroller/templates/manager.go | 61 +++++++++++++++++ webcontroller/templates/parse.go | 46 ------------- webcontroller/webcontroller.go | 81 +++++++++++++++++++++++ 24 files changed, 295 insertions(+), 476 deletions(-) delete mode 100644 conf/config.go create mode 100644 init/conf/config.go delete mode 100644 log/log.go create mode 100644 pixelapi/pixelapi.go delete mode 100644 webcontroller/apidoc.go delete mode 100644 webcontroller/favicon.go delete mode 100644 webcontroller/fileViewerDemo.go delete mode 100644 webcontroller/history.go delete mode 100644 webcontroller/home.go delete mode 100644 webcontroller/notfound.go delete mode 100644 webcontroller/paste.go create mode 100644 webcontroller/templates/manager.go delete mode 100644 webcontroller/templates/parse.go create mode 100644 webcontroller/webcontroller.go 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.

Funding

@@ -149,14 +149,13 @@

Missing

- Features which are in + Features which are in https://pixeldrain.com, but not in https://sia.pixeldrain.com. These will be added soon enough.