forked from 0x2620/pandora
upload, recovery
This commit is contained in:
parent
56ae83cb5b
commit
57fad37643
7 changed files with 118 additions and 13 deletions
|
@ -993,7 +993,7 @@ class ListItem(models.Model):
|
|||
def stream_path(f, size):
|
||||
name = "%s.%s" % (size, 'ogv')
|
||||
url_hash = f.oshash
|
||||
return os.path.join('stream', url_hash[:2], url_hash[2:4], url_hash[4:6], name)
|
||||
return os.path.join('stream', url_hash[:2], url_hash[2:4], url_hash[4:6], url_hash, name)
|
||||
|
||||
def still_path(f, still):
|
||||
name = "%s.%s" % (still, 'png')
|
||||
|
@ -1061,13 +1061,14 @@ class File(models.Model):
|
|||
#FIXME: this should use stream128 or stream640 depending on configuration
|
||||
video = getattr(self, 'stream128')
|
||||
if not video:
|
||||
video.save(name, ContentFile(chunk))
|
||||
video.save(name, chunk)
|
||||
self.save()
|
||||
else:
|
||||
f = open(video.path, 'a')
|
||||
f.write(chunk)
|
||||
f.write(chunk.read())
|
||||
f.close()
|
||||
return True
|
||||
print "somehing failed, not sure what?"
|
||||
return False
|
||||
|
||||
objects = managers.FileManager()
|
||||
|
@ -1134,7 +1135,7 @@ class File(models.Model):
|
|||
|
||||
def editable(self, user):
|
||||
#FIXME: make permissions work
|
||||
return False
|
||||
return True
|
||||
|
||||
class Still(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
@ -1213,3 +1214,9 @@ class ArchiveFile(models.Model):
|
|||
return '%s (%s)' % (self.path, unicode(self.archive))
|
||||
|
||||
|
||||
class Collection(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
name = models.CharField(blank=True, max_length=2048)
|
||||
subdomain = models.CharField(unique=True, max_length=2048)
|
||||
movies = models.ForeignKey(Movie)
|
||||
|
|
11
oxdb/backend/urls.py
Normal file
11
oxdb/backend/urls.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
|
||||
urlpatterns = patterns("backend.views",
|
||||
(r'^upload/', 'firefogg_upload'),
|
||||
(r'^$', 'api'),
|
||||
)
|
||||
|
|
@ -356,7 +356,7 @@ def api_removeList(request):
|
|||
@login_required_json
|
||||
def api_addArchive(request):
|
||||
'''
|
||||
ARCHIVE API NEED CLEANUP
|
||||
ARCHIVE API NEEDS CLEANUP
|
||||
param data
|
||||
{name: string}
|
||||
return {'status': {'code': int, 'text': string},
|
||||
|
@ -376,7 +376,7 @@ def api_addArchive(request):
|
|||
@login_required_json
|
||||
def api_editArchive(request):
|
||||
'''
|
||||
ARCHIVE API NEED CLEANUP
|
||||
ARCHIVE API NEEDS CLEANUP
|
||||
param data
|
||||
{id: string, key: value,..}
|
||||
return {'status': {'code': int, 'text': string},
|
||||
|
@ -394,7 +394,7 @@ def api_editArchive(request):
|
|||
@login_required_json
|
||||
def api_removeArchive(request):
|
||||
'''
|
||||
ARCHIVE API NEED CLEANUP
|
||||
ARCHIVE API NEEDS CLEANUP
|
||||
param data
|
||||
string id
|
||||
|
||||
|
@ -454,10 +454,24 @@ def api_update(request):
|
|||
response = {'status': {'code': 403, 'text': 'permission denied'}}
|
||||
return render_to_json_response(response)
|
||||
|
||||
def api_encodingSettings(request):
|
||||
'''
|
||||
returns Firefogg encoding settings as specified by site
|
||||
return {'status': {'code': int, 'text': string},
|
||||
'data': {'options': {'videoQuality':...}}}
|
||||
'''
|
||||
response = {'status': {'code': 200, 'text': 'ok'}}
|
||||
response['data'] = {'options': {'preset': 'padma'}}
|
||||
return render_to_json_response(response)
|
||||
|
||||
class UploadForm(forms.Form):
|
||||
data = forms.TextInput()
|
||||
file = forms.FileField()
|
||||
|
||||
class VideoChunkForm(forms.Form):
|
||||
chunk = forms.FileField()
|
||||
done = forms.IntegerField(required=False)
|
||||
|
||||
def api_upload(request): #video, timeline, frame
|
||||
'''
|
||||
upload video, timeline or frame
|
||||
|
@ -466,7 +480,7 @@ def api_upload(request): #video, timeline, frame
|
|||
return {'status': {'code': int, 'text': string},
|
||||
'data': {}}
|
||||
'''
|
||||
form = LoginForm(request.POST, request.FILES)
|
||||
form = UploadForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
data = json.loads(request.POST['data'])
|
||||
if data['item'] == 'timeline':
|
||||
|
@ -476,6 +490,49 @@ def api_upload(request): #video, timeline, frame
|
|||
response = {'status': {'code': 501, 'text': 'not implemented'}}
|
||||
return render_to_json_response(response)
|
||||
|
||||
@login_required_json
|
||||
def firefogg_upload(request):
|
||||
#handle video upload
|
||||
if request.method == 'POST':
|
||||
#init upload
|
||||
if 'oshash' in request.POST:
|
||||
#FIXME: what to do if requested oshash is not in db?
|
||||
#FIXME: should existing data be reset here? or better, should this fail if an upload was there
|
||||
f = get_object_or_404(models.File, oshash=request.POST['oshash'])
|
||||
if f.stream128:
|
||||
f.stream128.delete()
|
||||
f.available = False
|
||||
f.save()
|
||||
response = {
|
||||
'uploadUrl': request.build_absolute_uri('/api/upload/?oshash=%s' % f.oshash),
|
||||
'result': 1
|
||||
}
|
||||
return render_to_json_response(response)
|
||||
#post next chunk
|
||||
if 'chunk' in request.FILES and 'oshash' in request.GET:
|
||||
print "all chunk now"
|
||||
f = get_object_or_404(models.File, oshash=request.GET['oshash'])
|
||||
form = VideoChunkForm(request.POST, request.FILES)
|
||||
#FIXME:
|
||||
if form.is_valid() and f.editable(request.user):
|
||||
c = form.cleaned_data['chunk']
|
||||
response = {
|
||||
'result': 1,
|
||||
'resultUrl': request.build_absolute_uri('/')
|
||||
}
|
||||
if not f.save_chunk(c, c.name):
|
||||
response['result'] = -1
|
||||
elif form.cleaned_data['done']:
|
||||
#FIXME: send message to encode deamon to create derivates instead
|
||||
f.available = True
|
||||
f.save()
|
||||
response['result'] = 1
|
||||
response['done'] = 1
|
||||
return render_to_json_response(response)
|
||||
print request.GET, request.POST
|
||||
response = {'status': {'code': 400, 'text': 'this request requires POST'}}
|
||||
return render_to_json_response(response)
|
||||
|
||||
@login_required_json
|
||||
def api_editFile(request): #FIXME: should this be file.files. or part of update
|
||||
'''
|
||||
|
|
|
@ -5,6 +5,19 @@ from django.db import models
|
|||
from django.contrib.auth.models import User
|
||||
from django.utils import simplejson as json
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.db.models import signals
|
||||
from django.dispatch import dispatcher
|
||||
|
||||
|
||||
class UserProfile(models.Model):
|
||||
recover_key = models.TextField()
|
||||
user = models.ForeignKey(User, unique=True)
|
||||
|
||||
def user_post_save(sender, instance, **kwargs):
|
||||
profile, new = UserProfile.objects.get_or_create(user=instance)
|
||||
|
||||
models.signals.post_save.connect(user_post_save, sender=User)
|
||||
|
||||
class Preference(models.Model):
|
||||
user = models.ForeignKey(User, related_name='preferences')
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
import uuid
|
||||
import hashlib
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
|
||||
from django.template import RequestContext
|
||||
from django.template import RequestContext, loader, Context
|
||||
from django.utils import simplejson as json
|
||||
from django import forms
|
||||
|
||||
|
@ -109,8 +111,19 @@ def api_recover(request):
|
|||
if q.count() > 0:
|
||||
user = q[0]
|
||||
if user:
|
||||
user.email_user('recovert','not yest, but soon you will be able to recover')
|
||||
#user.sendmail(...) #FIXME: send recovery mail
|
||||
key = hashlib.sha1(str(uuid.uuid4())).hexdigest()
|
||||
user_profile = user.get_profile()
|
||||
user_profile.recover_key = key
|
||||
user_profile.save()
|
||||
|
||||
template = loader.get_template('recover_mail.txt')
|
||||
context = RequestContext({
|
||||
'recover_url': request.build_absolute_uri("/r/%s" % key),
|
||||
'sitename': settings.SITENAME,
|
||||
})
|
||||
message = template.render(context)
|
||||
subject = '%s account recovery' % settings.SITENAME
|
||||
user.email_user(subject, message)
|
||||
response = {'status': {'code': 200, 'text': 'recover email sent.'}}
|
||||
else:
|
||||
response = {'status': {'code': 404, 'text': 'user or email not found.'}}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import os
|
||||
from os.path import join
|
||||
|
||||
SITENAME = 'Pad.ma'
|
||||
PROJECT_ROOT = os.path.normpath(os.path.dirname(__file__))
|
||||
|
||||
DEBUG = True
|
||||
|
@ -42,6 +43,7 @@ SITE_ID = 1
|
|||
# If you set this to False, Django will make some optimizations so as not
|
||||
# to load the internationalization machinery.
|
||||
USE_I18N = True
|
||||
APPEND_SLASH = False
|
||||
|
||||
# Absolute path to the directory that holds media.
|
||||
# Example: "/home/media/media.lawrence.com/"
|
||||
|
@ -95,6 +97,8 @@ INSTALLED_APPS = (
|
|||
'oxuser',
|
||||
)
|
||||
|
||||
AUTH_PROFILE_MODULE = 'oxuser.UserProfile'
|
||||
|
||||
#rabbitmq connection settings
|
||||
BROKER_HOST = "127.0.0.1"
|
||||
BROKER_PORT = 5672
|
||||
|
|
|
@ -10,7 +10,7 @@ admin.autodiscover()
|
|||
urlpatterns = patterns('',
|
||||
# Example:
|
||||
(r'^ajax_filtered_fields/', include('ajax_filtered_fields.urls')),
|
||||
(r'^api/', 'backend.views.api'),
|
||||
(r'^api/', include('backend.urls')),
|
||||
(r'^$', 'app.views.index'),
|
||||
|
||||
# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
|
||||
|
|
Loading…
Reference in a new issue