Switch to dropzonejs. Fixes #18
This commit is contained in:
parent
ba73f4adf3
commit
31359499ac
|
@ -32,8 +32,8 @@ func TestIndex(t *testing.T) {
|
||||||
|
|
||||||
goji.DefaultMux.ServeHTTP(w, req)
|
goji.DefaultMux.ServeHTTP(w, req)
|
||||||
|
|
||||||
if !strings.Contains(w.Body.String(), "file-uploader") {
|
if !strings.Contains(w.Body.String(), "Click or Drop file") {
|
||||||
t.Fatal("String 'file-uploader' not found in index response")
|
t.Fatal("String 'Click or Drop file' not found in index response")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,87 +86,6 @@ func TestDisplayNotFound(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPostBodyUpload(t *testing.T) {
|
|
||||||
w := httptest.NewRecorder()
|
|
||||||
|
|
||||||
filename := randomString(10) + ".ext"
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "/upload", strings.NewReader("File content"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/octet-stream")
|
|
||||||
params := req.URL.Query()
|
|
||||||
params.Add("qqfile", filename)
|
|
||||||
req.URL.RawQuery = params.Encode()
|
|
||||||
|
|
||||||
goji.DefaultMux.ServeHTTP(w, req)
|
|
||||||
|
|
||||||
if w.Code != 301 {
|
|
||||||
t.Fatalf("Status code is not 301, but %d", w.Code)
|
|
||||||
}
|
|
||||||
if w.Header().Get("Location") != "/"+filename {
|
|
||||||
t.Fatalf("Was redirected to %s instead of /%s", w.Header().Get("Location"), filename)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostEmptyBodyUpload(t *testing.T) {
|
|
||||||
w := httptest.NewRecorder()
|
|
||||||
|
|
||||||
filename := randomString(10) + ".ext"
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "/upload", strings.NewReader(""))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/octet-stream")
|
|
||||||
params := req.URL.Query()
|
|
||||||
params.Add("qqfile", filename)
|
|
||||||
req.URL.RawQuery = params.Encode()
|
|
||||||
|
|
||||||
goji.DefaultMux.ServeHTTP(w, req)
|
|
||||||
|
|
||||||
if w.Code == 301 {
|
|
||||||
t.Fatal("Status code is 301")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.Contains(w.Body.String(), "Oops! Something went wrong.") {
|
|
||||||
t.Fatal("Response doesn't contain'Oops! Something went wrong.'")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostBodyRandomizeUpload(t *testing.T) {
|
|
||||||
w := httptest.NewRecorder()
|
|
||||||
|
|
||||||
filename := randomString(10) + ".ext"
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "/upload", strings.NewReader("File content"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/octet-stream")
|
|
||||||
params := req.URL.Query()
|
|
||||||
params.Add("qqfile", filename)
|
|
||||||
params.Add("randomize", "true")
|
|
||||||
req.URL.RawQuery = params.Encode()
|
|
||||||
|
|
||||||
goji.DefaultMux.ServeHTTP(w, req)
|
|
||||||
|
|
||||||
if w.Code != 301 {
|
|
||||||
t.Fatalf("Status code is not 301, but %d", w.Code)
|
|
||||||
}
|
|
||||||
if w.Header().Get("Location") == "/"+filename {
|
|
||||||
t.Fatalf("Was redirected to %s instead of something random", filename)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostBodyExpireUpload(t *testing.T) {
|
|
||||||
// Dependant on json info on display url to check expiry
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPutUpload(t *testing.T) {
|
func TestPutUpload(t *testing.T) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
#dropzone {
|
||||||
|
width: 400px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#choices {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dz-default {
|
||||||
|
border: 2px dashed #C9C9C9;
|
||||||
|
color: #C9C9C9;
|
||||||
|
font: 14px "helvetica neue",helvetica,arial,sans-serif;
|
||||||
|
background-color: #FAFBFC;
|
||||||
|
padding-top: 60px;
|
||||||
|
padding-bottom: 60px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dz-default:hover {
|
||||||
|
background-color: #eff4f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.upload {
|
||||||
|
background-color: #E2E2E2;
|
||||||
|
border: 1px solid #C9C9C9;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload a {
|
||||||
|
font-size: 12px;
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 1px dotted #556A7F;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #556A7F;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload a:hover {
|
||||||
|
border-bottom: 1px dotted #556A7F;
|
||||||
|
color: #556A7F;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload .right {
|
||||||
|
float: right;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel {
|
||||||
|
margin-right: 5px;
|
||||||
|
font-size: 10px;
|
||||||
|
border-bottom: 1px dotted #556A7F;
|
||||||
|
}
|
|
@ -189,10 +189,6 @@ body {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#html5 {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#file-uploader a {
|
#file-uploader a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-bottom: 1px dotted #556A7F;
|
border-bottom: 1px dotted #556A7F;
|
||||||
|
|
1291
static/js/cat.js
1291
static/js/cat.js
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,74 @@
|
||||||
|
Dropzone.options.dropzone = {
|
||||||
|
addedfile: function(file) {
|
||||||
|
var upload = document.createElement("div");
|
||||||
|
upload.className = "upload";
|
||||||
|
|
||||||
|
var left = document.createElement("span");
|
||||||
|
left.innerHTML = file.name;
|
||||||
|
file.leftElement = left;
|
||||||
|
upload.appendChild(left);
|
||||||
|
|
||||||
|
var right = document.createElement("div");
|
||||||
|
right.className = "right";
|
||||||
|
var rightleft = document.createElement("span");
|
||||||
|
rightleft.className = "cancel";
|
||||||
|
rightleft.innerHTML = "Cancel";
|
||||||
|
rightleft.onclick = function(ev) {
|
||||||
|
this.removeFile(file);
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
var rightright = document.createElement("span");
|
||||||
|
right.appendChild(rightleft);
|
||||||
|
file.rightLeftElement = rightleft;
|
||||||
|
right.appendChild(rightright);
|
||||||
|
file.rightRightElement = rightright;
|
||||||
|
file.rightElement = right;
|
||||||
|
upload.appendChild(right);
|
||||||
|
file.uploadElement = upload;
|
||||||
|
document.getElementById("uploads").appendChild(upload);
|
||||||
|
},
|
||||||
|
uploadprogress: function(file, p, bytesSent) {
|
||||||
|
p = parseInt(p);
|
||||||
|
file.rightRightElement.innerHTML = p + "%";
|
||||||
|
file.uploadElement.setAttribute("style", 'background-image: -webkit-linear-gradient(left, #F2F4F7 ' + p + '%, #E2E2E2 ' + p + '%); background-image: -moz-linear-gradient(left, #F2F4F7 ' + p + '%, #E2E2E2 ' + p + '%); background-image: -ms-linear-gradient(left, #F2F4F7 ' + p + '%, #E2E2E2 ' + p + '%); background-image: -o-linear-gradient(left, #F2F4F7 ' + p + '%, #E2E2E2 ' + p + '%); background-image: linear-gradient(left, #F2F4F7 ' + p + '%, #E2E2E2 ' + p + '%)');
|
||||||
|
},
|
||||||
|
success: function(file, resp) {
|
||||||
|
file.rightLeftElement.innerHTML = "";
|
||||||
|
file.leftElement.innerHTML = '<a target="_blank" href="' + resp.url + '">' + resp.url + '</a>';
|
||||||
|
file.rightRightElement.innerHTML = "Delete";
|
||||||
|
file.rightRightElement.className = "cancel";
|
||||||
|
file.rightRightElement.style.color = "#E68181";
|
||||||
|
file.rightRightElement.onclick = function(ev) {
|
||||||
|
xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("DELETE", resp.url, true);
|
||||||
|
xhr.setRequestHeader("X-Delete-Key", resp.delete_key);
|
||||||
|
xhr.onreadystatechange = function(file) {
|
||||||
|
if (xhr.status === 404) {
|
||||||
|
file.leftElement.innerHTML = 'Deleted <a target="_blank" href="' + resp.url + '">' + resp.url + '</a>';
|
||||||
|
file.leftElement.style.color = "#E68181";
|
||||||
|
file.rightRightElement.onclick = null;
|
||||||
|
file.rightRightElement.innerHTML = "";
|
||||||
|
}
|
||||||
|
}.bind(this, file);
|
||||||
|
xhr.send();
|
||||||
|
}.bind(this);
|
||||||
|
},
|
||||||
|
error: function(file, errMsg, xhrO) {
|
||||||
|
file.rightLeftElement.onclick = null;
|
||||||
|
file.rightLeftElement.innerHTML = "";
|
||||||
|
file.rightRightElement.innerHTML = "";
|
||||||
|
if (file.status === "canceled") {
|
||||||
|
file.leftElement.innerHTML = "Canceled " + file.name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
file.leftElement.innerHTML = "Could not upload " + file.name;
|
||||||
|
}
|
||||||
|
file.leftElement.style.color = "#E68181";
|
||||||
|
},
|
||||||
|
maxFilesize: 4096,
|
||||||
|
previewsContainer: "#uploads",
|
||||||
|
parallelUploads: 5,
|
||||||
|
headers: {"Accept": "application/json"},
|
||||||
|
dictDefaultMessage: "Click or Drop file(s)",
|
||||||
|
dictFallbackMessage: ""
|
||||||
|
};
|
|
@ -1,24 +1,26 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block head %}
|
||||||
|
<link href='/static/css/dropzone.css' media='screen, projection' rel='stylesheet' type='text/css'>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div id="fileupload">
|
<div id="fileupload">
|
||||||
|
<form action="/upload" class="dropzone" id="dropzone" method="POST" enctype="multipart/form-data">
|
||||||
<div id="html5">
|
<div class="fallback">
|
||||||
<div class="clear"></div>
|
<input name="file" type="file" /><br />
|
||||||
|
<input type="submit" value="Upload">
|
||||||
<form action="/upload" method="POST" enctype="multipart/form-data">
|
|
||||||
<div id="file-uploader" style="min-width: 400px;">
|
|
||||||
<br />
|
|
||||||
<input type="file" name="file" id="file_upload" name="file"><br/ ><br/ >
|
|
||||||
<input id ="upload_btn" type="submit" value="Upload">
|
|
||||||
<br /><br />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="dz-default dz-message">
|
||||||
|
<span>Click or Drop file(s)</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div id="choices">
|
<div id="choices">
|
||||||
<div id="expiry">
|
<div id="expiry">
|
||||||
<label>File expiry:
|
<label>File expiry:
|
||||||
<select name="expires" id="expires" onchange="uploader.setParams({expires: $('#expires').val(), randomize: $('#randomize').is(':checked')})">
|
<select name="expires" id="expires">
|
||||||
</label>
|
</label>
|
||||||
<option value="0">never</option>
|
<option value="0">never</option>
|
||||||
<option value="60">a minute</option>
|
<option value="60">a minute</option>
|
||||||
|
@ -30,29 +32,14 @@
|
||||||
<option value="29030400">a year</option>
|
<option value="29030400">a year</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<label><input name="randomize" id="randomize" type="checkbox" checked /> Randomize filename</label>
|
||||||
<label><input name="randomize" id="randomize" type="checkbox" checked onclick="uploader.setParams({expires: $('#expires').val(), randomize: $('#randomize').is(':checked')})" /> Randomize filename</label>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="clear"></div>
|
||||||
</form>
|
</form>
|
||||||
|
<div id="uploads"></div>
|
||||||
<div style="clear:both;"></div>
|
<div style="clear:both;"></div>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script src="/static/js/dropzone.js"></script>
|
||||||
function downloadJSAtOnload() {
|
<script src="/static/js/upload.js"></script>
|
||||||
var element = document.createElement("script");
|
|
||||||
element.src = "/static/js/cat.js";
|
|
||||||
document.body.appendChild(element);
|
|
||||||
}
|
|
||||||
if (window.addEventListener)
|
|
||||||
window.addEventListener("load", downloadJSAtOnload, false);
|
|
||||||
else if (window.attachEvent)
|
|
||||||
window.attachEvent("onload", downloadJSAtOnload);
|
|
||||||
else window.onload = downloadJSAtOnload;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
13
upload.go
13
upload.go
|
@ -40,17 +40,7 @@ func uploadPostHandler(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
contentType := r.Header.Get("Content-Type")
|
contentType := r.Header.Get("Content-Type")
|
||||||
|
|
||||||
if contentType == "application/octet-stream" {
|
if strings.HasPrefix(contentType, "multipart/form-data") {
|
||||||
if r.URL.Query().Get("randomize") == "true" {
|
|
||||||
upReq.randomBarename = true
|
|
||||||
}
|
|
||||||
upReq.expiry = parseExpiry(r.URL.Query().Get("expires"))
|
|
||||||
|
|
||||||
defer r.Body.Close()
|
|
||||||
upReq.src = r.Body
|
|
||||||
upReq.filename = r.URL.Query().Get("qqfile")
|
|
||||||
|
|
||||||
} else if strings.HasPrefix(contentType, "multipart/form-data") {
|
|
||||||
file, headers, err := r.FormFile("file")
|
file, headers, err := r.FormFile("file")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
oopsHandler(c, w, r)
|
oopsHandler(c, w, r)
|
||||||
|
@ -66,6 +56,7 @@ func uploadPostHandler(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||||
upReq.src = file
|
upReq.src = file
|
||||||
upReq.filename = headers.Filename
|
upReq.filename = headers.Filename
|
||||||
} else {
|
} else {
|
||||||
|
fmt.Println(r.Header.Get("Content-Type"))
|
||||||
if r.FormValue("content") == "" {
|
if r.FormValue("content") == "" {
|
||||||
oopsHandler(c, w, r)
|
oopsHandler(c, w, r)
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue