Switch to dropzonejs. Fixes #18

This commit is contained in:
andreimarcu 2015-09-30 23:37:00 -04:00
parent ba73f4adf3
commit 31359499ac
8 changed files with 1901 additions and 1438 deletions

View File

@ -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()

58
static/css/dropzone.css Normal file
View File

@ -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;
}

View File

@ -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;

File diff suppressed because one or more lines are too long

1729
static/js/dropzone.js Normal file

File diff suppressed because it is too large Load Diff

74
static/js/upload.js Normal file
View File

@ -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: ""
};

View File

@ -1,58 +1,45 @@
{% 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 class="fallback">
<input name="file" type="file" /><br />
<input type="submit" value="Upload">
</div>
<div id="html5"> <div class="dz-default dz-message">
<span>Click or Drop file(s)</span>
</div>
<div id="choices">
<div id="expiry">
<label>File expiry:
<select name="expires" id="expires">
</label>
<option value="0">never</option>
<option value="60">a minute</option>
<option value="300">5 minutes</option>
<option value="3600">an hour</option>
<option value="86400">a day</option>
<option value="604800">a week</option>
<option value="2419200">a month</option>
<option value="29030400">a year</option>
</select>
</div>
<label><input name="randomize" id="randomize" type="checkbox" checked /> Randomize filename</label>
</div>
<div class="clear"></div> <div class="clear"></div>
</form>
<form action="/upload" method="POST" enctype="multipart/form-data"> <div id="uploads"></div>
<div id="file-uploader" style="min-width: 400px;"> <div style="clear:both;"></div>
<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 id="choices">
<div id="expiry">
<label>File expiry:
<select name="expires" id="expires" onchange="uploader.setParams({expires: $('#expires').val(), randomize: $('#randomize').is(':checked')})">
</label>
<option value="0">never</option>
<option value="60">a minute</option>
<option value="300">5 minutes</option>
<option value="3600">an hour</option>
<option value="86400">a day</option>
<option value="604800">a week</option>
<option value="2419200">a month</option>
<option value="29030400">a year</option>
</select>
</div>
<label><input name="randomize" id="randomize" type="checkbox" checked onclick="uploader.setParams({expires: $('#expires').val(), randomize: $('#randomize').is(':checked')})" /> Randomize filename</label>
</div>
</form>
<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 %}

View File

@ -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