add login/register forms. Restructure pixelapi
This commit is contained in:
@@ -1,10 +1,7 @@
|
||||
package pixelapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/Fornaxian/log"
|
||||
)
|
||||
|
||||
// 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
|
||||
func (p *PixelAPI) GetFileInfo(id string) *FileInfo {
|
||||
body, err := getString(p.apiEndpoint + "/file/" + id + "/info")
|
||||
|
||||
func (p *PixelAPI) GetFileInfo(id string) (resp *FileInfo, err *Error) {
|
||||
resp = &FileInfo{}
|
||||
err = getJSON(p.apiEndpoint+"/file/"+id+"/info", resp)
|
||||
if err != nil {
|
||||
log.Error("req failed: %v", err)
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
var fileInfo FileInfo
|
||||
err = json.Unmarshal([]byte(body), &fileInfo)
|
||||
if err != nil {
|
||||
log.Error("unmarshal failed: %v. json: %s", err, body)
|
||||
return nil
|
||||
}
|
||||
return &fileInfo
|
||||
return resp, nil
|
||||
}
|
||||
|
@@ -1,9 +1,5 @@
|
||||
package pixelapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// API error constants
|
||||
const (
|
||||
ListNotFoundError = "list_not_found"
|
||||
@@ -11,7 +7,6 @@ const (
|
||||
|
||||
// List information object from the pixeldrain API
|
||||
type List struct {
|
||||
Error *ErrorResponse
|
||||
Success bool `json:"success"`
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
@@ -32,22 +27,11 @@ type ListFile struct {
|
||||
|
||||
// GetList get a List from the pixeldrain API. Errors will be available through
|
||||
// List.Error. Standard error checks apply.
|
||||
func (p *PixelAPI) GetList(id string) *List {
|
||||
var list = &List{}
|
||||
body, err := getString(p.apiEndpoint + "/list/" + id)
|
||||
func (p *PixelAPI) GetList(id string) (resp *List, err *Error) {
|
||||
resp = &List{}
|
||||
err = getJSON(p.apiEndpoint+"/list/"+id, resp)
|
||||
if err != nil {
|
||||
list.Error = errorResponseFromError(err)
|
||||
return list
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(body), list)
|
||||
if err != nil {
|
||||
list.Error = errorResponseFromError(err)
|
||||
return list
|
||||
}
|
||||
|
||||
if !list.Success {
|
||||
list.Error = errorResponseFromJSON(body)
|
||||
}
|
||||
return list
|
||||
return resp, nil
|
||||
}
|
||||
|
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
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/Fornaxian/log"
|
||||
)
|
||||
|
||||
// PixelAPI is the Pixeldrain API client
|
||||
type PixelAPI struct {
|
||||
apiEndpoint string
|
||||
}
|
||||
|
||||
// New creates a new Pixeldrain API client to query the Pixeldrain API with
|
||||
func New(apiEndpoint string) *PixelAPI {
|
||||
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
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
Created on : Jun 3, 2015, 9:33:11 AM
|
||||
Author : Fornax
|
||||
*/
|
||||
@@ -72,7 +72,7 @@ html{
|
||||
margin: 0 4px;
|
||||
text-decoration: none;
|
||||
font-family: "Lato", sans-serif;
|
||||
font-weight: bold;
|
||||
font-weight: bold;
|
||||
font-size: 26px;
|
||||
}
|
||||
.navigation a:hover {
|
||||
@@ -123,8 +123,8 @@ html{
|
||||
.highlight_middle {background-color: #3a3a3a;}
|
||||
.highlight_dark {background-color: #303030;}
|
||||
|
||||
.border-top {border-top: #686868 1px solid;}
|
||||
.border-bottom {border-bottom: #686868 1px solid;}
|
||||
.border_top {border-top: #686868 1px solid;}
|
||||
.border_bottom {border-bottom: #686868 1px solid;}
|
||||
|
||||
/* Common elements */
|
||||
|
||||
@@ -241,9 +241,13 @@ a:hover{
|
||||
|
||||
/* Form fields */
|
||||
|
||||
.form_input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* BUTTONS */
|
||||
button,
|
||||
input[type="submit"],
|
||||
input[type="submit"],
|
||||
input[type="button"],
|
||||
input[type="color"],
|
||||
select{
|
||||
@@ -260,19 +264,19 @@ select{
|
||||
cursor: pointer;
|
||||
}
|
||||
button:hover,
|
||||
input[type="submit"]:hover,
|
||||
input[type="submit"]:hover,
|
||||
input[type="button"]:hover,
|
||||
input[type="color"]:hover,
|
||||
select:hover,
|
||||
button:focus,
|
||||
input[type="submit"]:focus,
|
||||
input[type="submit"]:focus,
|
||||
input[type="button"]:focus,
|
||||
input[type="color"]:focus,
|
||||
select:focus{
|
||||
box-shadow: var(--highlight_border), 2px 2px 8px #000000;
|
||||
}
|
||||
button:active,
|
||||
input[type="submit"]:active,
|
||||
input[type="submit"]:active,
|
||||
input[type="button"]:active,
|
||||
input[type="color"]:active,
|
||||
select:active{
|
||||
@@ -281,10 +285,10 @@ select:active{
|
||||
padding: 8px 8px 4px 12px;
|
||||
}
|
||||
.button_full_width {width: calc(100% - 4px);}
|
||||
.button_highlight {background: linear-gradient(var(--highlight_color), var(--highlight_color_dark));}
|
||||
.button_highlight:active{background: linear-gradient(var(--highlight_color_dark), var(--highlight_color));}
|
||||
.button_red {background: linear-gradient(#821C40, #61152F);}
|
||||
.button_red:active {background: linear-gradient(#61152F, #821C40);}
|
||||
.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)) !important; color: #000000 !important;}
|
||||
.button_red {background: linear-gradient(#821C40, #61152F) !important;}
|
||||
.button_red:active {background: linear-gradient(#61152F, #821C40) !important;}
|
||||
|
||||
/* Dropdown list of the select tag */
|
||||
option{
|
||||
|
@@ -1,24 +1,22 @@
|
||||
{{define "login"}}
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>Login ~ PixelDrain</title>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="stylesheet" href="/res/style/home.css"/>
|
||||
<link rel="stylesheet" href="/res/style/season.css"/>
|
||||
<link rel="stylesheet" href="/res/style/form.css"/>
|
||||
<link rel="stylesheet" href="/res/style/menu.css"/>
|
||||
<link rel="stylesheet" href="/global.css"/>
|
||||
<link rel="stylesheet" href="/res/style/layout.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 rel="shortcut icon" href="/res/img/tray32.png"/>
|
||||
<meta name="theme-color" content="#9FCF6C"/>
|
||||
<link rel="icon" sizes="180x180" href="/res/img/pixeldrain.png"/>
|
||||
<link rel="icon" sizes="256x256" href="/res/img/pixeldrain_big.png"/>
|
||||
|
||||
<style th:include="fragments :: background-pattern" th:inline="text"></style>
|
||||
{{template "bgpattern"}}
|
||||
|
||||
<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.
|
||||
<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.
|
||||
PixelDrain also supports previews for images, videos, audio, PDFs and much more.
|
||||
Uncensored, unmonitored and unmoderated."/>
|
||||
<meta property="og:type" content="website" />
|
||||
@@ -32,49 +30,30 @@
|
||||
|
||||
<body>
|
||||
<div id='body' class="body">
|
||||
<div th:replace="fragments :: menu"></div>
|
||||
<br/><br/>
|
||||
|
||||
<div id="message" th:switch="${messageType}">
|
||||
<div th:case="'info'" th:utext="${message}" id="text-info" class="text-info"></div>
|
||||
<div th:case="'warn'" th:utext="${message}" id="text-warning" class="text-warning"></div>
|
||||
</div>
|
||||
|
||||
Log in to your PixelDrain account
|
||||
<form action="/login" method="POST">
|
||||
<table>
|
||||
{{template "menu"}}
|
||||
|
||||
<h1>Log in to your PixelDrain account</h1>
|
||||
<form action="/login" method="POST" class="highlight_dark border_top border_bottom">
|
||||
<table style="margin-left: auto; margin-right: auto;">
|
||||
<tr>
|
||||
<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>
|
||||
<td>Password</td>
|
||||
<td><input name="password" type="password"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2 style="text-align: right;"><input type="submit" value="Login"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<input type="submit" value="Login"/>
|
||||
</form>
|
||||
<br/><br/>
|
||||
If you don't have a PixelDrain account, you can <a href="/register">register here</a>.
|
||||
<br/>
|
||||
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>
|
||||
|
||||
<!-- Google Analytics Tracking Code -->
|
||||
<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>
|
||||
{{template "analytics"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
|
@@ -1,26 +1,22 @@
|
||||
{{define "register"}}
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>Register ~ PixelDrain</title>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="stylesheet" href="/res/style/home.css"/>
|
||||
<link rel="stylesheet" href="/res/style/season.css"/>
|
||||
<link rel="stylesheet" href="/res/style/form.css"/>
|
||||
<link rel="stylesheet" href="/res/style/menu.css"/>
|
||||
<link rel="stylesheet" href="/global.css"/>
|
||||
<link rel="stylesheet" href="/res/style/layout.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 rel="shortcut icon" href="/res/img/tray32.png"/>
|
||||
<meta name="theme-color" content="#9FCF6C"/>
|
||||
<link rel="icon" sizes="180x180" href="/res/img/pixeldrain.png"/>
|
||||
<link rel="icon" sizes="256x256" href="/res/img/pixeldrain_big.png"/>
|
||||
|
||||
<style th:include="fragments :: background-pattern" th:inline="text"></style>
|
||||
{{template "bgpattern"}}
|
||||
|
||||
<script src='https://www.google.com/recaptcha/api.js'></script>
|
||||
|
||||
<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.
|
||||
<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.
|
||||
PixelDrain also supports previews for images, videos, audio, PDFs and much more.
|
||||
Uncensored, unmonitored and unmoderated."/>
|
||||
<meta property="og:type" content="website" />
|
||||
@@ -30,53 +26,39 @@
|
||||
<meta property="og:url" content="http://pixeldra.in/" />
|
||||
<meta property="og:image" content="/res/img/pixeldrain_big.png" />
|
||||
<meta property="og:image:type" content="image/png" />
|
||||
|
||||
<script src="https://www.google.com/recaptcha/api.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id='body' class="body">
|
||||
<div th:replace="fragments :: menu"></div>
|
||||
<br/>
|
||||
{{template "menu"}}
|
||||
|
||||
<h3>Register a new PixelDrain account</h3>
|
||||
<div id="message" th:switch="${messageType}">
|
||||
<div th:case="'info'" th:utext="${message}" id="text-info" class="text-info"></div>
|
||||
<div th:case="'warn'" th:utext="${message}" id="text-warning" class="text-warning"></div>
|
||||
</div>
|
||||
<form action="/register" method="POST">
|
||||
|
||||
|
||||
Username (Used to log in)<br/>
|
||||
<input name="username" type="text" th:value="${username}"/><br/>
|
||||
<br/>
|
||||
Enter your password twice (Why twice? So we can verify that you have not made any typing errors)<br/>
|
||||
<input name="password1" type="password" th:value="${password1}"/><br/>
|
||||
<input name="password2" type="password" th:value="${password2}"/><br/>
|
||||
<br/>
|
||||
Prove that you're not a robot (Click the white box)
|
||||
<div class="g-recaptcha" data-theme="dark"
|
||||
data-sitekey="6LdEeQ0TAAAAALBmDF_k_2LgbpuJM66PGspByViS">
|
||||
</div><br/>
|
||||
<br/>
|
||||
<input type="submit" value="Register"/>
|
||||
<h1>Register a new Pixeldrain account</h1>
|
||||
<form action="/login" method="POST" class="highlight_dark border_top border_bottom">
|
||||
<table style="margin-left: auto; margin-right: auto; text-align: left; max-width: 30em;">
|
||||
<tr><td>Username (Used to log in)</td></tr>
|
||||
<tr><td><input name="username" type="text" class="form_input"/></td></tr>
|
||||
<tr><td>
|
||||
Enter your password twice:<br/>
|
||||
(So we can verify that you have not made any typing errors)
|
||||
</td></tr>
|
||||
<tr><td><input name="password1" type="password" class="form_input"/></td></tr>
|
||||
<tr><td><input name="password2" type="password" class="form_input"/></td></tr>
|
||||
<tr><td>Prove that you're not a robot (Click the white box)</td></tr>
|
||||
<tr><td style="text-align: center;">
|
||||
<div class="g-recaptcha" data-theme="dark" data-sitekey="6LdEeQ0TAAAAALBmDF_k_2LgbpuJM66PGspByViS"></div>
|
||||
</td></tr>
|
||||
</tr>
|
||||
<tr><td colspan=2 style="text-align: right;"><input type="submit" value="Register" class="button_highlight"/></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<br/>
|
||||
Welcome to the club!<br/>
|
||||
{{template "footer"}}
|
||||
</div>
|
||||
|
||||
<!-- Google Analytics Tracking Code -->
|
||||
<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>
|
||||
{{template "analytics"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{{define "footer"}}
|
||||
<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>.
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
@@ -1,8 +1,9 @@
|
||||
{{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="/history">My Files</a>
|
||||
<a href="/api">API Documentation</a>
|
||||
<a href="/user">Account</a>
|
||||
<a href="javascript:void(0);" class="icon" onclick="expandNavigation()">☰</a>
|
||||
<script>
|
||||
function expandNavigation() {
|
||||
@@ -15,4 +16,4 @@
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
@@ -36,14 +36,14 @@
|
||||
<br/>
|
||||
<div id="body" class="body">
|
||||
{{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"/>
|
||||
<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/>
|
||||
|
||||
<div id="uploads_queue" class="uploads_queue"></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>
|
||||
</div>
|
||||
|
||||
|
@@ -24,8 +24,8 @@ func (wc *WebController) serveFilePreview(w http.ResponseWriter, r *http.Request
|
||||
return
|
||||
}
|
||||
|
||||
inf := wc.api.GetFileInfo(p.ByName("id")) // TODO: Error handling
|
||||
if inf == nil {
|
||||
inf, err := wc.api.GetFileInfo(p.ByName("id")) // TODO: Error handling
|
||||
if err != nil {
|
||||
wc.serveNotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
@@ -28,8 +28,8 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request,
|
||||
|
||||
var finfo []*pixelapi.FileInfo
|
||||
for _, id := range ids {
|
||||
inf := wc.api.GetFileInfo(id)
|
||||
if inf == nil {
|
||||
inf, err := wc.api.GetFileInfo(id)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
finfo = append(finfo, inf)
|
||||
|
@@ -10,10 +10,10 @@ import (
|
||||
|
||||
// ServeListViewer controller for GET /l/: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)
|
||||
var list, aerr = wc.api.GetList(p.ByName("id"))
|
||||
if aerr != nil {
|
||||
if aerr.ReqError {
|
||||
log.Error("API request error occurred: %s", aerr.Value)
|
||||
}
|
||||
wc.serveNotFound(w, r)
|
||||
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
|
||||
// defined in the config file
|
||||
func (tm *TemplateManager) ParseTemplates() {
|
||||
// defined in the config file.
|
||||
// If silent is false it will print an info log message for every template found
|
||||
func (tm *TemplateManager) ParseTemplates(silent bool) {
|
||||
var templatePaths []string
|
||||
|
||||
filepath.Walk(tm.templateDir, func(path string, f os.FileInfo, err error) error {
|
||||
@@ -35,7 +36,9 @@ func (tm *TemplateManager) ParseTemplates() {
|
||||
return nil
|
||||
}
|
||||
templatePaths = append(templatePaths, path)
|
||||
log.Info("Template found: %s", path)
|
||||
if !silent {
|
||||
log.Info("Template found: %s", path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -57,5 +60,8 @@ func (tm *TemplateManager) ParseTemplates() {
|
||||
|
||||
// Get returns the templates, so they can be used to render views
|
||||
func (tm *TemplateManager) Get() *template.Template {
|
||||
if tm.debugModeEnabled {
|
||||
tm.ParseTemplates(true)
|
||||
}
|
||||
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.DebugMode,
|
||||
)
|
||||
wc.templates.ParseTemplates()
|
||||
wc.templates.ParseTemplates(false)
|
||||
|
||||
// Serve static files
|
||||
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+"/t" /* */, wc.serveTemplate("paste"))
|
||||
|
||||
r.GET(prefix+"/register" /* */, wc.serveTemplate("register"))
|
||||
r.GET(prefix+"/login" /* */, wc.serveTemplate("login"))
|
||||
|
||||
r.NotFound = http.HandlerFunc(wc.serveNotFound)
|
||||
|
||||
return wc
|
||||
}
|
||||
|
||||
func (wc *WebController) ReloadTemplates() {
|
||||
wc.templates.ParseTemplates()
|
||||
wc.templates.ParseTemplates(false)
|
||||
}
|
||||
|
||||
func (wc *WebController) serveTemplate(tpl string) httprouter.Handle {
|
||||
|
Reference in New Issue
Block a user