add login/register forms. Restructure pixelapi

This commit is contained in:
2018-06-20 23:47:47 +02:00
parent 75197310bf
commit ffa9fb3395
18 changed files with 292 additions and 228 deletions

View File

@@ -1,10 +1,7 @@
package pixelapi package pixelapi
import ( import (
"encoding/json"
"io" "io"
"github.com/Fornaxian/log"
) )
// GetFile makes a file download request and returns a readcloser. Don't forget // GetFile makes a file download request and returns a readcloser. Don't forget
@@ -29,18 +26,11 @@ type FileInfo struct {
} }
// GetFileInfo gets the FileInfo from the pixeldrain API // GetFileInfo gets the FileInfo from the pixeldrain API
func (p *PixelAPI) GetFileInfo(id string) *FileInfo { func (p *PixelAPI) GetFileInfo(id string) (resp *FileInfo, err *Error) {
body, err := getString(p.apiEndpoint + "/file/" + id + "/info") resp = &FileInfo{}
err = getJSON(p.apiEndpoint+"/file/"+id+"/info", resp)
if err != nil { if err != nil {
log.Error("req failed: %v", err) return nil, err
return nil
} }
var fileInfo FileInfo return resp, nil
err = json.Unmarshal([]byte(body), &fileInfo)
if err != nil {
log.Error("unmarshal failed: %v. json: %s", err, body)
return nil
}
return &fileInfo
} }

View File

