add login/register forms. Restructure pixelapi
This commit is contained in:
@@ -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
|
|
||||||
}
|
}
|
||||||
|
@@ -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
13
pixelapi/misc.go
Normal 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
|
||||||
|
}
|
@@ -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
|
||||||
|
}
|
||||||
|
@@ -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
|
|
||||||
}
|
|
@@ -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{
|
||||||
|
@@ -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}}
|
||||||
|
@@ -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}}
|
||||||
|
@@ -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}}
|
@@ -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 Files</a>
|
<a href="/history">My Files</a>
|
||||||
<a href="/api">API Documentation</a>
|
<a href="/api">API Documentation</a>
|
||||||
|
<a href="/user">Account</a>
|
||||||
<a href="javascript:void(0);" class="icon" onclick="expandNavigation()">☰</a>
|
<a href="javascript:void(0);" class="icon" onclick="expandNavigation()">☰</a>
|
||||||
<script>
|
<script>
|
||||||
function expandNavigation() {
|
function expandNavigation() {
|
||||||
|
@@ -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>
|
||||||
|
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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)
|
||||||
|
@@ -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
|
||||||
|
25
webcontroller/templateData.go
Normal file
25
webcontroller/templateData.go
Normal 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
|
||||||
|
}
|
@@ -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
|
||||||
}
|
}
|
||||||
|
15
webcontroller/userAccount.go
Normal file
15
webcontroller/userAccount.go
Normal 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,
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
@@ -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 {
|
||||||
|
Reference in New Issue
Block a user