forked from 0x2620/pandora
recover account, email in preferences
This commit is contained in:
parent
76368153ba
commit
c964ffaa71
7 changed files with 136 additions and 48 deletions
|
@ -5,6 +5,7 @@ from django.conf import settings
|
|||
import load
|
||||
import models
|
||||
|
||||
|
||||
def send_encoder_message(msg):
|
||||
conn = DjangoBrokerConnection()
|
||||
publisher = Publisher(connection=conn, exchange="oxdb-encoder",
|
||||
|
|
|
@ -964,6 +964,8 @@ class List(models.Model):
|
|||
|
||||
def editable(self, user):
|
||||
#FIXME: make permissions work
|
||||
if self.user == user or user.has_perm('Ox.admin'):
|
||||
return True
|
||||
return False
|
||||
|
||||
class ListItem(models.Model):
|
||||
|
@ -978,12 +980,18 @@ 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], url_hash, name)
|
||||
return os.path.join(url_hash[:2], url_hash[2:4], url_hash[4:6], url_hash, name)
|
||||
|
||||
def still_path(f, still):
|
||||
name = "%s.%s" % (still, 'png')
|
||||
def timeline_path(f):
|
||||
name = "timeline.png"
|
||||
url_hash = f.oshash
|
||||
return os.path.join('still', url_hash[:2], url_hash[2:4], url_hash[4:6], name)
|
||||
return os.path.join(url_hash[:2], url_hash[2:4], url_hash[4:6], url_hash, name)
|
||||
|
||||
def frame_path(f):
|
||||
position = oxlib.formatTime(f.position*1000).replace(':', '.')
|
||||
name = "%s.%s" % (position, 'png')
|
||||
url_hash = f.file.oshash
|
||||
return os.path.join(url_hash[:2], url_hash[2:4], url_hash[4:6], url_hash, name)
|
||||
|
||||
FILE_TYPES = (
|
||||
(0, 'unknown'),
|
||||
|
@ -1039,7 +1047,7 @@ class File(models.Model):
|
|||
stream320 = models.FileField(default=None, upload_to=lambda f, x: stream_path(f, '320'))
|
||||
stream640 = models.FileField(default=None, upload_to=lambda f, x: stream_path(f, '640'))
|
||||
|
||||
timeline = models.ImageField(default=None, null=True, upload_to=lambda f, x: still_path(f, '0'))
|
||||
timeline = models.ImageField(default=None, null=True, upload_to=lambda f, x: timeline_path(f))
|
||||
|
||||
def save_chunk(self, chunk, name='video.ogv'):
|
||||
if not self.available:
|
||||
|
@ -1105,24 +1113,69 @@ class File(models.Model):
|
|||
self.movie = getMovie(info)
|
||||
self.save()
|
||||
|
||||
def extract_timeline(self):
|
||||
if self.stream640:
|
||||
video = self.stream640.path
|
||||
elif stream320:
|
||||
video = self.stream320.path
|
||||
elif stream128:
|
||||
video = self.stream128.path
|
||||
else:
|
||||
return False
|
||||
prefix = os.path.join(os.path.dirname(video), 'timeline')
|
||||
cmd = ['oxtimeline', '-i', video, '-o', prefix]
|
||||
p = subprocess.Popen(cmd)
|
||||
p.wait()
|
||||
return p.returncode == 0
|
||||
|
||||
def extract_video(self):
|
||||
ogg = Firefogg()
|
||||
if self.stream640:
|
||||
#320 stream
|
||||
self.stream320.name = stream_path(self, '320')
|
||||
self.stream320.save()
|
||||
ogg.encode(self.stream640.path, self.stream320.path, settings.VIDEO320)
|
||||
#128 stream
|
||||
self.stream128.name = stream_path(self, '128')
|
||||
self.stream128.save()
|
||||
ogg.encode(self.stream640.path, self.stream128.path, settings.VIDEO128)
|
||||
elif self.stream320:
|
||||
self.stream128.name = stream_path(self, '128')
|
||||
self.stream128.save()
|
||||
ogg.encode(self.stream320.path, self.stream128.path, settings.VIDEO128)
|
||||
|
||||
def extract(self):
|
||||
#FIXME: do stuff, like create timeline or create smaller videos etc
|
||||
self.extract_video()
|
||||
self.extract_timeline()
|
||||
return
|
||||
|
||||
def editable(self, user):
|
||||
#FIXME: make permissions work
|
||||
return True
|
||||
'''
|
||||
#FIXME: this should use a queryset!!!
|
||||
archives = []
|
||||
for a in self.archive_files.all():
|
||||
archives.append(a.archive)
|
||||
users = []
|
||||
for a in archives:
|
||||
users += a.users.all()
|
||||
return user in users
|
||||
'''
|
||||
return self.archive_files.filter(archive__users__id=user.id).count() > 0
|
||||
|
||||
class Still(models.Model):
|
||||
class Frame(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
file = models.ForeignKey(File, related_name="stills")
|
||||
file = models.ForeignKey(File, related_name="frames")
|
||||
position = models.FloatField()
|
||||
still = models.ImageField(default=None, null=True, upload_to=lambda f, x: still_path(f, '0'))
|
||||
frame = models.ImageField(default=None, null=True, upload_to=lambda f, x: frame_path(f))
|
||||
|
||||
#FIXME: frame path should be renamed on save to match current position
|
||||
|
||||
def __unicode__(self):
|
||||
return '%s at %s' % (self.file, self.position)
|
||||
|
||||
|
||||
class Layer(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
|
@ -1140,10 +1193,13 @@ class Layer(models.Model):
|
|||
#location = models.ForeignKey('Location', default=None)
|
||||
|
||||
def editable(self, user):
|
||||
#FIXME: make permissions work
|
||||
if user.is_authenticated():
|
||||
if obj.user == user.id or user.has_perm('0x.admin'):
|
||||
return True
|
||||
if user.groups.filter(id__in=obj.groups.all()).count() > 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Archive(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
|
@ -1162,7 +1218,7 @@ class ArchiveFile(models.Model):
|
|||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
archive = models.ForeignKey(Archive, related_name='files')
|
||||
file = models.ForeignKey(File)
|
||||
file = models.ForeignKey(File, related_name='archive_files')
|
||||
path = models.CharField(blank=True, max_length=2048)
|
||||
|
||||
objects = managers.ArchiveFileManager()
|
||||
|
@ -1189,10 +1245,16 @@ class ArchiveFile(models.Model):
|
|||
def __unicode__(self):
|
||||
return '%s (%s)' % (self.path, unicode(self.archive))
|
||||
|
||||
def editable(self, user):
|
||||
return self.archive.editable(user)
|
||||
|
||||
class Collection(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
users = models.ManyToManyField(User, related_name='collections')
|
||||
name = models.CharField(blank=True, max_length=2048)
|
||||
subdomain = models.CharField(unique=True, max_length=2048)
|
||||
movies = models.ForeignKey(Movie)
|
||||
|
||||
def editable(self, user):
|
||||
return self.users.filter(id=user.id).count() > 0
|
||||
|
|
|
@ -484,7 +484,18 @@ def api_upload(request): #video, timeline, frame
|
|||
'''
|
||||
form = UploadForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
data = json.loads(request.POST['data'])
|
||||
data = json.loads(form.cleaned_data['data'])
|
||||
oshash = data['oshash']
|
||||
f = get_object_or_404(models.File, oshash=oshash)
|
||||
if data['item'] == 'frame':
|
||||
ff = form.cleaned_data['file']
|
||||
position = data['position']
|
||||
frame = models.Frame.objects.get_or_create(file=f, position=position)
|
||||
frame.frame.save(ff.name, ff)
|
||||
frame.save()
|
||||
response = {'status': {'code': 200, 'text': 'ok'}}
|
||||
response['url'] = still.url()
|
||||
return render_to_json_response(response)
|
||||
if data['item'] == 'timeline':
|
||||
pass
|
||||
#print "not implemented"
|
||||
|
@ -652,26 +663,6 @@ def find_files(request):
|
|||
response['files'][f.movie_file.oshash] = {'path': f.path, 'size': f.movie_file.size}
|
||||
return render_to_json_response(response)
|
||||
|
||||
class StillForm(forms.Form):
|
||||
still = forms.FileField()
|
||||
position = forms.FloatField()
|
||||
|
||||
#@login_required_json
|
||||
def add_still(request, oshash):
|
||||
response = {'status': 500}
|
||||
f = get_object_or_404(models.File, oshash=oshash)
|
||||
|
||||
form = TimelineForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
ff = form.cleaned_data['still']
|
||||
position = form.cleaned_data['position']
|
||||
|
||||
still = models.Still(file=f, position=position)
|
||||
still.save()
|
||||
still.still.save(ff, ff.name)
|
||||
response = {'status': 200}
|
||||
response['url'] = still.url()
|
||||
return render_to_json_response(response)
|
||||
|
||||
class TimelineForm(forms.Form):
|
||||
timeline = forms.FileField()
|
||||
|
|
|
@ -26,7 +26,7 @@ class Preference(models.Model):
|
|||
|
||||
def getUserJSON(user):
|
||||
json = {}
|
||||
for key in ('username', 'email'):
|
||||
for key in ('username', ):
|
||||
json[key] = getattr(user, key)
|
||||
json['preferences'] = getPreferences(user)
|
||||
return json
|
||||
|
@ -35,19 +35,29 @@ def getPreferences(user):
|
|||
prefs = {}
|
||||
for p in Preference.objects.filter(user=user):
|
||||
prefs[p.key] = json.loads(p.value)
|
||||
prefs['email'] = user.email
|
||||
return prefs
|
||||
|
||||
def getPreference(user, key, value=None):
|
||||
q = Preference.objects.filter(user=user, key=key)
|
||||
if q.count() > 0:
|
||||
value = json.loads(q[0].value)
|
||||
if key in ('email', ):
|
||||
value = getattr(user, key)
|
||||
else:
|
||||
q = Preference.objects.filter(user=user, key=key)
|
||||
if q.count() > 0:
|
||||
value = json.loads(q[0].value)
|
||||
return value
|
||||
|
||||
def setPreference(user, key, value):
|
||||
value = json.dumps(value)
|
||||
q = Preference.objects.filter(user=user, key=key)
|
||||
if q.count() > 0:
|
||||
q[0].value = value
|
||||
if key in ('email', ):
|
||||
setattr(user, key, value)
|
||||
user.save()
|
||||
else:
|
||||
p = Preference(user=user, key=key, value=value)
|
||||
p.save()
|
||||
value = json.dumps(value)
|
||||
q = Preference.objects.filter(user=user, key=key)
|
||||
if q.count() > 0:
|
||||
p = q[0]
|
||||
p.value = value
|
||||
p.save()
|
||||
else:
|
||||
p = Preference(user=user, key=key, value=value)
|
||||
p.save()
|
||||
|
|
|
@ -6,9 +6,10 @@ import hashlib
|
|||
from django import forms
|
||||
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.shortcuts import render_to_response, get_object_or_404, get_list_or_404, redirect
|
||||
from django.template import RequestContext, loader, Context
|
||||
from django.utils import simplejson as json
|
||||
from django.conf import settings
|
||||
|
||||
from oxdjango.shortcuts import render_to_json_response
|
||||
from oxdjango.decorators import login_required_json
|
||||
|
@ -116,8 +117,8 @@ def api_recover(request):
|
|||
user_profile.recover_key = key
|
||||
user_profile.save()
|
||||
|
||||
template = loader.get_template('recover_mail.txt')
|
||||
context = RequestContext({
|
||||
template = loader.get_template('recover_email.txt')
|
||||
context = RequestContext(request, {
|
||||
'recover_url': request.build_absolute_uri("/r/%s" % key),
|
||||
'sitename': settings.SITENAME,
|
||||
})
|
||||
|
@ -131,6 +132,22 @@ def api_recover(request):
|
|||
response = {'status': {'code': 400, 'text': 'username exists'}}
|
||||
return render_to_json_response(response)
|
||||
|
||||
def recover(request, key):
|
||||
qs = models.UserProfile.objects.filter(recover_key=key)
|
||||
if qs.count() == 1:
|
||||
user = qs[0].user
|
||||
user.set_password(key)
|
||||
user.save()
|
||||
user_profile = user.get_profile()
|
||||
user_profile.recover_key = ''
|
||||
user_profile.save()
|
||||
user = authenticate(username=user.username, password=key)
|
||||
login(request, user)
|
||||
|
||||
#FIXME: set message to notify user to update password
|
||||
return redirect('/#settings')
|
||||
return redirect('/')
|
||||
|
||||
@login_required_json
|
||||
def api_preferences(request):
|
||||
'''
|
||||
|
|
|
@ -12,9 +12,11 @@ TEMPLATE_DEBUG = DEBUG
|
|||
JSON_DEBUG = False
|
||||
|
||||
ADMINS = (
|
||||
# ('Your Name', 'your_email@domain.com'),
|
||||
('j', 'j@mailb.org'),
|
||||
)
|
||||
|
||||
DEFAULT_FROM_EMAIL='bot@0xdb.org'
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
|
||||
|
@ -106,6 +108,10 @@ BROKER_USER = "oxdb"
|
|||
BROKER_PASSWORD = "0xdb"
|
||||
BROKER_VHOST = "/oxdb"
|
||||
|
||||
#Video encoding settings
|
||||
VIDEO128 = {'profile': 'padma-stream', 'samplerate': 44100, 'noUpscaling': True}
|
||||
VIDEO320 = {'maxSize': 320, 'samplerate': 44100, 'videoBitrate': 500, 'audioQuality': 0, 'channels': 1, 'noUpscaling': True}
|
||||
VIDEO640 = {'profile': 'padma'}
|
||||
|
||||
#overwrite default settings with local settings
|
||||
try:
|
||||
|
|
|
@ -12,6 +12,7 @@ urlpatterns = patterns('',
|
|||
(r'^ajax_filtered_fields/', include('ajax_filtered_fields.urls')),
|
||||
(r'^api/', include('backend.urls')),
|
||||
(r'^$', 'app.views.index'),
|
||||
(r'^r/(?P<key>.*)$', 'oxuser.views.recover'),
|
||||
|
||||
# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
|
||||
# to INSTALLED_APPS to enable admin documentation:
|
||||
|
|
Loading…
Reference in a new issue