From 9197591bb69c37d733b26f151d975f60b01aab65 Mon Sep 17 00:00:00 2001 From: j <0x006A@0x2620.org> Date: Sat, 25 Apr 2015 16:13:42 +0200 Subject: [PATCH] tune smart clip queries --- pandora/edit/models.py | 86 ++++++++++++++++++++++++++++-------------- pandora/edit/views.py | 35 +++++++---------- static/js/utils.js | 9 +++-- 3 files changed, 77 insertions(+), 53 deletions(-) diff --git a/pandora/edit/models.py b/pandora/edit/models.py index 9a7c66cc..96e52445 100644 --- a/pandora/edit/models.py +++ b/pandora/edit/models.py @@ -68,32 +68,55 @@ class Edit(models.Model): def get_absolute_url(self): return ('/edits/%s' % quote(self.get_id())).replace('%3A', ':') - def add_clip(self, data, index): - ids = [i['id'] for i in self.clips.order_by('index').values('id')] - clip = Clip(edit=self) + def add_clip(self, data, index=None): + if index != None: + ids = [i['id'] for i in self.clips.order_by('index').values('id')] + c = Clip(edit=self) if 'annotation' in data and data['annotation']: - clip.annotation = Annotation.objects.get(public_id=data['annotation']) - clip.item = clip.annotation.item + c.annotation = Annotation.objects.get(public_id=data['annotation']) + c.item = c.annotation.item else: - clip.item = Item.objects.get(public_id=data['item']) - clip.start = data['in'] - clip.end = data['out'] - clip.index = index + c.item = Item.objects.get(public_id=data['item']) + c.start = data['in'] + c.end = data['out'] + if index != None: + c.index = index # dont add clip if in/out are invalid - if not clip.annotation: - duration = clip.item.sort.duration - if clip.start > clip.end \ - or round(clip.start, 3) >= round(duration, 3) \ - or round(clip.end, 3) > round(duration, 3): + if not c.annotation: + duration = c.item.sort.duration + if c.start > c.end \ + or round(c.start, 3) >= round(duration, 3) \ + or round(c.end, 3) > round(duration, 3): return False - clip.save() - ids.insert(index, clip.id) + c.save() + 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 with transaction.commit_on_success(): for i in ids: Clip.objects.filter(id=i).update(index=index) index += 1 - return clip def accessible(self, user): return self.user == user or self.status in ('public', 'featured') @@ -203,8 +226,12 @@ class Edit(models.Model): if self.type == 'static': clips = self.clips.all() else: - clips = clip.models.Clip.objects.find({'query': self.clip_query()}, user) - clips = clips.filter(item__in=self.get_items(user)) + clips_query = self.clip_query() + 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 def get_clips_json(self, user=None): @@ -212,15 +239,15 @@ class Edit(models.Model): if self.type == 'static': clips = [c.json(user) for c in qs.order_by('index')] else: - if qs.count() <= 1000: + if qs is None: + clips = [] + else: clips = [c.edit_json(user) for c in qs] index = 0 for c in clips: c['index'] = index index += 1 - else: - clips = [] - return clips + return clips, qs def clip_query(self): def get_conditions(conditions): @@ -245,7 +272,7 @@ class Edit(models.Model): frames = [] if not self.poster_frames: items = self.get_items(self.user).filter(rendered=True) - if items.count(): + if 0 < items.count() <= 1000: poster_frames = [] for i in range(0, items.count(), max(1, int(items.count()/4))): poster_frames.append({ @@ -320,21 +347,24 @@ class Edit(models.Model): 'posterFrames': 'poster_frames' } if 'clips' in keys: - clips = self.get_clips_json(user) - clips_qs = self.get_clips(user) + clips, clips_qs = self.get_clips_json(user) + else: + clips_qs = self.get_clips(user) for key in keys: if key == 'id': response[key] = self.get_id() elif key == 'items': - response[key] = clips_qs.count() + response[key] = 0 if clips_qs is None else clips_qs.count() elif key == 'query': if not self.query.get('static', False): response[key] = self.query elif key == 'clips': response[key] = clips 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']) for c in clips_qs.values('start', 'end', 'annotation__start', 'annotation__end')]) else: diff --git a/pandora/edit/views.py b/pandora/edit/views.py index e9a9556d..46cb89a5 100644 --- a/pandora/edit/views.py +++ b/pandora/edit/views.py @@ -5,7 +5,6 @@ import os import re import ox -from ox.utils import 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 django.db import transaction @@ -54,16 +53,10 @@ def addClips(request, data): edit = get_edit_or_404_json(data['edit']) clips = [] if edit.editable(request.user): - index = data.get('index', edit.clips.count()) - with transaction.commit_on_success(): - for c in data['clips']: - clip = edit.add_clip(c, index) - 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)) + clips = edit.add_clips(data['clips'], data.get('index'), request.user) + if not clips: + response = json_response(status=500, text='invalid in/out') + return render_to_json_response(response) add_changelog(request, data, edit.get_id()) response['data']['clips'] = clips else: @@ -273,14 +266,10 @@ def addEdit(request, data): edit.save() if 'clips' in data and edit.type == 'static': - index = 0 - with transaction.commit_on_success(): - for c in data['clips']: - clip = edit.add_clip(c, index) - index += 1 - if not clip: - response = json_response(status=500, text='invalid in/out') - return render_to_json_response(response) + clips = edit.add_clips(data['clips'], 0, request.user) + if not clips: + response = json_response(status=500, text='invalid in/out') + return render_to_json_response(response) if edit.status == 'featured': 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.save() 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()) return render_to_json_response(response) actions.register(addEdit, cache=False) @@ -321,7 +314,7 @@ def editEdit(request, data): response['data'] = edit.json(keys=[ 'description', 'editable', 'rightslevel', 'id', 'name', 'posterFrames', 'status', - 'subscribed', 'user' + 'subscribed', 'user', 'type' ], user=request.user) add_changelog(request, data, edit.get_id()) else: diff --git a/static/js/utils.js b/static/js/utils.js index 45c98eaa..afc3ddb6 100644 --- a/static/js/utils.js +++ b/static/js/utils.js @@ -133,7 +133,7 @@ pandora.addFolderItem = function(section) { })), operator: '|' }; - pandora.api.find({ + (isItems ? pandora.api.find : Ox.noop)({ query: { conditions: [ {key: 'list', value: newList, operator: '=='} @@ -144,9 +144,10 @@ pandora.addFolderItem = function(section) { sort: [{key: sortKey, operator: ''}], range: [0, 4] }, function(result) { - var posterFrames = result.data.items.map(function(item) { - return {item: item.id, position: item.posterFrame}; - }); + var posterFrames = result + ? result.data.items.map(function(item) { + return {item: item.id, position: item.posterFrame}; + }) : []; posterFrames = posterFrames.length == 1 ? Ox.repeat([posterFrames[0]], 4) : posterFrames.length == 2