basic file upload works
This commit is contained in:
parent
7fc6cd215f
commit
bdf16adb52
|
@ -9,6 +9,8 @@ from convert import convertFile
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from settings import UPLOAD_ROOT, MEDIA_ROOT
|
from settings import UPLOAD_ROOT, MEDIA_ROOT
|
||||||
from utils.add_file import hashFile, fileInfo, getFileType
|
from utils.add_file import hashFile, fileInfo, getFileType
|
||||||
|
from django.core.files.base import ContentFile
|
||||||
|
|
||||||
|
|
||||||
#FIXME: The following two functions are ridiculous. please remove and clean up all references to them.
|
#FIXME: The following two functions are ridiculous. please remove and clean up all references to them.
|
||||||
def baseFileName(filename):
|
def baseFileName(filename):
|
||||||
|
@ -72,6 +74,7 @@ class File(models.Model):
|
||||||
file = models.FileField('File', upload_to=UPLOAD_ROOT, max_length=1024)
|
file = models.FileField('File', upload_to=UPLOAD_ROOT, max_length=1024)
|
||||||
full_path = models.CharField(max_length=2048, blank=True, db_index=True) #makes it more efficient to retrieve a file by path instead of using self.file.path
|
full_path = models.CharField(max_length=2048, blank=True, db_index=True) #makes it more efficient to retrieve a file by path instead of using self.file.path
|
||||||
title = models.CharField(max_length=255)
|
title = models.CharField(max_length=255)
|
||||||
|
done = models.BooleanField(default=False)
|
||||||
description = models.TextField(blank=True)
|
description = models.TextField(blank=True)
|
||||||
tags = TagField("Tags", help_text="Enter as many tags as you like, separated by commas")
|
tags = TagField("Tags", help_text="Enter as many tags as you like, separated by commas")
|
||||||
userID = models.ForeignKey(User)
|
userID = models.ForeignKey(User)
|
||||||
|
@ -85,6 +88,21 @@ class File(models.Model):
|
||||||
# folder = models.ForeignKey("Folder")
|
# folder = models.ForeignKey("Folder")
|
||||||
info = models.CharField(max_length=1024, blank=True, null=True)
|
info = models.CharField(max_length=1024, blank=True, null=True)
|
||||||
|
|
||||||
|
def save_chunk(self, chunk, name='data.bin'):
|
||||||
|
if not self.done:
|
||||||
|
if not self.file:
|
||||||
|
self.file.save(name, ContentFile(chunk))
|
||||||
|
self.filename = name
|
||||||
|
self.save()
|
||||||
|
else:
|
||||||
|
f = open(self.file.path, 'a')
|
||||||
|
f.write(chunk)
|
||||||
|
f.close()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_from_path(cls, category, user, path, **kwargs):
|
def add_from_path(cls, category, user, path, **kwargs):
|
||||||
if cls.objects.filter(full_path=path).count() > 0:
|
if cls.objects.filter(full_path=path).count() > 0:
|
||||||
|
@ -156,4 +174,4 @@ class Type(models.Model):
|
||||||
verbose_name = 'File Type'
|
verbose_name = 'File Type'
|
||||||
verbose_name_plural = 'File Types'
|
verbose_name_plural = 'File Types'
|
||||||
|
|
||||||
post_save.connect(convertFile, sender=File)
|
# post_save.connect(convertFile, sender=File)
|
||||||
|
|
|
@ -4,4 +4,15 @@ import views
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
(r'addFolder', views.add_folder),
|
(r'addFolder', views.add_folder),
|
||||||
(r'upload', views.upload_files),
|
(r'upload', views.upload_files),
|
||||||
|
(r'add', views.add),
|
||||||
|
(r'^([A-Z0-9].*)/chunk$', views.chunk)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# urlpatterns += patterns('views',
|
||||||
|
# (r'^$', 'index'),
|
||||||
|
# (r'^add$', 'add'),
|
||||||
|
# (r'^([A-Z0-9].*)/$', 'view'),
|
||||||
|
# (r'^([A-Z0-9].*)/chunk$', 'chunk'),
|
||||||
|
# (r'^([A-Z0-9].*)/(.+)$', 'download'),
|
||||||
|
# (r'^([A-Z0-9].*)$', 'view'),
|
||||||
|
# )
|
||||||
|
|
|
@ -8,7 +8,9 @@ from settings import FTP_ROOT, UPLOAD_ROOT
|
||||||
import os
|
import os
|
||||||
from os.path import join, isdir, getmtime, basename
|
from os.path import join, isdir, getmtime, basename
|
||||||
import shutil
|
import shutil
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
from ox.django.shortcuts import render_to_json_response
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
'''
|
'''
|
||||||
class folder_names(object):
|
class folder_names(object):
|
||||||
|
@ -85,6 +87,77 @@ def add_folder(request):
|
||||||
def editor(request):
|
def editor(request):
|
||||||
return render_to_response("editor.html")
|
return render_to_response("editor.html")
|
||||||
|
|
||||||
|
'''
|
||||||
def gallery(request):
|
def gallery(request):
|
||||||
return HttpResponseRedirect('http://www.urbaanedge.com/wordpress')
|
return HttpResponseRedirect('http://www.urbaanedge.com/wordpress')
|
||||||
|
'''
|
||||||
|
|
||||||
|
#Start Upload stuff - from hostb.org/host/views.py
|
||||||
|
|
||||||
|
class ChunkForm(forms.Form):
|
||||||
|
chunk = forms.FileField()
|
||||||
|
done = forms.IntegerField(required=False)
|
||||||
|
|
||||||
|
@csrf_exempt
|
||||||
|
def chunk(request, id):
|
||||||
|
if request.method == 'POST':
|
||||||
|
item = get_object_or_404(File, id=id)
|
||||||
|
form = ChunkForm(request.POST, request.FILES)
|
||||||
|
canEdit = True
|
||||||
|
if form.is_valid() and canEdit:
|
||||||
|
f = form.cleaned_data['chunk']
|
||||||
|
response = {
|
||||||
|
'resultUrl': '/files/' + str(item.id)
|
||||||
|
}
|
||||||
|
if item.title:
|
||||||
|
name = item.title
|
||||||
|
else:
|
||||||
|
name = f.name
|
||||||
|
if not item.save_chunk(f.read(), name):
|
||||||
|
response['result'] = 'failed'
|
||||||
|
elif form.cleaned_data['done']:
|
||||||
|
item.done = True
|
||||||
|
item.save()
|
||||||
|
response['done'] = 1
|
||||||
|
response['result'] = 1
|
||||||
|
else:
|
||||||
|
response['result'] = 1
|
||||||
|
return render_to_json_response(response)
|
||||||
|
response = {
|
||||||
|
'result': -1,
|
||||||
|
'fileUrl': '/'
|
||||||
|
}
|
||||||
|
return render_to_json_response(response)
|
||||||
|
|
||||||
|
@csrf_exempt
|
||||||
|
def add(request):
|
||||||
|
if request.method == 'POST':
|
||||||
|
if request.POST.get('firefogg', False):
|
||||||
|
file = File()
|
||||||
|
file.userID = request.user
|
||||||
|
file.info = '' #WTF!
|
||||||
|
file.title = request.POST.get('name', '')
|
||||||
|
file.save()
|
||||||
|
response = {
|
||||||
|
'result': 1,
|
||||||
|
'maxRetry': 10,
|
||||||
|
'uploadUrl': '/files/' + str(file.id) + "/chunk"
|
||||||
|
# 'uploadUrl': request.build_absolute_uri("%s/chunk" % file.get_absolute_url())
|
||||||
|
}
|
||||||
|
return render_to_json_response(response)
|
||||||
|
# Save any files that were uploaded (ignoring empty form fields)
|
||||||
|
if 'file' in request.FILES:
|
||||||
|
new_file = request.FILES['file']
|
||||||
|
file = File(title=new_file.name)
|
||||||
|
file.userID = request.user
|
||||||
|
file.done = True
|
||||||
|
file.info = '' #WTF!
|
||||||
|
file.file.save(new_file.name, new_file)
|
||||||
|
file.save()
|
||||||
|
if request.POST.get('api', False):
|
||||||
|
return HttpResponse(request.build_absolute_uri(file.get_absolute_url()), content_type="text/plain")
|
||||||
|
return HttpResponseRedirect(file.get_absolute_url())
|
||||||
|
|
||||||
|
#no upload
|
||||||
|
return HttpResponseRedirect('/')
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ from os.path import join
|
||||||
|
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
TEMPLATE_DEBUG = DEBUG
|
TEMPLATE_DEBUG = DEBUG
|
||||||
|
JSON_DEBUG = DEBUG
|
||||||
LOCAL_DEVELOPMENT = True
|
LOCAL_DEVELOPMENT = True
|
||||||
APPEND_SLASH = True
|
APPEND_SLASH = True
|
||||||
LOGGING_INTERCEPT_REDIRECTS = False
|
LOGGING_INTERCEPT_REDIRECTS = False
|
||||||
|
|
56
edgware/static/js/upload/firefogg.js
Normal file
56
edgware/static/js/upload/firefogg.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#firefogg').hide();
|
||||||
|
if(typeof(Firefogg) != 'undefined') {
|
||||||
|
$('#addFile').hide();
|
||||||
|
$('#firefogg').show();
|
||||||
|
$('#submitFile').hide();
|
||||||
|
|
||||||
|
ogg = new Firefogg();
|
||||||
|
|
||||||
|
$('#selectFile').click(function() {
|
||||||
|
if(ogg.selectVideo()) {
|
||||||
|
$('#selectFile').hide();
|
||||||
|
$('#submitFile').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('#submitFile').click(function() {
|
||||||
|
$('#submitFile').hide();
|
||||||
|
$('#progressbar').show();
|
||||||
|
$('#progressbar').width(200);
|
||||||
|
$('#progressbar').css('background-color', '#eee');
|
||||||
|
$('#progressbar').html('<div id="progress" style="background-color: #666;height:20px;" /><div id="progressstatus" style="background-color: #fff;" />')
|
||||||
|
options = JSON.stringify({'passthrough': true});
|
||||||
|
var _data = $('#firefogg').serializeArray();
|
||||||
|
var data = {}
|
||||||
|
$(_data).each(function() {
|
||||||
|
data[this.name] = this.value;
|
||||||
|
})
|
||||||
|
data['firefogg'] = 1;
|
||||||
|
var data = JSON.stringify(data);
|
||||||
|
ogg.upload(options, add_url, data);
|
||||||
|
var updateStatus = function() {
|
||||||
|
var status = ogg.status();
|
||||||
|
var progress = ogg.progress();
|
||||||
|
|
||||||
|
//do something with status and progress, i.e. set progressbar width:
|
||||||
|
var progressbar = document.getElementById('progress');
|
||||||
|
progressbar.style.width= parseInt(progress*200) +'px';
|
||||||
|
$('#progressstatus').html(parseInt(progress*100) + '% - ' + status);
|
||||||
|
|
||||||
|
//loop to get new status if still encoding
|
||||||
|
if(ogg.state == 'encoding' || ogg.state == 'uploading') {
|
||||||
|
setTimeout(updateStatus, 500);
|
||||||
|
}
|
||||||
|
//encoding sucessfull, state can also be 'encoding failed'
|
||||||
|
else if (ogg.state == 'done') {
|
||||||
|
if(ogg.resultUrl)
|
||||||
|
document.location.href = ogg.resultUrl;
|
||||||
|
} else {
|
||||||
|
$('#progressstatus').html(ogg.state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateStatus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
97
edgware/static/js/upload/jquery.uploadProgress.js
Normal file
97
edgware/static/js/upload/jquery.uploadProgress.js
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* jquery.uploadProgress
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008 Piotr Sarnacki (drogomir.com)
|
||||||
|
*
|
||||||
|
* Licensed under the MIT license:
|
||||||
|
* http://www.opensource.org/licenses/mit-license.php
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
(function($) {
|
||||||
|
$.fn.uploadProgress = function(options) {
|
||||||
|
options = $.extend({
|
||||||
|
dataType: "json",
|
||||||
|
interval: 2000,
|
||||||
|
progressBar: "#progressbar",
|
||||||
|
progressUrl: "/progress",
|
||||||
|
start: function() {},
|
||||||
|
uploading: function() {},
|
||||||
|
complete: function() {},
|
||||||
|
success: function() {},
|
||||||
|
error: function() {},
|
||||||
|
preloadImages: [],
|
||||||
|
uploadProgressPath: '/javascripts/jquery.uploadProgress.js',
|
||||||
|
jqueryPath: '/javascripts/jquery.js',
|
||||||
|
timer: ""
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
//preload images
|
||||||
|
for(var i = 0; i<options.preloadImages.length; i++)
|
||||||
|
{
|
||||||
|
options.preloadImages[i] = $("<img>").attr("src", options.preloadImages[i]);
|
||||||
|
}
|
||||||
|
/* tried to add iframe after submit (to not always load it) but it won't work.
|
||||||
|
safari can't get scripts properly while submitting files */
|
||||||
|
if($.browser.safari && top.document == document) {
|
||||||
|
/* iframe to send ajax requests in safari
|
||||||
|
thanks to Michele Finotto for idea */
|
||||||
|
iframe = document.createElement('iframe');
|
||||||
|
iframe.name = "progressFrame";
|
||||||
|
$(iframe).css({width: '0', height: '0', position: 'absolute', top: '-3000px'});
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
|
||||||
|
var d = iframe.contentWindow.document;
|
||||||
|
d.open();
|
||||||
|
/* weird - safari won't load scripts without this lines... */
|
||||||
|
d.write('<html><head></head><body></body></html>');
|
||||||
|
d.close();
|
||||||
|
|
||||||
|
var b = d.body;
|
||||||
|
var s = d.createElement('script');
|
||||||
|
s.src = options.jqueryPath;
|
||||||
|
/* must be sure that jquery is loaded */
|
||||||
|
s.onload = function() {
|
||||||
|
var s1 = d.createElement('script');
|
||||||
|
s1.src = options.uploadProgressPath;
|
||||||
|
b.appendChild(s1);
|
||||||
|
}
|
||||||
|
b.appendChild(s);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.each(function(){
|
||||||
|
$(this).bind('submit', function() {
|
||||||
|
var uuid = "";
|
||||||
|
for (i = 0; i < 32; i++) { uuid += Math.floor(Math.random() * 16).toString(16); }
|
||||||
|
|
||||||
|
/* update uuid */
|
||||||
|
options.uuid = uuid;
|
||||||
|
/* start callback */
|
||||||
|
options.start();
|
||||||
|
|
||||||
|
/* patch the form-action tag to include the progress-id if X-Progress-ID has been already added just replace it */
|
||||||
|
if(old_id = /X-Progress-ID=([^&]+)/.exec($(this).attr("action"))) {
|
||||||
|
var action = $(this).attr("action").replace(old_id[1], uuid);
|
||||||
|
$(this).attr("action", action);
|
||||||
|
} else {
|
||||||
|
$(this).attr("action", jQuery(this).attr("action") + "?X-Progress-ID=" + uuid);
|
||||||
|
}
|
||||||
|
var uploadProgress = $.browser.safari ? progressFrame.jQuery.uploadProgress : jQuery.uploadProgress;
|
||||||
|
options.timer = window.setInterval(function() { uploadProgress(this, options) }, options.interval);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
jQuery.uploadProgress = function(e, options) {
|
||||||
|
jQuery.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: options.progressUrl + "?X-Progress-ID=" + options.uuid,
|
||||||
|
dataType: options.dataType,
|
||||||
|
success: function(upload) {
|
||||||
|
options.uploading(upload);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
})(jQuery);
|
119
edgware/static/js/upload/progressbar.js
Normal file
119
edgware/static/js/upload/progressbar.js
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* based on jquery.uploadProgress
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008 Piotr Sarnacki (drogomir.com)
|
||||||
|
*
|
||||||
|
* Licensed under the MIT license:
|
||||||
|
* http://www.opensource.org/licenses/mit-license.php
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
(function($) {
|
||||||
|
$.fn.uploadProgress = function(options) {
|
||||||
|
options = $.extend({
|
||||||
|
dataType: "json",
|
||||||
|
interval: 2000,
|
||||||
|
progressBar: "#progressbar",
|
||||||
|
progressUrl: "/progress",
|
||||||
|
start: function() {},
|
||||||
|
uploading: function() {},
|
||||||
|
complete: function() {},
|
||||||
|
success: function() {},
|
||||||
|
error: function() {},
|
||||||
|
preloadImages: [],
|
||||||
|
uploadProgressPath: '/javascripts/jquery.uploadProgress.js',
|
||||||
|
jqueryPath: '/javascripts/jquery.js',
|
||||||
|
timer: ""
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
//preload images
|
||||||
|
for(var i = 0; i<options.preloadImages.length; i++)
|
||||||
|
{
|
||||||
|
options.preloadImages[i] = $("<img>").attr("src", options.preloadImages[i]);
|
||||||
|
}
|
||||||
|
/* tried to add iframe after submit (to not always load it) but it won't work.
|
||||||
|
safari can't get scripts properly while submitting files */
|
||||||
|
if($.browser.safari && top.document == document) {
|
||||||
|
/* iframe to send ajax requests in safari
|
||||||
|
thanks to Michele Finotto for idea */
|
||||||
|
iframe = document.createElement('iframe');
|
||||||
|
iframe.name = "progressFrame";
|
||||||
|
$(iframe).css({width: '0', height: '0', position: 'absolute', top: '-3000px'});
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
|
||||||
|
var d = iframe.contentWindow.document;
|
||||||
|
d.open();
|
||||||
|
/* weird - safari won't load scripts without this lines... */
|
||||||
|
d.write('<html><head></head><body></body></html>');
|
||||||
|
d.close();
|
||||||
|
|
||||||
|
var b = d.body;
|
||||||
|
var s = d.createElement('script');
|
||||||
|
s.src = options.jqueryPath;
|
||||||
|
/* must be sure that jquery is loaded */
|
||||||
|
s.onload = function() {
|
||||||
|
var s1 = d.createElement('script');
|
||||||
|
s1.src = options.uploadProgressPath;
|
||||||
|
b.appendChild(s1);
|
||||||
|
}
|
||||||
|
b.appendChild(s);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.each(function(){
|
||||||
|
$(this).bind('submit', function() {
|
||||||
|
var uuid = "";
|
||||||
|
for (i = 0; i < 32; i++) { uuid += Math.floor(Math.random() * 16).toString(16); }
|
||||||
|
|
||||||
|
/* update uuid */
|
||||||
|
options.uuid = uuid;
|
||||||
|
/* start callback */
|
||||||
|
options.start();
|
||||||
|
|
||||||
|
/* patch the form-action tag to include the progress-id if X-Progress-ID has been already added just replace it */
|
||||||
|
if(old_id = /X-Progress-ID=([^&]+)/.exec($(this).attr("action"))) {
|
||||||
|
var action = $(this).attr("action").replace(old_id[1], uuid);
|
||||||
|
$(this).attr("action", action);
|
||||||
|
} else {
|
||||||
|
$(this).attr("action", jQuery(this).attr("action") + "?X-Progress-ID=" + uuid);
|
||||||
|
}
|
||||||
|
var uploadProgress = $.browser.safari ? progressFrame.jQuery.uploadProgress : jQuery.uploadProgress;
|
||||||
|
options.timer = window.setInterval(function() { uploadProgress(this, options) }, options.interval);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
jQuery.uploadProgress = function(e, options) {
|
||||||
|
jQuery.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: options.progressUrl + "?X-Progress-ID=" + options.uuid,
|
||||||
|
dataType: options.dataType,
|
||||||
|
success: function(upload) {
|
||||||
|
options.uploading(upload);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
})(jQuery);
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#addFile').uploadProgress({
|
||||||
|
/* scripts locations for safari */
|
||||||
|
jqueryPath: "/static/js/jquery.js",
|
||||||
|
uploadProgressPath: "/static/js/upload/jquery.uploadProgress.js",
|
||||||
|
start: function(upload) {
|
||||||
|
$('#addFile').hide();
|
||||||
|
$('#progressbar').show();
|
||||||
|
$('#progressbar').html('...');
|
||||||
|
},
|
||||||
|
uploading: function(upload) {
|
||||||
|
var filename = $('#file').val();
|
||||||
|
filename = filename.split('/');
|
||||||
|
filename = filename[filename.length-1];
|
||||||
|
$('#progressbar').html(upload.progressbar_html);
|
||||||
|
if(upload.precents)
|
||||||
|
document.title = upload.precents + "% of " + filename;
|
||||||
|
},
|
||||||
|
interval: 2500
|
||||||
|
});
|
||||||
|
});
|
301
edgware/static/js/upload/upload.js
Normal file
301
edgware/static/js/upload/upload.js
Normal file
|
@ -0,0 +1,301 @@
|
||||||
|
// -*- coding: utf-8 -*-
|
||||||
|
// vi:si:et:sw=2:sts=2:ts=2
|
||||||
|
|
||||||
|
// Workaround for Firefox 4.0 sending an empty string
|
||||||
|
// as filename for Blobs in FormData requests
|
||||||
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=649150
|
||||||
|
function geckoFormData() {
|
||||||
|
var self = this,
|
||||||
|
that = {},
|
||||||
|
boundary = '------XX' + Math.random(),
|
||||||
|
dashdash = '--',
|
||||||
|
crlf = '\r\n',
|
||||||
|
builder = '', // Build RFC2388 string.
|
||||||
|
wait = 0;
|
||||||
|
|
||||||
|
builder += dashdash + boundary + crlf;
|
||||||
|
|
||||||
|
that.append = function(name, data) {
|
||||||
|
// Generate headers.
|
||||||
|
builder += 'Content-Disposition: form-data; name="'+ name +'"';
|
||||||
|
builder += crlf;
|
||||||
|
builder += crlf;
|
||||||
|
|
||||||
|
// Write data.
|
||||||
|
builder += data;
|
||||||
|
builder += crlf;
|
||||||
|
|
||||||
|
// Write boundary.
|
||||||
|
builder += dashdash + boundary + crlf;
|
||||||
|
};
|
||||||
|
that.appendFile = function(name, data, type, filename) {
|
||||||
|
builder += 'Content-Disposition: form-data; name="'+ name +'"';
|
||||||
|
builder += '; filename="' + filename + '"';
|
||||||
|
builder += crlf;
|
||||||
|
builder += 'Content-Type: ' + type;
|
||||||
|
builder += crlf;
|
||||||
|
builder += crlf;
|
||||||
|
|
||||||
|
// Write binary data.
|
||||||
|
builder += data;
|
||||||
|
builder += crlf;
|
||||||
|
|
||||||
|
// Write boundary.
|
||||||
|
builder += dashdash + boundary + crlf;
|
||||||
|
};
|
||||||
|
that.appendBlob = function(name, blob, filename) {
|
||||||
|
wait++;
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(e) {
|
||||||
|
that.appendFile(name, e.target.result, blob.type, filename);
|
||||||
|
// Call onload after last Blob
|
||||||
|
wait--;
|
||||||
|
if(!wait && self.onload) {
|
||||||
|
self.onload();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.readAsBinaryString(blob);
|
||||||
|
};
|
||||||
|
|
||||||
|
that.send = function(xhr) {
|
||||||
|
self.onload = function() {
|
||||||
|
// Mark end of the request.
|
||||||
|
builder += dashdash + boundary + dashdash + crlf;
|
||||||
|
|
||||||
|
// Send to server
|
||||||
|
xhr.setRequestHeader("Content-type", "multipart/form-data; boundary=" + boundary);
|
||||||
|
xhr.sendAsBinary(builder);
|
||||||
|
};
|
||||||
|
if(!wait) {
|
||||||
|
self.onload();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
function FirefoggUploader(file, uploadUrl, uploadData, callback, progress_callback) {
|
||||||
|
var self = this,
|
||||||
|
that = {
|
||||||
|
progress: 0
|
||||||
|
},
|
||||||
|
chunkSize = 1024*1024,
|
||||||
|
chunkUrl,
|
||||||
|
gecko = /gecko\//.test(navigator.userAgent.toLowerCase()),
|
||||||
|
maxRetry = -1,
|
||||||
|
progress,
|
||||||
|
retries = 0;
|
||||||
|
|
||||||
|
progress_callback = progress_callback || function(progress) {};
|
||||||
|
callback = callback || function(result) {};
|
||||||
|
|
||||||
|
function uploadChunk(chunkId) {
|
||||||
|
var bytesAvailable = file.size,
|
||||||
|
chunk,
|
||||||
|
chunkOffset = chunkId * chunkSize;
|
||||||
|
//Slice API was taken out and new version now require start/end and not start/length
|
||||||
|
if(file.slice)
|
||||||
|
chunk = file.slice(chunkOffset, chunkSize, file.type);
|
||||||
|
else if(file.mozSlice)
|
||||||
|
chunk = file.mozSlice(chunkOffset, chunkOffset+chunkSize, file.type);
|
||||||
|
else if(file.webkitSlice)
|
||||||
|
chunk = file.webkitSlice(chunkOffset, chunkOffset+chunkSize, file.type);
|
||||||
|
|
||||||
|
that.progress = parseFloat(chunkOffset)/bytesAvailable;
|
||||||
|
self.req = new XMLHttpRequest();
|
||||||
|
self.req.addEventListener("load", function (evt) {
|
||||||
|
var response;
|
||||||
|
that.responseText = evt.target.responseText;
|
||||||
|
try {
|
||||||
|
response = JSON.parse(evt.target.responseText);
|
||||||
|
} catch(e) {
|
||||||
|
response = {};
|
||||||
|
}
|
||||||
|
if (response.done == 1) {
|
||||||
|
//upload finished
|
||||||
|
that.resultUrl = response.resultUrl;
|
||||||
|
that.progress = 1;
|
||||||
|
that.status = 'done';
|
||||||
|
callback(that);
|
||||||
|
}
|
||||||
|
else if (response.result == 1) {
|
||||||
|
//reset retry counter
|
||||||
|
retries = 0;
|
||||||
|
//start uploading next chunk
|
||||||
|
uploadChunk(chunkId + 1);
|
||||||
|
} else {
|
||||||
|
//failed to upload, try again in 3 second
|
||||||
|
retries++;
|
||||||
|
if (maxRetry > 0 && retries > maxRetry) {
|
||||||
|
that.status = 'uplaod failed';
|
||||||
|
that.progress = -1;
|
||||||
|
callback(that);
|
||||||
|
} else {
|
||||||
|
setTimeout(function() {
|
||||||
|
uploadChunk(chunkId);
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
self.req.addEventListener("error", function (evt) {
|
||||||
|
//failed to upload, try again in 3 second
|
||||||
|
retries++;
|
||||||
|
if (maxRetry > 0 && retries > maxRetry) {
|
||||||
|
that.status = 'uplaod failed';
|
||||||
|
that.progress = -1;
|
||||||
|
callback(that);
|
||||||
|
} else {
|
||||||
|
setTimeout(function() {
|
||||||
|
uploadChunk(chunkId);
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
self.req.upload.addEventListener("progress", function (evt) {
|
||||||
|
if (evt.lengthComputable) {
|
||||||
|
that.progress = parseFloat(chunkOffset + evt.loaded) / bytesAvailable;
|
||||||
|
progress_callback(that.progress);
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
self.req.addEventListener("abort", function (evt) {
|
||||||
|
that.status = 'aborted';
|
||||||
|
that.progress = -1;
|
||||||
|
callback(that);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
var formData;
|
||||||
|
if(gecko) {
|
||||||
|
formData = new geckoFormData();
|
||||||
|
} else {
|
||||||
|
formData = new FormData();
|
||||||
|
}
|
||||||
|
formData.append('chunkId', chunkId);
|
||||||
|
if (bytesAvailable <= chunkOffset + chunkSize) {
|
||||||
|
formData.append('done', 1);
|
||||||
|
}
|
||||||
|
if(gecko) {
|
||||||
|
formData.appendBlob('chunk', chunk, 'chunk.bin');
|
||||||
|
} else {
|
||||||
|
formData.append('chunk', chunk);
|
||||||
|
}
|
||||||
|
self.req.open("POST", chunkUrl, true);
|
||||||
|
if(gecko) {
|
||||||
|
formData.send(self.req);
|
||||||
|
} else {
|
||||||
|
self.req.send(formData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//request upload slot from server
|
||||||
|
that.status = 'requesting chunk upload';
|
||||||
|
self.req = new XMLHttpRequest();
|
||||||
|
self.req.addEventListener("load", function (evt) {
|
||||||
|
var response = {};
|
||||||
|
that.responseText = evt.target.responseText;
|
||||||
|
try {
|
||||||
|
response = JSON.parse(evt.target.responseText);
|
||||||
|
} catch(e) {
|
||||||
|
response = {};
|
||||||
|
that.status = "failed to parse response";
|
||||||
|
that.progress = -1;
|
||||||
|
callback(that);
|
||||||
|
}
|
||||||
|
if (response.maxRetry) {
|
||||||
|
maxRetry = response.maxRetry;
|
||||||
|
}
|
||||||
|
chunkUrl = response.uploadUrl;
|
||||||
|
if (chunkUrl) {
|
||||||
|
that.status = 'uploading';
|
||||||
|
that.progress = 0.0;
|
||||||
|
//start upload
|
||||||
|
uploadChunk(0);
|
||||||
|
} else {
|
||||||
|
that.status = 'upload failed, no upload url provided';
|
||||||
|
that.progress = -1;
|
||||||
|
callback(that);
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
self.req.addEventListener("error", function (evt) {
|
||||||
|
that.status = 'uplaod failed';
|
||||||
|
that.progress = -1;
|
||||||
|
that.responseText = evt.target.responseText;
|
||||||
|
callback(that);
|
||||||
|
}, false);
|
||||||
|
self.req.addEventListener("abort", function (evt) {
|
||||||
|
that.status = 'aborted';
|
||||||
|
that.progress = -1;
|
||||||
|
callback(that);
|
||||||
|
}, false);
|
||||||
|
var formData = new FormData();
|
||||||
|
for(var key in uploadData) {
|
||||||
|
if (uploadData.hasOwnProperty(key)) {
|
||||||
|
formData.append(key, uploadData[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.req.open("POST", uploadUrl);
|
||||||
|
self.req.send(formData);
|
||||||
|
|
||||||
|
//public interface
|
||||||
|
that.abort = function() {
|
||||||
|
if (self.req) {
|
||||||
|
self.req.abort();
|
||||||
|
self.req = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activate on page is possible
|
||||||
|
$(document).ready(function() {
|
||||||
|
var Chrome = /chrome/.test(navigator.userAgent.toLowerCase()),
|
||||||
|
GeckoVersion = navigator.userAgent.match(/rv\:(.+)\) Gecko/),
|
||||||
|
WebKitVersion = navigator.userAgent.match(/AppleWebKit\/([\d\.]+)/);
|
||||||
|
if (WebKitVersion) {
|
||||||
|
WebKitVersion = WebKitVersion[1];
|
||||||
|
}
|
||||||
|
if (GeckoVersion) {
|
||||||
|
GeckoVersion = GeckoVersion[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Chrome || WebKitVersion >= '534.28' ||
|
||||||
|
(GeckoVersion >= '2.0')) {
|
||||||
|
$('#firefogg').hide();
|
||||||
|
$('#submit').hide();
|
||||||
|
$('#file').change(function(e) {
|
||||||
|
if(this.files.length>0) {
|
||||||
|
$('#file').hide();
|
||||||
|
$('#upload').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if($('#file')[0].files.length>0) {
|
||||||
|
$('#file').hide();
|
||||||
|
$('#upload').show();
|
||||||
|
} else {
|
||||||
|
$('#upload').hide();
|
||||||
|
}
|
||||||
|
$('#upload').click(function(e) {
|
||||||
|
$('#upload').hide();
|
||||||
|
e.stopPropagation();
|
||||||
|
var file = $('#file')[0].files[0];
|
||||||
|
var data = {
|
||||||
|
'firefogg': 1,
|
||||||
|
'name': file.name // Send filename here since Blobs will have no name later
|
||||||
|
};
|
||||||
|
var ogg = FirefoggUploader(file, add_url, data, function(ogg) { //callback
|
||||||
|
if(ogg.resultUrl) {
|
||||||
|
document.location.href = ogg.resultUrl;
|
||||||
|
} else {
|
||||||
|
$('#progressstatus').html(ogg.status);
|
||||||
|
}
|
||||||
|
}, function(progress) { //progress callback
|
||||||
|
//do something with status and progress, i.e. set progressbar width:
|
||||||
|
$('#progress').css('width', parseInt(progress*100, 10) +'%');
|
||||||
|
$('#progressstatus').html(parseInt(progress*100, 10) + '% - ' + ogg.status);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#submitFile').hide();
|
||||||
|
$('#progressbar').show();
|
||||||
|
$('#progressbar').width(200);
|
||||||
|
$('#progressbar').css('background-color', '#eee');
|
||||||
|
$('#progressbar').html('<div id="progress" style="background-color: #666;height:20px;width:0%" /><div id="progressstatus" style="background-color: #fff;">uploading</div>');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -26,7 +26,7 @@ urlpatterns = patterns('',
|
||||||
(r'^comments/', include('django.contrib.comments.urls')),
|
(r'^comments/', include('django.contrib.comments.urls')),
|
||||||
(r'^edit/', include('editor.urls')),
|
(r'^edit/', include('editor.urls')),
|
||||||
(r'files/', include('files.urls')),
|
(r'files/', include('files.urls')),
|
||||||
(r'^gallery/', 'files.views.gallery'),
|
# (r'^gallery/', 'files.views.gallery'),
|
||||||
# Uncomment the next line to enable the admin:
|
# Uncomment the next line to enable the admin:
|
||||||
(r'^admin/', include(admin.site.urls)),
|
(r'^admin/', include(admin.site.urls)),
|
||||||
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
|
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user