This commit is contained in:
j 2013-02-12 12:39:52 +05:30
commit 15d3c2c3ba
74 changed files with 47647 additions and 0 deletions

0
item/__init__.py Normal file
View file

14
item/admin.py Normal file
View file

@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
# Written 2010 by j@mailb.org
from django.contrib import admin
import models
class ItemAdmin(admin.ModelAdmin):
search_fields = ['filename', 'slug']
list_display = ('slug', 'filename', 'created', 'size', 'done')
admin.site.register(models.Item, ItemAdmin)

92
item/models.py Normal file
View file

@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
# GPL 2013
from __future__ import division, with_statement
import os
import random
from urllib import quote
import json
from django.db import models
from django.core.files.base import ContentFile
from django.db.models.signals import pre_delete
from django.contrib.auth.models import User, Group
import ox
from ox.django import fields
def new_slug():
current_max = Item.objects.all().count() * 2
slug = ox.to32(random.randint(0, max(10, current_max))).capitalize()
if Item.objects.all().filter(slug=slug).count() > 0:
return new_slug()
return slug
class Item(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
user = models.ForeignKey(User, related_name='items')
slug = models.SlugField(unique=True, default=new_slug)
file = models.FileField(upload_to=lambda f, x: f.path(x), max_length=1024)
filename = models.CharField(max_length=1024)
overlay = fields.DictField(default={}, editable=True)
done = models.BooleanField(default=False)
def get_overlay(self):
return json.dumps(self.overlay)
def size(self):
try:
size = self.file and self.file.size or 0
except:
size = 0
return ox.format_bytes(size)
def get_absolute_url(self):
return '/%s' % self.slug
def get_absolute_pdf_url(self):
filename = self.filename
if not filename.endswith('.pdf'):
filename += '.pdf'
return '/%s/%s' % (self.slug, quote(filename))
def path(self, filename):
if len(filename) > 1024:
filename = os.path.splitext(filename)
filename = filename[0][:1024-len(filename[-1])-3] + '...' + filename[-1]
return os.path.join('item', self.slug, filename)
def __unicode__(self):
return u"%s/%s" %(self.slug, self.filename)
def save_chunk(self, chunk, name='data.bin'):
if not self.done:
if not self.file:
if len(name) > 1024:
name = os.path.splitext(name)
name = name[0][:1024-len(name[-1])-3] + '...' + name[-1]
self.file.save(name, ContentFile(chunk))
self.filename = name
self.save()
os.chmod(self.file.path, 0644)
else:
f = open(self.file.path, 'a')
f.write(chunk)
f.close()
return True
return False
def delete_file(sender, **kwargs):
item= kwargs['instance']
if item.file:
path = item.file.path
item.file.delete()
try:
os.rmdir(os.path.dirname(path))
except OSError:
pass
pre_delete.connect(delete_file, sender=Item)

16
item/tests.py Normal file
View file

@ -0,0 +1,16 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)

116
item/views.py Normal file
View file

@ -0,0 +1,116 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
# GPL 2013
from __future__ import division, with_statement
import os
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
from django.template import RequestContext
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound, Http404
from django.views.decorators.http import condition
from django import forms
from django.db.models import F
from ox.django.http import HttpFileResponse
from ox.django.shortcuts import render_to_json_response
import models
class ChunkForm(forms.Form):
chunk = forms.FileField()
done = forms.IntegerField(required=False)
def chunk(request, slug):
if request.method == 'POST':
item = get_object_or_404(models.Item, slug=slug)
form = ChunkForm(request.POST, request.FILES)
canEdit = True
if form.is_valid() and canEdit:
f = form.cleaned_data['chunk']
response = {
'resultUrl': request.build_absolute_uri(item.get_absolute_url())
}
if item.filename:
name = item.filename
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)
def add(request):
if request.method == 'POST':
if request.POST.get('firefogg', False):
if not request.session.session_key:
request.session.save()
request.session.modified = True
file = models.Item()
file.filename = request.POST.get('name', '')
file.uploader = request.session.session_key
file.save()
response = {
'result': 1,
'maxRetry': 10,
'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 = models.Item(filename=new_file.name)
file.done = True
file.file.save(new_file.name, new_file)
os.chmod(file.file.path, 0644)
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('/')
def index(request):
context = RequestContext(request, {
})
return render_to_response('index.html', context)
def item(request, slug, edit=False):
item = get_object_or_404(models.Item, slug=slug)
edit = edit and item.editable()
context = RequestContext(request, {
'item': item,
'edit': edit
})
return render_to_response('item.html', context)
def pdf(request, slug, filename):
item = get_object_or_404(models.Item, slug=slug)
if filename == 'download':
filename = item.filename
filename = filename.encode('utf-8')
content_type = None
return HttpFileResponse(item.file.path.encode('utf-8'),
content_type=content_type, filename=filename)
def save(request):
data = json.loads(request.POST['data'])
item = get_object_or_404(models.Item, slug=data['id'])
response = json_response({})
if item.editable(request.user):
item.overlay = data['overlay']
item.save()
else:
response = json_response(status=403, text='permission denied')
return render_to_json_response(response)