@@ -1,9 +1,5 @@
package pixelapi package pixelapi
import (
"encoding/json"
)
// API error constants // API error constants
const ( const (
ListNotFoundError = "list_not_found" ListNotFoundError = "list_not_found"
@@ -11,7 +7,6 @@ const (
// List information object from the pixeldrain API // List information object from the pixeldrain API
type List struct { type List struct {
Error *ErrorResponse
Success bool `json:"success"` Success bool `json:"success"`
ID string `json:"id"` ID string `json:"id"`
Title string `json:"title"` Title string `json:"title"`
@@ -32,22 +27,11 @@ type ListFile struct {
// GetList get a List from the pixeldrain API. Errors will be available through // GetList get a List from the pixeldrain API. Errors will be available through
// List.Error. Standard error checks apply. // List.Error. Standard error checks apply.
func (p *PixelAPI) GetList(id string) *List { func (p *PixelAPI) GetList(id string) (resp *List, err *Error) {
var list = &List{} resp = &List{}
body, err := getString(p.apiEndpoint + "/list/" + id) err = getJSON(p.apiEndpoint+"/list/"+id, resp)
if err != nil { if err != nil {
list.Error = errorResponseFromError(err) return nil, err
return list
} }
return resp, nil
err = json.Unmarshal([]byte(body), list)
if err != nil {
list.Error = errorResponseFromError(err)
return list
}
if !list.Success {
list.Error = errorResponseFromJSON(body)
}
return list
} }

13
pixelapi/misc.go Normal file
View File

@@ -0,0 +1,13 @@
package pixelapi
type Recaptcha struct {
SiteKey string `json:"site_key"`
}
func (p *PixelAPI) GetRecaptcha() (resp *Recaptcha, err *Error) {
err = getJSON(p.apiEndpoint+"/misc/recpatcha", resp)
if err != nil {
return nil, err
}
return resp, nil
}

View File

@@ -1,9 +1,141 @@
package pixelapi package pixelapi
import (
"encoding/json"
"io"
"io/ioutil"
"net/http"
"github.com/Fornaxian/log"
)
// PixelAPI is the Pixeldrain API client
type PixelAPI struct { type PixelAPI struct {
apiEndpoint string apiEndpoint string
} }
// New creates a new Pixeldrain API client to query the Pixeldrain API with
func New(apiEndpoint string) *PixelAPI { func New(apiEndpoint string) *PixelAPI {
return &PixelAPI{apiEndpoint} return &PixelAPI{apiEndpoint}
} }
type Error struct {
ReqError bool
Success bool `json:"success"`
Value string `json:"value"`
Message string `json:"message"`
}
func (e Error) Error() string { return e.Value }
func errorResponseFromJSON(j string) *Error {
var r = &Error{}
var err = json.Unmarshal([]byte(j), r)
if err != nil {
r.Success = false
r.ReqError = true
r.Value = err.Error()
}
return r
}
func errorResponseFromError(e error) *Error {
var r = &Error{}
r.Success = false
r.ReqError = true
r.Value = e.Error()
return r
}
func getJSON(url string, target interface{}) *Error {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return &Error{
ReqError: true,
Success: false,
Value: err.Error(),
Message: err.Error(),
}
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return &Error{
ReqError: true,
Success: false,
Value: err.Error(),
Message: err.Error(),
}
}
defer resp.Body.Close()
var jdec = json.NewDecoder(resp.Body)
// Test for client side and server side errors
if resp.StatusCode >= 400 {
var errResp = &Error{
ReqError: false,
}
err = jdec.Decode(&errResp)
if err != nil {
log.Error("Can't decode this: %v", err)
return &Error{
ReqError: true,
Success: false,
Value: err.Error(),
Message: err.Error(),
}
}
return errResp
}
err = jdec.Decode(target)
if err != nil {
r, _ := ioutil.ReadAll(resp.Body)
log.Error("Can't decode this: %v. %s", err, r)
return &Error{
ReqError: true,
Success: false,
Value: err.Error(),
Message: err.Error(),
}
}
return nil
}
func getString(url string) (string, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return "", err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
return string(bodyBytes), err
}
func getRaw(url string) (io.ReadCloser, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
return resp.Body, err
}

View File

@@ -1,70 +0,0 @@
package pixelapi
import (
"encoding/json"
"io"
"io/ioutil"
"net/http"
)
type ErrorResponse struct {
ReqError bool
Success bool `json:"success"`
Value string `json:"value"`
Message *string `json:"message"`
ID *string `json:"id"`
}
func errorResponseFromJSON(j string) *ErrorResponse {
var r = &ErrorResponse{}
var err = json.Unmarshal([]byte(j), r)
if err != nil {
r.Success = false
r.ReqError = true
r.Value = err.Error()
}
return r
}
func errorResponseFromError(e error) *ErrorResponse {
var r = &ErrorResponse{}
r.Success = false
r.ReqError = true
r.Value = e.Error()
return r
}
func getString(url string) (string, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return "", err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
return string(bodyBytes), err
}
func getRaw(url string) (io.ReadCloser, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
return resp.Body, err
}

View File

@@ -123,8 +123,8 @@ html{
.highlight_middle {background-color: #3a3a3a;} .highlight_middle {background-color: #3a3a3a;}
.highlight_dark {background-color: #303030;} .highlight_dark {background-color: #303030;}
.border-top {border-top: #686868 1px solid;} .border_top {border-top: #686868 1px solid;}
.border-bottom {border-bottom: #686868 1px solid;} .border_bottom {border-bottom: #686868 1px solid;}
/* Common elements */ /* Common elements */
@@ -241,6 +241,10 @@ a:hover{
/* Form fields */ /* Form fields */
.form_input {
width: 100%;
}
/* BUTTONS */ /* BUTTONS */
button, button,
input[type="submit"], input[type="submit"],
@@ -281,10 +285,10 @@ select:active{
padding: 8px 8px 4px 12px; padding: 8px 8px 4px 12px;
} }
.button_full_width {width: calc(100% - 4px);} .button_full_width {width: calc(100% - 4px);}
.button_highlight {background: linear-gradient(var(--highlight_color), var(--highlight_color_dark));} .button_highlight {background: linear-gradient(var(--highlight_color), var(--highlight_color_dark)) !important; color: #000000 !important;}
.button_highlight:active{background: linear-gradient(var(--highlight_color_dark), var(--highlight_color));} .button_highlight:active{background: linear-gradient(var(--highlight_color_dark), var(--highlight_color)) !important; color: #000000 !important;}
.button_red {background: linear-gradient(#821C40, #61152F);} .button_red {background: linear-gradient(#821C40, #61152F) !important;}
.button_red:active {background: linear-gradient(#61152F, #821C40);} .button_red:active {background: linear-gradient(#61152F, #821C40) !important;}
/* Dropdown list of the select tag */ /* Dropdown list of the select tag */
option{ option{

View File

@@ -1,21 +1,19 @@
{{define "login"}}
<!DOCTYPE html> <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"> <html xmlns:th="http://www.thymeleaf.org">
<head> <head>
<title>Login ~ PixelDrain</title> <title>Login ~ PixelDrain</title>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/res/style/home.css"/> <link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/season.css"/> <link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/form.css"/>
<link rel="stylesheet" href="/res/style/menu.css"/>
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/> <link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/> <link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/>
<link rel="shortcut icon" href="/res/img/tray32.png"/> <link rel="shortcut icon" href="/res/img/tray32.png"/>
<meta name="theme-color" content="#9FCF6C"/> <meta name="theme-color" content="#9FCF6C"/>
<link rel="icon" sizes="180x180" href="/res/img/pixeldrain.png"/> <link rel="icon" sizes="180x180" href="/res/img/pixeldrain.png"/>
<link rel="icon" sizes="256x256" href="/res/img/pixeldrain_big.png"/> <link rel="icon" sizes="256x256" href="/res/img/pixeldrain_big.png"/>
{{template "bgpattern"}}
<style th:include="fragments :: background-pattern" th:inline="text"></style>
<meta name="description" content="PixelDrain is a free file sharing service, you <meta name="description" content="PixelDrain is a free file sharing service, you
can upload any file and you will be given a shareable link right away. can upload any file and you will be given a shareable link right away.
@@ -32,49 +30,30 @@
<body> <body>
<div id='body' class="body"> <div id='body' class="body">
<div th:replace="fragments :: menu"></div> {{template "menu"}}
<br/><br/>
<div id="message" th:switch="${messageType}"> <h1>Log in to your PixelDrain account</h1>
<div th:case="'info'" th:utext="${message}" id="text-info" class="text-info"></div> <form action="/login" method="POST" class="highlight_dark border_top border_bottom">
<div th:case="'warn'" th:utext="${message}" id="text-warning" class="text-warning"></div> <table style="margin-left: auto; margin-right: auto;">
</div>
Log in to your PixelDrain account
<form action="/login" method="POST">
<table>
<tr> <tr>
<td>Username</td> <td>Username</td>
<td><input name="username" type="text" value="" th:value="${form_username}"/></td> <td><input name="username" type="text" value=""/></td>
</tr> </tr>
<tr> <tr>
<td>Password</td> <td>Password</td>
<td><input name="password" type="password"/></td> <td><input name="password" type="password"/></td>
</tr> </tr>
<tr>
<td colspan=2 style="text-align: right;"><input type="submit" value="Login"/></td>
</tr>
</table> </table>
<input type="submit" value="Login"/>
</form> </form>
<br/><br/> <br/>
If you don't have a PixelDrain account, you can <a href="/register">register here</a>. If you don't have a PixelDrain account, you can <a href="/register">register here</a>. No e-mail address required.<br/>
{{template "footer"}}
</div> </div>
<!-- Google Analytics Tracking Code --> {{template "analytics"}}
<script>
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-24463738-4', 'auto');
ga('send', 'pageview');
</script>
</body> </body>
</html> </html>
{{end}}

View File

@@ -1,23 +1,19 @@
{{define "register"}}
<!DOCTYPE html> <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"> <html xmlns:th="http://www.thymeleaf.org">
<head> <head>
<title>Register ~ PixelDrain</title> <title>Register ~ PixelDrain</title>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/res/style/home.css"/> <link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/season.css"/> <link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/form.css"/>
<link rel="stylesheet" href="/res/style/menu.css"/>
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/> <link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/> <link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/>
<link rel="shortcut icon" href="/res/img/tray32.png"/> <link rel="shortcut icon" href="/res/img/tray32.png"/>
<meta name="theme-color" content="#9FCF6C"/> <meta name="theme-color" content="#9FCF6C"/>
<link rel="icon" sizes="180x180" href="/res/img/pixeldrain.png"/> <link rel="icon" sizes="180x180" href="/res/img/pixeldrain.png"/>
<link rel="icon" sizes="256x256" href="/res/img/pixeldrain_big.png"/> <link rel="icon" sizes="256x256" href="/res/img/pixeldrain_big.png"/>
{{template "bgpattern"}}
<style th:include="fragments :: background-pattern" th:inline="text"></style>
<script src='https://www.google.com/recaptcha/api.js'></script>
<meta name="description" content="PixelDrain is a free file sharing service, you <meta name="description" content="PixelDrain is a free file sharing service, you
can upload any file and you will be given a shareable link right away. can upload any file and you will be given a shareable link right away.
@@ -30,53 +26,39 @@
<meta property="og:url" content="http://pixeldra.in/" /> <meta property="og:url" content="http://pixeldra.in/" />
<meta property="og:image" content="/res/img/pixeldrain_big.png" /> <meta property="og:image" content="/res/img/pixeldrain_big.png" />
<meta property="og:image:type" content="image/png" /> <meta property="og:image:type" content="image/png" />
<script src="https://www.google.com/recaptcha/api.js"></script>
</head> </head>
<body> <body>
<div id='body' class="body"> <div id='body' class="body">
<div th:replace="fragments :: menu"></div> {{template "menu"}}
<br/>
<h3>Register a new PixelDrain account</h3> <h1>Register a new Pixeldrain account</h1>
<div id="message" th:switch="${messageType}"> <form action="/login" method="POST" class="highlight_dark border_top border_bottom">
<div th:case="'info'" th:utext="${message}" id="text-info" class="text-info"></div> <table style="margin-left: auto; margin-right: auto; text-align: left; max-width: 30em;">
<div th:case="'warn'" th:utext="${message}" id="text-warning" class="text-warning"></div> <tr><td>Username (Used to log in)</td></tr>
</div> <tr><td><input name="username" type="text" class="form_input"/></td></tr>
<form action="/register" method="POST"> <tr><td>
Enter your password twice:<br/>
(So we can verify that you have not made any typing errors)
Username (Used to log in)<br/> </td></tr>
<input name="username" type="text" th:value="${username}"/><br/> <tr><td><input name="password1" type="password" class="form_input"/></td></tr>
<br/> <tr><td><input name="password2" type="password" class="form_input"/></td></tr>
Enter your password twice (Why twice? So we can verify that you have not made any typing errors)<br/> <tr><td>Prove that you're not a robot (Click the white box)</td></tr>
<input name="password1" type="password" th:value="${password1}"/><br/> <tr><td style="text-align: center;">
<input name="password2" type="password" th:value="${password2}"/><br/> <div class="g-recaptcha" data-theme="dark" data-sitekey="6LdEeQ0TAAAAALBmDF_k_2LgbpuJM66PGspByViS"></div>
<br/> </td></tr>
Prove that you're not a robot (Click the white box) </tr>
<div class="g-recaptcha" data-theme="dark" <tr><td colspan=2 style="text-align: right;"><input type="submit" value="Register" class="button_highlight"/></td></tr>
data-sitekey="6LdEeQ0TAAAAALBmDF_k_2LgbpuJM66PGspByViS"> </table>
</div><br/>
<br/>
<input type="submit" value="Register"/>
</form> </form>
<br/>
Welcome to the club!<br/>
{{template "footer"}}
</div> </div>
<!-- Google Analytics Tracking Code --> {{template "analytics"}}
<script>
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-24463738-4', 'auto');
ga('send', 'pageview');
</script>
</body> </body>
</html> </html>
{{end}}

View File

@@ -1,6 +1,6 @@
{{define "footer"}} {{define "footer"}}
<br/> <br/>
<div class="highlight_dark border-top border-bottom"> <div class="highlight_dark border_top border_bottom">
Pixeldrain is a product by <a href="//fornaxian.com" target="_blank">Fornaxian Technologies</a>. Pixeldrain is a product by <a href="//fornaxian.com" target="_blank">Fornaxian Technologies</a>.
</div> </div>
{{end}} {{end}}

View File

@@ -1,8 +1,9 @@
{{define "menu"}} {{define "menu"}}
<div id="navigation" class="highlight_light border-top border-bottom navigation"> <div id="navigation" class="highlight_light border_top border_bottom navigation">
<a href="/">Home</a> <a href="/">Home</a>
<a href="/history">My&nbsp;Files</a> <a href="/history">My&nbsp;Files</a>
<a href="/api">API&nbsp;Documentation</a> <a href="/api">API&nbsp;Documentation</a>
<a href="/user">Account</a>
<a href="javascript:void(0);" class="icon" onclick="expandNavigation()">&#9776;</a> <a href="javascript:void(0);" class="icon" onclick="expandNavigation()">&#9776;</a>
<script> <script>
function expandNavigation() { function expandNavigation() {

View File

@@ -36,14 +36,14 @@
<br/> <br/>
<div id="body" class="body"> <div id="body" class="body">
{{template "menu"}} {{template "menu"}}
<div class="highlight_middle border-bottom"> <div class="highlight_middle border_bottom">
<input id="file_input_field" type="file" name="file" multiple="multiple"/> <input id="file_input_field" type="file" name="file" multiple="multiple"/>
<button id="select_file_button" class="big_button button_highlight">Upload Files</button> <button id="select_file_button" class="big_button button_highlight">Upload Files</button>
<button id="text_button" class="big_button button_highlight" onClick="window.location.href = '/t/'">Upload Text</button><br/> <button id="text_button" class="big_button button_highlight" onClick="window.location.href = '/t/'">Upload Text</button><br/>
<div id="uploads_queue" class="uploads_queue"></div> <div id="uploads_queue" class="uploads_queue"></div>
</div> </div>
<div class="highlight_dark border-bottom"> <div class="highlight_dark border_bottom">
<button id="btn_create_list">Create list with uploaded files</button> <button id="btn_create_list">Create list with uploaded files</button>
</div> </div>

View File

@@ -24,8 +24,8 @@ func (wc *WebController) serveFilePreview(w http.ResponseWriter, r *http.Request
return return
} }
inf := wc.api.GetFileInfo(p.ByName("id")) // TODO: Error handling inf, err := wc.api.GetFileInfo(p.ByName("id")) // TODO: Error handling
if inf == nil { if err != nil {
wc.serveNotFound(w, r) wc.serveNotFound(w, r)
return return
} }

View File

@@ -28,8 +28,8 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
var finfo []*pixelapi.FileInfo var finfo []*pixelapi.FileInfo
for _, id := range ids { for _, id := range ids {
inf := wc.api.GetFileInfo(id) inf, err := wc.api.GetFileInfo(id)
if inf == nil { if err != nil {
continue continue
} }
finfo = append(finfo, inf) finfo = append(finfo, inf)

View File

@@ -10,10 +10,10 @@ import (
// ServeListViewer controller for GET /l/:id // ServeListViewer controller for GET /l/:id
func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) { func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
var list = wc.api.GetList(p.ByName("id")) var list, aerr = wc.api.GetList(p.ByName("id"))
if list.Error != nil { if aerr != nil {
if list.Error.ReqError { if aerr.ReqError {
log.Error("API request error occurred: %s", list.Error.Value) log.Error("API request error occurred: %s", aerr.Value)
} }
wc.serveNotFound(w, r) wc.serveNotFound(w, r)
return return

View File

@@ -0,0 +1,25 @@
package webcontroller
import (
"net/http"
)
// TemplateData is a struct that every template expects when being rendered. In
// the field Other you can pass your own template-specific variables.
type TemplateData struct {
Authenticated bool
Username string
Recaptcha struct {
Enabled bool
PubKey string
}
Other interface{}
}
func (wc *WebController) newTemplateData(r http.Request) *TemplateData {
var t = &TemplateData{}
return t
}

View File

@@ -26,8 +26,9 @@ func New(templateDir, externalAPIEndpoint string, debugMode bool) *TemplateManag
} }
// ParseTemplates parses the templates in the template directory which is // ParseTemplates parses the templates in the template directory which is
// defined in the config file // defined in the config file.
func (tm *TemplateManager) ParseTemplates() { // If silent is false it will print an info log message for every template found
func (tm *TemplateManager) ParseTemplates(silent bool) {
var templatePaths []string var templatePaths []string
filepath.Walk(tm.templateDir, func(path string, f os.FileInfo, err error) error { filepath.Walk(tm.templateDir, func(path string, f os.FileInfo, err error) error {
@@ -35,7 +36,9 @@ func (tm *TemplateManager) ParseTemplates() {
return nil return nil
} }
templatePaths = append(templatePaths, path) templatePaths = append(templatePaths, path)
if !silent {
log.Info("Template found: %s", path) log.Info("Template found: %s", path)
}
return nil return nil
}) })
@@ -57,5 +60,8 @@ func (tm *TemplateManager) ParseTemplates() {
// Get returns the templates, so they can be used to render views // Get returns the templates, so they can be used to render views
func (tm *TemplateManager) Get() *template.Template { func (tm *TemplateManager) Get() *template.Template {
if tm.debugModeEnabled {
tm.ParseTemplates(true)
}
return tm.templates return tm.templates
} }

View File

@@ -0,0 +1,15 @@
package webcontroller
import (
"net/http"
"github.com/julienschmidt/httprouter"
)
func (wc *WebController) handleLogin(
w http.ResponseWriter,
r *http.Request,
p httprouter.Params,
) {
}

View File

@@ -28,7 +28,7 @@ func New(r *httprouter.Router, prefix string, conf *conf.PixelWebConfig) *WebCon
conf.APIURLExternal, conf.APIURLExternal,
conf.DebugMode, conf.DebugMode,
) )
wc.templates.ParseTemplates() wc.templates.ParseTemplates(false)
// Serve static files // Serve static files
r.ServeFiles(prefix+"/res/*filepath", http.Dir(wc.staticResourceDir+"/res")) r.ServeFiles(prefix+"/res/*filepath", http.Dir(wc.staticResourceDir+"/res"))
@@ -43,13 +43,16 @@ func New(r *httprouter.Router, prefix string, conf *conf.PixelWebConfig) *WebCon
r.GET(prefix+"/l/:id" /* */, wc.serveListViewer) r.GET(prefix+"/l/:id" /* */, wc.serveListViewer)
r.GET(prefix+"/t" /* */, wc.serveTemplate("paste")) r.GET(prefix+"/t" /* */, wc.serveTemplate("paste"))
r.GET(prefix+"/register" /* */, wc.serveTemplate("register"))
r.GET(prefix+"/login" /* */, wc.serveTemplate("login"))
r.NotFound = http.HandlerFunc(wc.serveNotFound) r.NotFound = http.HandlerFunc(wc.serveNotFound)
return wc return wc
} }
func (wc *WebController) ReloadTemplates() { func (wc *WebController) ReloadTemplates() {
wc.templates.ParseTemplates() wc.templates.ParseTemplates(false)
} }
func (wc *WebController) serveTemplate(tpl string) httprouter.Handle { func (wc *WebController) serveTemplate(tpl string) httprouter.Handle {