tune smart clip queries

This commit is contained in:
j 2015-04-25 16:13:42 +02:00
parent e604ba73bd
commit 9197591bb6
3 changed files with 77 additions and 53 deletions

View file

@ -68,32 +68,55 @@ class Edit(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
return ('/edits/%s' % quote(self.get_id())).replace('%3A', ':') return ('/edits/%s' % quote(self.get_id())).replace('%3A', ':')
def add_clip(self, data, index): def add_clip(self, data, index=None):
ids = [i['id'] for i in self.clips.order_by('index').values('id')] if index != None:
clip = Clip(edit=self) ids = [i['id'] for i in self.clips.order_by('index').values('id')]
c = Clip(edit=self)
if 'annotation' in data and data['annotation']: if 'annotation' in data and data['annotation']:
clip.annotation = Annotation.objects.get(public_id=data['annotation']) c.annotation = Annotation.objects.get(public_id=data['annotation'])
clip.item = clip.annotation.item c.item = c.annotation.item
else: else:
clip.item = Item.objects.get(public_id=data['item']) c.item = Item.objects.get(public_id=data['item'])
clip.start = data['in'] c.start = data['in']
clip.end = data['out'] c.end = data['out']
clip.index = index if index != None:
c.index = index
# dont add clip if in/out are invalid # dont add clip if in/out are invalid
if not clip.annotation: if not c.annotation:
duration = clip.item.sort.duration duration = c.item.sort.duration
if clip.start > clip.end \ if c.start > c.end \
or round(clip.start, 3) >= round(duration, 3) \ or round(c.start, 3) >= round(duration, 3) \
or round(clip.end, 3) > round(duration, 3): or round(c.end, 3) > round(duration, 3):
return False return False
clip.save() c.save()
ids.insert(index, clip.id) if index != None:
ids.insert(index, c.id)
self.sort_clips(ids)
return c
def add_clips(self, clips, index=None, user=None):
if index is None:
index = self.clips.count()
ids = [i['id'] for i in self.clips.order_by('index').values('id')]
added = []
with transaction.commit_on_success():
for data in clips:
c = self.add_clip(data)
if c:
ids.insert(index, c.id)
index += 1
added.append(c.json(user))
else:
return False
self.sort_clips(ids)
return added
def sort_clips(self, ids):
index = 0 index = 0
with transaction.commit_on_success(): with transaction.commit_on_success():
for i in ids: for i in ids:
Clip.objects.filter(id=i).update(index=index) Clip.objects.filter(id=i).update(index=index)
index += 1 index += 1
return clip
def accessible(self, user): def accessible(self, user):
return self.user == user or self.status in ('public', 'featured') return self.user == user or self.status in ('public', 'featured')
@ -203,8 +226,12 @@ class Edit(models.Model):
if self.type == 'static': if self.type == 'static':
clips = self.clips.all() clips = self.clips.all()
else: else:
clips = clip.models.Clip.objects.find({'query': self.clip_query()}, user) clips_query = self.clip_query()
clips = clips.filter(item__in=self.get_items(user)) if clips_query['conditions']:
clips = clip.models.Clip.objects.find({'query': clips_query}, user)
clips = clips.filter(item__in=self.get_items(user))
else:
clips = None
return clips return clips
def get_clips_json(self, user=None): def get_clips_json(self, user=None):
@ -212,15 +239,15 @@ class Edit(models.Model):
if self.type == 'static': if self.type == 'static':
clips = [c.json(user) for c in qs.order_by('index')] clips = [c.json(user) for c in qs.order_by('index')]
else: else:
if qs.count() <= 1000: if qs is None:
clips = []
else:
clips = [c.edit_json(user) for c in qs] clips = [c.edit_json(user) for c in qs]
index = 0 index = 0
for c in clips: for c in clips:
c['index'] = index c['index'] = index
index += 1 index += 1
else: return clips, qs
clips = []
return clips
def clip_query(self): def clip_query(self):
def get_conditions(conditions): def get_conditions(conditions):
@ -245,7 +272,7 @@ class Edit(models.Model):
frames = [] frames = []
if not self.poster_frames: if not self.poster_frames:
items = self.get_items(self.user).filter(rendered=True) items = self.get_items(self.user).filter(rendered=True)
if items.count(): if 0 < items.count() <= 1000:
poster_frames = [] poster_frames = []
for i in range(0, items.count(), max(1, int(items.count()/4))): for i in range(0, items.count(), max(1, int(items.count()/4))):
poster_frames.append({ poster_frames.append({
@ -320,21 +347,24 @@ class Edit(models.Model):
'posterFrames': 'poster_frames' 'posterFrames': 'poster_frames'
} }
if 'clips' in keys: if 'clips' in keys:
clips = self.get_clips_json(user) clips, clips_qs = self.get_clips_json(user)
clips_qs = self.get_clips(user) else:
clips_qs = self.get_clips(user)
for key in keys: for key in keys:
if key == 'id': if key == 'id':
response[key] = self.get_id() response[key] = self.get_id()
elif key == 'items': elif key == 'items':
response[key] = clips_qs.count() response[key] = 0 if clips_qs is None else clips_qs.count()
elif key == 'query': elif key == 'query':
if not self.query.get('static', False): if not self.query.get('static', False):
response[key] = self.query response[key] = self.query
elif key == 'clips': elif key == 'clips':
response[key] = clips response[key] = clips
elif key == 'duration': elif key == 'duration':
if self.type == 'static': if clips_qs is None:
response[key] = 0
elif self.type == 'static':
response[key] = sum([(c['annotation__end'] or c['end']) - (c['annotation__start'] or c['start']) response[key] = sum([(c['annotation__end'] or c['end']) - (c['annotation__start'] or c['start'])
for c in clips_qs.values('start', 'end', 'annotation__start', 'annotation__end')]) for c in clips_qs.values('start', 'end', 'annotation__start', 'annotation__end')])
else: else:

View file

@ -5,7 +5,6 @@ import os
import re import re
import ox import ox
from ox.utils import json
from ox.django.decorators import login_required_json from ox.django.decorators import login_required_json
from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response
from django.db import transaction from django.db import transaction
@ -54,16 +53,10 @@ def addClips(request, data):
edit = get_edit_or_404_json(data['edit']) edit = get_edit_or_404_json(data['edit'])
clips = [] clips = []
if edit.editable(request.user): if edit.editable(request.user):
index = data.get('index', edit.clips.count()) clips = edit.add_clips(data['clips'], data.get('index'), request.user)
with transaction.commit_on_success(): if not clips:
for c in data['clips']: response = json_response(status=500, text='invalid in/out')
clip = edit.add_clip(c, index) return render_to_json_response(response)
index += 1
if not clip:
response = json_response(status=500, text='invalid in/out')
return render_to_json_response(response)
else:
clips.append(clip.json(request.user))
add_changelog(request, data, edit.get_id()) add_changelog(request, data, edit.get_id())
response['data']['clips'] = clips response['data']['clips'] = clips
else: else:
@ -273,14 +266,10 @@ def addEdit(request, data):
edit.save() edit.save()
if 'clips' in data and edit.type == 'static': if 'clips' in data and edit.type == 'static':
index = 0 clips = edit.add_clips(data['clips'], 0, request.user)
with transaction.commit_on_success(): if not clips:
for c in data['clips']: response = json_response(status=500, text='invalid in/out')
clip = edit.add_clip(c, index) return render_to_json_response(response)
index += 1
if not clip:
response = json_response(status=500, text='invalid in/out')
return render_to_json_response(response)
if edit.status == 'featured': if edit.status == 'featured':
pos, created = models.Position.objects.get_or_create(edit=edit, pos, created = models.Position.objects.get_or_create(edit=edit,
@ -293,7 +282,11 @@ def addEdit(request, data):
pos.position = qs.aggregate(Max('position'))['position__max'] + 1 pos.position = qs.aggregate(Max('position'))['position__max'] + 1
pos.save() pos.save()
response = json_response(status=200, text='created') response = json_response(status=200, text='created')
response['data'] = edit.json(user=request.user) response['data'] = edit.json(user=request.user, keys=[
'description', 'editable', 'rightslevel',
'id', 'name', 'posterFrames', 'status',
'subscribed', 'user', 'type'
])
add_changelog(request, data, edit.get_id()) add_changelog(request, data, edit.get_id())
return render_to_json_response(response) return render_to_json_response(response)
actions.register(addEdit, cache=False) actions.register(addEdit, cache=False)
@ -321,7 +314,7 @@ def editEdit(request, data):
response['data'] = edit.json(keys=[ response['data'] = edit.json(keys=[
'description', 'editable', 'rightslevel', 'description', 'editable', 'rightslevel',
'id', 'name', 'posterFrames', 'status', 'id', 'name', 'posterFrames', 'status',
'subscribed', 'user' 'subscribed', 'user', 'type'
], user=request.user) ], user=request.user)
add_changelog(request, data, edit.get_id()) add_changelog(request, data, edit.get_id())
else: else:

View file

@ -133,7 +133,7 @@ pandora.addFolderItem = function(section) {
})), })),
operator: '|' operator: '|'
}; };
pandora.api.find({ (isItems ? pandora.api.find : Ox.noop)({
query: { query: {
conditions: [ conditions: [
{key: 'list', value: newList, operator: '=='} {key: 'list', value: newList, operator: '=='}
@ -144,9 +144,10 @@ pandora.addFolderItem = function(section) {
sort: [{key: sortKey, operator: ''}], sort: [{key: sortKey, operator: ''}],
range: [0, 4] range: [0, 4]
}, function(result) { }, function(result) {
var posterFrames = result.data.items.map(function(item) { var posterFrames = result
return {item: item.id, position: item.posterFrame}; ? result.data.items.map(function(item) {
}); return {item: item.id, position: item.posterFrame};
}) : [];
posterFrames = posterFrames.length == 1 posterFrames = posterFrames.length == 1
? Ox.repeat([posterFrames[0]], 4) ? Ox.repeat([posterFrames[0]], 4)
: posterFrames.length == 2 : posterFrames.length == 2