From 09389f84dcaf08bb2f6f3dd15d5332f099d0f4e4 Mon Sep 17 00:00:00 2001 From: j <0x006A@0x2620.org> Date: Thu, 5 Jan 2012 18:01:56 +0530 Subject: [PATCH] only return matching annotations in findClips if query contains annotation conditions --- pandora/clip/managers.py | 35 ++++++++++++++++++++++++++++++++++ pandora/clip/models.py | 7 +++++-- pandora/clip/views.py | 4 +++- pandora/item/views.py | 4 +++- static/js/pandora/clipsView.js | 9 ++++++--- 5 files changed, 52 insertions(+), 7 deletions(-) diff --git a/pandora/clip/managers.py b/pandora/clip/managers.py index 513036b04..7b7f0929f 100644 --- a/pandora/clip/managers.py +++ b/pandora/clip/managers.py @@ -28,6 +28,7 @@ def parseCondition(condition, user): 'out': 'end', 'place': 'annotations__places__id', 'text': 'annotations__findvalue', + 'annotations': 'annotations__findvalue', 'user': 'annotations__user__username', }.get(k, k) if not k: @@ -139,6 +140,40 @@ class ClipManager(Manager): def get_query_set(self): return QuerySet(self.model) + def filter_annotations(self, data, user): + public_layers = [l['id'] + for l in filter(lambda l: not l.get('private', False), + settings.CONFIG['layers'])] + keys = public_layers + ['annotations', 'text', '*'] + conditions = data.get('query', {}).get('conditions', []) + conditions = filter(lambda c: c['key'] in keys, conditions) + operator = data.get('query', {}).get('operator', '&') + def parse(condition): + key = "%s%s" % ('findvalue', { + '>': '__gt', + '>=': '__gte', + '<': '__lt', + '<=': '__lte', + '==': '__iexact', + '=': '__icontains', + '^': '__istartswith', + '$': '__iendswith', + }.get(condition.get('opterator', ''), '__icontains')) + q = Q(**{key: condition['value']}) + if condition['key'] in public_layers: + q = q & Q(layer=condition['key']) + return q + conditions = map(parse, conditions) + if conditions: + q = conditions[0] + for c in conditions[1:]: + if operator == '|': + q = q | c + else: + q = q & c + return q + return None + def find(self, data, user): ''' query: { diff --git a/pandora/clip/models.py b/pandora/clip/models.py index d9a5efeda..b40d997e7 100644 --- a/pandora/clip/models.py +++ b/pandora/clip/models.py @@ -42,7 +42,7 @@ class MetaClip: clip_keys = ('id', 'in', 'out', 'position', 'created', 'modified', 'hue', 'saturation', 'lightness', 'volume', 'videoRatio') - def json(self, keys=None): + def json(self, keys=None, qs=None): j = {} for key in self.clip_keys: j[key] = getattr(self, { @@ -60,8 +60,11 @@ class MetaClip: del j[key] #needed here to make item find with clips work if 'annotations' in keys: + annotations = self.annotations.filter(layer__in=self.layers) + if qs: + annotations = annotations.filter(qs) j['annotations'] = [a.json(keys=['value', 'id', 'layer']) - for a in self.annotations.filter(layer__in=self.layers)] + for a in annotations] for key in keys: if key not in self.clip_keys and key not in j: value = self.item.get(key) diff --git a/pandora/clip/views.py b/pandora/clip/views.py index 8a65ed976..d95eb3c43 100644 --- a/pandora/clip/views.py +++ b/pandora/clip/views.py @@ -23,6 +23,7 @@ def parse_query(data, user): if key in data: query[key] = data[key] query['qs'] = models.Clip.objects.find(query, user) + query['filter'] = models.Clip.objects.filter_annotations(query, user) if 'itemsQuery' in data and data['itemsQuery'].get('conditions'): item_query = Item.objects.find({'query': data['itemsQuery']}, user) query['qs'] = query['qs'].filter(item__in=item_query) @@ -94,11 +95,12 @@ def findClips(request): response['data']['items'] = [add(p) for p in qs] keys = data['keys'] - def add_annotations(key, qs, add_layer=False): values = ['public_id', 'value', 'clip__public_id'] if add_layer: values.append('layer') + if query['filter']: + qs = qs.filter(query['filter']) for a in qs.values(*values): for i in response['data']['items']: if i['id'] == a['clip__public_id']: diff --git a/pandora/item/views.py b/pandora/item/views.py index 3987cb7db..adca932fe 100644 --- a/pandora/item/views.py +++ b/pandora/item/views.py @@ -92,6 +92,8 @@ def parse_query(data, user): if 'clips' in data: query['clip_qs'] = Clip.objects.find({'query': data['clips']['query']}, user).order_by('start') + query['clip_filter'] = Clip.objects.find({'query': data['clips']['query']}, + user) query['clip_items'] = data['clips'].get('items', 5) query['clip_keys'] = data['clips'].get('keys') if not query['clip_keys']: @@ -231,7 +233,7 @@ Positions i += step else: clips = qs - return [c.json(query['clip_keys']) for c in clips] + return [c.json(query['clip_keys'], query['clip_filter']) for c in clips] def only_p_sums(m): r = {} diff --git a/static/js/pandora/clipsView.js b/static/js/pandora/clipsView.js index 667828f03..36f268409 100644 --- a/static/js/pandora/clipsView.js +++ b/static/js/pandora/clipsView.js @@ -4,7 +4,10 @@ pandora.ui.clipsView = function(videoRatio) { - var that = Ox.SplitPanel({ + var textKey = Ox.getObjectById(pandora.site.layers, 'subtitles') + ? 'subtitles' + : 'annotations', + that = Ox.SplitPanel({ elements: [ { element: Ox.Bar({size: 24}) @@ -26,7 +29,7 @@ pandora.ui.clipsView = function(videoRatio) { .bindEvent({ submit: function(data) { pandora.UI.set('itemFind', data.value ? { - conditions: [{key: 'subtitles', value: data.value, operator: '='}], + conditions: [{key: textKey, value: data.value, operator: '='}], operator: '&' } : pandora.site.user.ui.itemFind); // since this is the only way itemFind can change, @@ -48,4 +51,4 @@ pandora.ui.clipsView = function(videoRatio) { return that; -}; \ No newline at end of file +};