forked from 0x2620/pandora
merge
This commit is contained in:
commit
e53c6dfef3
8 changed files with 162 additions and 71 deletions
|
@ -261,28 +261,26 @@ class File(models.Model):
|
|||
if resolution == (0, 0):
|
||||
resolution = None
|
||||
duration = self.duration
|
||||
if self.get_type() != 'video':
|
||||
if self.type != 'video':
|
||||
duration = None
|
||||
data = {
|
||||
'audioCodec': self.audio_codec,
|
||||
'available': self.available,
|
||||
'duration': duration,
|
||||
'framerate': self.framerate,
|
||||
#'height': self.height,
|
||||
#'width': self.width,
|
||||
'resolution': resolution,
|
||||
'id': self.oshash,
|
||||
'samplerate': self.samplerate,
|
||||
'video_codec': self.video_codec,
|
||||
'audio_codec': self.audio_codec,
|
||||
'path': self.path,
|
||||
'size': self.size,
|
||||
#'info': self.info,
|
||||
'users': list(set([u.username
|
||||
for u in User.objects.filter(volumes__files__in=self.instances.all())])),
|
||||
'instances': [i.json() for i in self.instances.all()],
|
||||
'type': self.get_type(),
|
||||
'part': self.get_part()
|
||||
'part': self.part,
|
||||
'path': self.path,
|
||||
'resolution': resolution,
|
||||
'samplerate': self.samplerate,
|
||||
'selected': self.selected,
|
||||
'size': self.size,
|
||||
'type': self.type,
|
||||
'videoCodec': self.video_codec,
|
||||
'wanted': self.wanted,
|
||||
}
|
||||
data['users'] = [i['user'] for i in data['instances']]
|
||||
if keys:
|
||||
for k in data.keys():
|
||||
if k not in keys:
|
||||
|
@ -290,7 +288,6 @@ class File(models.Model):
|
|||
return data
|
||||
|
||||
def get_part(self):
|
||||
#FIXME: this breaks for sub/idx/srt
|
||||
if os.path.splitext(self.path)[-1] in ('.sub', '.idx', '.srt'):
|
||||
name = os.path.splitext(self.path)[0]
|
||||
if self.language:
|
||||
|
@ -298,7 +295,7 @@ class File(models.Model):
|
|||
qs = self.item.files.filter(Q(is_video=True)|Q(is_audio=True),
|
||||
selected=True, path__startswith=name)
|
||||
if qs.count()>0:
|
||||
return qs[0].part
|
||||
return qs[0].get_part()
|
||||
if self.selected:
|
||||
files = list(self.item.files.filter(type=self.type, language=self.language,
|
||||
selected=self.selected).order_by('sort_path'))
|
||||
|
@ -388,9 +385,10 @@ class Instance(models.Model):
|
|||
|
||||
def json(self):
|
||||
return {
|
||||
'ignore': self.ignore,
|
||||
'path': self.path,
|
||||
'user': self.volume.user.username,
|
||||
'volume': self.volume.name,
|
||||
'path': self.path
|
||||
}
|
||||
|
||||
def frame_path(frame, name):
|
||||
|
|
|
@ -7,7 +7,7 @@ from datetime import datetime
|
|||
from django import forms
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.conf import settings
|
||||
from django.db.models import Count, Sum
|
||||
from django.db.models import Count
|
||||
|
||||
import ox
|
||||
from ox.utils import json
|
||||
|
@ -288,7 +288,8 @@ def editFile(request):
|
|||
param data {
|
||||
id: hash of file
|
||||
part:
|
||||
id_extra: boolean
|
||||
language:
|
||||
ignore: boolean
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -297,17 +298,26 @@ def editFile(request):
|
|||
}
|
||||
}
|
||||
'''
|
||||
#FIXME: permissions, need to be checked
|
||||
data = json.loads(request.POST['data'])
|
||||
f = get_object_or_404_json(models.File, oshash=data['id'])
|
||||
response = json_response()
|
||||
if data.keys() != ('id', ):
|
||||
for key in data:
|
||||
if key in ('is_extra', 'is_subtitle', 'is_video', 'is_version',
|
||||
'part', 'language'):
|
||||
if f.editable(request.user):
|
||||
update = False
|
||||
#FIXME: should all instances be ignored?
|
||||
if 'ignore' in data:
|
||||
f.instances.update(ignore=True)
|
||||
#FIXME: is this to slow to run sync?
|
||||
f.item.update_selected()
|
||||
for key in ('part', 'language'):
|
||||
if key in data:
|
||||
setattr(f, key, data[key])
|
||||
f.auto = False
|
||||
f.save()
|
||||
f.auto = False
|
||||
update = True
|
||||
if update:
|
||||
f.save()
|
||||
response = json_response(status=200, text='updated')
|
||||
else:
|
||||
response = json_response(status=403, text='permissino denied')
|
||||
return render_to_json_response(response)
|
||||
actions.register(editFile, cache=False)
|
||||
|
||||
|
@ -415,8 +425,6 @@ Positions
|
|||
}
|
||||
'''
|
||||
data = json.loads(request.POST['data'])
|
||||
if settings.JSON_DEBUG:
|
||||
print json.dumps(data, indent=2)
|
||||
query = parse_query(data, request.user)
|
||||
|
||||
response = json_response({})
|
||||
|
|
|
@ -59,7 +59,7 @@ def get_id(info):
|
|||
if settings.DATA_SERVICE:
|
||||
r = external_data('getId', info)
|
||||
if r['status']['code'] == 200:
|
||||
imdbId = r['data']['imdbId']
|
||||
imdbId = r['data']['id']
|
||||
return imdbId
|
||||
return None
|
||||
|
||||
|
@ -542,6 +542,8 @@ class Item(models.Model):
|
|||
def set_value(s, name, value):
|
||||
if not value:
|
||||
value = None
|
||||
if isinstance(value, basestring):
|
||||
value = value.lower()
|
||||
setattr(s, name, value)
|
||||
|
||||
base_keys = (
|
||||
|
@ -553,7 +555,7 @@ class Item(models.Model):
|
|||
'lightness',
|
||||
'volume',
|
||||
'clips',
|
||||
'cuts',
|
||||
'numberofcuts',
|
||||
'cutsperminute',
|
||||
'words',
|
||||
'wordsperminute',
|
||||
|
@ -622,8 +624,8 @@ class Item(models.Model):
|
|||
|
||||
# sort values based on data from videos
|
||||
s.words = sum([len(a.value.split()) for a in self.annotations.all()])
|
||||
s.clips= self.clips.count()
|
||||
|
||||
s.clips = 0 #FIXME: get clips from all layers or something
|
||||
videos = self.files.filter(selected=True, is_video=True)
|
||||
if videos.count() > 0:
|
||||
s.duration = sum([v.duration for v in videos])
|
||||
|
@ -657,9 +659,9 @@ class Item(models.Model):
|
|||
s.hue = None
|
||||
s.saturation = None
|
||||
s.brighness = None
|
||||
s.cuts = len(self.data.get('cuts', []))
|
||||
s.numberofcuts = len(self.data.get('cuts', []))
|
||||
if s.duration:
|
||||
s.cutsperminute = s.cuts / (s.duration/60)
|
||||
s.cutsperminute = s.numberofcuts / (s.duration/60)
|
||||
s.wordsperminute = s.words / (s.duration / 60)
|
||||
else:
|
||||
s.cutsperminute = None
|
||||
|
@ -667,7 +669,6 @@ class Item(models.Model):
|
|||
s.popularity = self.accessed.aggregate(Sum('accessed'))['accessed__sum']
|
||||
s.save()
|
||||
|
||||
|
||||
def update_facets(self):
|
||||
#FIXME: what to do with Unkown Director, Year, Country etc.
|
||||
for key in self.facet_keys + ['title']:
|
||||
|
@ -735,8 +736,10 @@ class Item(models.Model):
|
|||
return os.path.join(settings.MEDIA_ROOT, self.path(), 'timeline')
|
||||
|
||||
def get_files(self, user):
|
||||
#FIXME: limit by user
|
||||
return [f.json() for f in self.files.all()]
|
||||
files = self.files.all().select_related()
|
||||
if user.get_profile().get_level() != 'admin':
|
||||
files = files.filter(instances__volume__user=user)
|
||||
return [f.json() for f in files]
|
||||
|
||||
def users_with_files(self):
|
||||
return User.objects.filter(
|
||||
|
@ -764,6 +767,7 @@ class Item(models.Model):
|
|||
for s in self.sets():
|
||||
if s.filter(Q(is_video=True)|Q(is_audio=True)).filter(available=False).count() == 0:
|
||||
update = False
|
||||
self.files.exclude(id__in=s).exclude(part=None).update(part=None)
|
||||
deselect = self.files.filter(selected=True).exclude(id__in=s)
|
||||
if deselect.count() > 0:
|
||||
deselect.update(selected=False)
|
||||
|
@ -771,6 +775,10 @@ class Item(models.Model):
|
|||
if s.filter(selected=False).count() > 0:
|
||||
s.update(selected=True, wanted=False)
|
||||
update = True
|
||||
for f in s:
|
||||
if f.get_part() != f.part:
|
||||
f.save()
|
||||
update = True
|
||||
if update:
|
||||
self.rendered = False
|
||||
self.save()
|
||||
|
|
|
@ -326,6 +326,38 @@ def autocomplete(request):
|
|||
return render_to_json_response(response)
|
||||
actions.register(autocomplete)
|
||||
|
||||
def findId(request):
|
||||
'''
|
||||
param data {
|
||||
'query': query,
|
||||
'sort': array,
|
||||
'range': array
|
||||
}
|
||||
|
||||
'''
|
||||
data = json.loads(request.POST['data'])
|
||||
response = json_response({})
|
||||
response['data']['items'] = []
|
||||
'''
|
||||
FIXME: can not handle query for director []
|
||||
query = parse_query(data, request.user)
|
||||
qs = _order_query(query['qs'], query['sort'])
|
||||
if qs.count() == 1:
|
||||
response['data']['items'] = [i.get_json(data['keys']) for i in qs]
|
||||
elif settings.DATA_SERVICE:
|
||||
'''
|
||||
if settings.DATA_SERVICE:
|
||||
'''
|
||||
info = {}
|
||||
for c in data['query']['conditions']:
|
||||
info[c['key']] = c['value']
|
||||
r = models.external_data('getId', info)
|
||||
'''
|
||||
r = models.external_data('getId', data)
|
||||
if r['status']['code'] == 200:
|
||||
response['data']['items'] = [r['data']]
|
||||
return render_to_json_response(response)
|
||||
actions.register(findId)
|
||||
|
||||
def get(request):
|
||||
'''
|
||||
|
|
|
@ -33,11 +33,6 @@ class UserProfile(models.Model):
|
|||
info = DictField(default={})
|
||||
notes = models.TextField(default='')
|
||||
|
||||
def get_preferences(self):
|
||||
prefs = self.preferences
|
||||
prefs['email'] = self.user.email
|
||||
return prefs
|
||||
|
||||
def get_ui(self):
|
||||
return get_ui(self.ui, self.user)
|
||||
|
||||
|
@ -154,7 +149,7 @@ def init_user(user, request=None):
|
|||
result[key] = getattr(user, key)
|
||||
result['level'] = profile.get_level()
|
||||
result['groups'] = [g.name for g in user.groups.all()]
|
||||
result['preferences'] = profile.get_preferences()
|
||||
result['email'] = user.email
|
||||
result['ui'] = profile.get_ui()
|
||||
result['volumes'] = [v.json() for v in user.volumes.all()]
|
||||
return result
|
||||
|
|
|
@ -577,29 +577,34 @@ def getPositionById(list, key):
|
|||
|
||||
|
||||
@login_required_json
|
||||
def setPreferences(request):
|
||||
def editPreferences(request):
|
||||
'''
|
||||
param data {
|
||||
key.subkey: value
|
||||
key: value
|
||||
}
|
||||
keys: email, password
|
||||
return
|
||||
'''
|
||||
data = json.loads(request.POST['data'])
|
||||
keys = re.sub('([^\\\\])\.', '\\1\n', data.keys()[0]).split('\n')
|
||||
value = data.values()[0]
|
||||
profile = request.user.get_profile()
|
||||
p = profile.preferences
|
||||
while len(keys)>1:
|
||||
key = keys.pop(0)
|
||||
if isinstance(p, list):
|
||||
p = p[getPositionById(p, key)]
|
||||
else:
|
||||
p = p[key]
|
||||
p[keys[0]] = value
|
||||
profile.save()
|
||||
errors = {}
|
||||
change = False
|
||||
response = json_response()
|
||||
if 'email' in data:
|
||||
if models.User.objects.filter(
|
||||
email=data['email']).exclude(username=request.user.username).count()>0:
|
||||
errors['email'] = 'Email address already in use'
|
||||
else:
|
||||
change = True
|
||||
request.user.email = data['email']
|
||||
if 'password' in data:
|
||||
change = True
|
||||
request.user.password = data['password']
|
||||
if change:
|
||||
request.user.save()
|
||||
if errors:
|
||||
response = json_response({ 'errors': errors})
|
||||
return render_to_json_response(response)
|
||||
actions.register(setPreferences, cache=False)
|
||||
actions.register(editPreferences, cache=False)
|
||||
|
||||
|
||||
def resetUI(request):
|
||||
|
|
|
@ -45,13 +45,36 @@ pandora.ui.filesView = function(options, self) {
|
|||
|
||||
self.$filesList = Ox.TextList({
|
||||
columns: [
|
||||
{
|
||||
format: function(value, data) {
|
||||
Ox.print('File', value, data.wanted, data);
|
||||
return $('<img>')
|
||||
.attr({
|
||||
src: data.wanted ? Ox.UI.getImageURL('symbolStar') :
|
||||
Ox.UI.getImageURL('symbolCheck')
|
||||
})
|
||||
.css({
|
||||
width: '10px',
|
||||
height: '10px',
|
||||
padding: '3px',
|
||||
opacity: (value || data.wanted) ? 1 : 0
|
||||
});
|
||||
},
|
||||
id: 'selected',
|
||||
operator: '-',
|
||||
title: $('<img>').attr({
|
||||
src: Ox.UI.getImageURL('symbolCheck')
|
||||
}),
|
||||
visible: true,
|
||||
width: 16
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
id: 'users',
|
||||
operator: '+',
|
||||
title: 'Users',
|
||||
visible: true,
|
||||
width: 120
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
|
@ -133,11 +156,12 @@ pandora.ui.filesView = function(options, self) {
|
|||
conditions: [{
|
||||
key: 'id',
|
||||
value: self.options.id,
|
||||
operator: '='
|
||||
operator: '=='
|
||||
}]
|
||||
}
|
||||
}), callback);
|
||||
},
|
||||
keys: ['wanted'],
|
||||
scrollbarVisible: true,
|
||||
sort: [{key: 'path', operator: '+'}]
|
||||
})
|
||||
|
@ -202,13 +226,14 @@ pandora.ui.filesView = function(options, self) {
|
|||
change: function(data) {
|
||||
var conditions;
|
||||
if (data.value.length) {
|
||||
/*
|
||||
if (key == 'id') {
|
||||
conditions = [{key: 'id', value: data.value, operator: '='}]
|
||||
conditions = [{key: 'id', value: data.value, operator: '=='}]
|
||||
} else {
|
||||
conditions = Ox.map(['title', 'director', 'year'], function(key) {
|
||||
var value = self['$' + key + 'Input'].options('value')
|
||||
return value.length ? {key: key, value: value, operator: '='} : null;
|
||||
})
|
||||
});
|
||||
}
|
||||
pandora.api.find({
|
||||
keys: ['title', 'director', 'year', 'id'],
|
||||
|
@ -218,6 +243,15 @@ pandora.ui.filesView = function(options, self) {
|
|||
},
|
||||
range: [0, 2]
|
||||
}, function(result) {
|
||||
*/
|
||||
conditions = {};
|
||||
Ox.map(['id', 'title', 'director', 'year'], function(key) {
|
||||
var value = self['$' + key + 'Input'].options('value');
|
||||
if(value.length) {
|
||||
conditions[key] = value;
|
||||
}
|
||||
});
|
||||
pandora.api.findId(conditions, function(result) {
|
||||
var length = result.data.items.length;
|
||||
if (length == 0) {
|
||||
if (key != 'id') {
|
||||
|
@ -234,7 +268,7 @@ pandora.ui.filesView = function(options, self) {
|
|||
} else {
|
||||
self.$idInput.options({value: ''});
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -345,6 +379,7 @@ pandora.ui.filesView = function(options, self) {
|
|||
}
|
||||
});
|
||||
updateForm();
|
||||
self.$titleInput.triggerEvent('change', {value: result.data['title']});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||
pandora.ui.status = function(key, data) {
|
||||
var that = Ox.toTitleCase(key) + ': ' + [
|
||||
Ox.formatNumber(data.items) + ' '+ (data.items != 1 ? pandora.site.itemName.plural : pandora.site.itemName.singular),
|
||||
Ox.formatDuration(data.runtime, 'short'),
|
||||
data.files + ' file' + (data.files != 1 ? 's' : ''),
|
||||
Ox.formatDuration(data.duration),
|
||||
Ox.formatValue(data.size, 'B'),
|
||||
Ox.formatValue(data.pixels, 'px')
|
||||
].join(', ');
|
||||
return that;
|
||||
var itemName = data.items != 1 ? pandora.site.itemName.plural : pandora.site.itemName.singular,
|
||||
segments = [],
|
||||
that = Ox.toTitleCase(key) + ': ';
|
||||
if (!pandora.user.ui.item && pandora.user.ui.listView == 'clip') {
|
||||
itemName = data.items != 1 ? 'Clips' : 'Clip';
|
||||
}
|
||||
|
||||
segments.push(Ox.formatNumber(data.items) + ' '+ itemName);
|
||||
if (data.runtime)
|
||||
segments.push(Ox.formatDuration(data.runtime, 'short'));
|
||||
if (data.files)
|
||||
segments.push(data.files + ' file' + (data.files != 1 ? 's' : ''));
|
||||
if (data.duration)
|
||||
segments.push(Ox.formatDuration(data.duration));
|
||||
if (data.size)
|
||||
segments.push(Ox.formatValue(data.size, 'B'));
|
||||
if (data.pixels)
|
||||
segments.push(Ox.formatValue(data.pixels, 'px'));
|
||||
return that + segments.join(', ');
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue