From 29008d0eaecac2d1f423d478375c94902c8d15ee Mon Sep 17 00:00:00 2001 From: j <0x006A@0x2620.org> Date: Mon, 4 Mar 2013 15:41:25 +0000 Subject: [PATCH] add addAnnotations api to batch import many annotations, update importAnnotations dialog --- pandora/annotation/tasks.py | 28 ++++++ pandora/annotation/views.py | 41 ++++++++- pandora/archive/views.py | 5 +- pandora/config.indiancinema.jsonc | 2 +- static/js/pandora/importAnnotations.js | 118 ++++++++++++++----------- static/js/pandora/utils.js | 20 ++++- 6 files changed, 158 insertions(+), 56 deletions(-) diff --git a/pandora/annotation/tasks.py b/pandora/annotation/tasks.py index 4684ad86a..3d3088ebd 100644 --- a/pandora/annotation/tasks.py +++ b/pandora/annotation/tasks.py @@ -4,6 +4,7 @@ import json import ox from django.conf import settings +from django.db import transaction from celery.task import task import models @@ -63,6 +64,33 @@ def update_matches(id, type): for e in a_matches.all(): e.update_matches(models.Annotation.objects.filter(pk=a.id)) +@task(ignore_results=False, queue='default') +def add_annotations(data): + from item.models import Item + from user.models import User + item = Item.objects.get(itemId=data['item']) + layer_id = data['layer'] + layer = filter(lambda l: l['id'] == layer_id, settings.CONFIG['layers'])[0] + user = User.objects.get(username=data['user']) + with transaction.commit_on_success(): + for a in data['annotations']: + annotation = models.Annotation( + item=item, + layer=layer_id, + user=user, + start=float(a['in']), end=float(a['out']), + value=a['value']) + annotation.save() + #update facets if needed + if filter(lambda f: f['id'] == layer_id, settings.CONFIG['filters']): + item.update_layer_facet(layer_id) + Item.objects.filter(id=item.id).update(modified=annotation.modified) + annotation.item.modified = annotation.modified + annotation.item.update_find() + annotation.item.update_sort() + annotation.item.update_facets() + return True + @task(ignore_results=True, queue='default') def update_item(id): from item.models import Item diff --git a/pandora/annotation/views.py b/pandora/annotation/views.py index 6cd04af19..3a632266f 100644 --- a/pandora/annotation/views.py +++ b/pandora/annotation/views.py @@ -15,7 +15,7 @@ from item import utils from item.models import Item import models -from tasks import update_item +from tasks import update_item, add_annotations def parse_query(data, user): query = {} @@ -157,6 +157,45 @@ def addAnnotation(request): return render_to_json_response(response) actions.register(addAnnotation, cache=False) +@login_required_json +def addAnnotations(request): + ''' + param data { + item: itemId, + layer: layerId, + annotations: [{ + in: float, + out: float, + value: string + }, ...] + } + return {'status': {'code': int, 'text': string}, + 'data': { + id: 123, //id of new annotation + ... + } + } + ''' + data = json.loads(request.POST['data']) + for key in ('item', 'layer', 'annotations'): + if key not in data: + return render_to_json_response(json_response(status=400, + text='invalid data')) + + item = get_object_or_404_json(Item, itemId=data['item']) + + layer_id = data['layer'] + layer = filter(lambda l: l['id'] == layer_id, settings.CONFIG['layers'])[0] + if item.editable(request.user) \ + and layer['canAddAnnotations'].get(request.user.get_profile().get_level()): + response = json_response() + data['user'] = request.user.username + t = add_annotations.delay(data) + response['data']['taskId'] = t.task_id + else: + response = json_response(status=403, text='permission denied') + return render_to_json_response(response) +actions.register(addAnnotations, cache=False) @login_required_json def removeAnnotation(request): diff --git a/pandora/archive/views.py b/pandora/archive/views.py index f23ee960d..d0ba76ccf 100644 --- a/pandora/archive/views.py +++ b/pandora/archive/views.py @@ -285,7 +285,10 @@ def firefogg_upload(request): def taskStatus(request): #FIXME: should check if user has permissions to get status data = json.loads(request.POST['data']) - task_id = data['task_id'] + if 'taskId' in data: + task_id = data['taskId'] + else: + task_id = data['task_id'] response = task_status(request, task_id) return render_to_json_response(response) actions.register(taskStatus, cache=False) diff --git a/pandora/config.indiancinema.jsonc b/pandora/config.indiancinema.jsonc index 2727a23b1..ef327adec 100644 --- a/pandora/config.indiancinema.jsonc +++ b/pandora/config.indiancinema.jsonc @@ -38,7 +38,7 @@ "canEditPlaces": {"student": true, "staff": true, "admin": true}, "canEditSitePages": {"staff": true, "admin": true}, "canEditUsers": {"staff": true, "admin": true}, - "canImportAnnotations": {}, + "canImportAnnotations": {"admin": true}, "canManagePlacesAndEvents": {"student": true, "staff": true, "admin": true}, "canManageTitlesAndNames": {"student": true, "staff": true, "admin": true}, "canManageUsers": {"staff": true, "admin": true}, diff --git a/static/js/pandora/importAnnotations.js b/static/js/pandora/importAnnotations.js index 17b1b5738..93f78fe22 100644 --- a/static/js/pandora/importAnnotations.js +++ b/static/js/pandora/importAnnotations.js @@ -4,18 +4,17 @@ pandora.ui.importAnnotations = function(data) { var content = Ox.Element().css({margin: '16px'}), file, - height = 192, + height = 128, layers = pandora.site.layers.filter(function(layer) { return layer.canAddAnnotations[pandora.user.level]; }), layer, - width = 384, srt = [], total = 0, importButton, selectLayer, selectFile, - that = Ox.Dialog({ + that = pandora.ui.iconDialog({ buttons: [ Ox.Button({ id: 'close', @@ -32,20 +31,16 @@ pandora.ui.importAnnotations = function(data) { }).bindEvent({ click: function() { importButton.hide(); - selectLayer.hide(); - selectFile.hide(); - addAnnotation(); + addAnnotations(); } }) ], closeButton: true, - content: content, + text: content, keys: { 'escape': 'close' }, - height: height, removeOnClose: true, - width: width, title: 'Import Annotations' }) .bindEvent({ @@ -54,39 +49,50 @@ pandora.ui.importAnnotations = function(data) { } }), $status = $('