# HG changeset patch # User ymh # Date 1441879446 -7200 # Node ID 26e3ee7483278079a4452385a373d2dee0634572 # Parent 19d1f3311e893ba786046582f986389083a048f7 correct critical sections handling diff -r 19d1f3311e89 -r 26e3ee748327 src/ldt/ldt/api/ldt/resources/annotation.py --- a/src/ldt/ldt/api/ldt/resources/annotation.py Mon Sep 07 17:25:08 2015 +0200 +++ b/src/ldt/ldt/api/ldt/resources/annotation.py Thu Sep 10 12:04:06 2015 +0200 @@ -2,6 +2,7 @@ from ldt.ldt_utils.models import Project, Content, Segment from ldt.ldt_utils.utils import LdtAnnotation from ldt.security import protect_models, unprotect_models + from tastypie import fields from tastypie.authorization import Authorization from tastypie.exceptions import NotFound, BadRequest @@ -9,7 +10,7 @@ class AnnotationObject(object): - def __init__(self, id="", project = "", type = "", type_title = "", ensemble="", media = "", begin = 0, end = 0, content = {"title":"", "description":""}, tags = [], meta = {"creator":"","created":""}): # @ReservedAssignment + def __init__(self, id="", project="", type="", type_title="", ensemble="", media="", begin=0, end=0, content={"title":"", "description":""}, tags=[], meta={"creator":"", "created":""}): # @ReservedAssignment self.id = id self.project = project self.type = type @@ -21,20 +22,20 @@ self.content = content self.tags = tags self.meta = meta - + class AnnotationResource(Resource): # For the moment, these attributes are useless. We just prepare relations to AnnotationObject - id = fields.CharField(attribute = 'id') - project = fields.CharField(attribute = 'project') - type = fields.CharField(attribute = 'type') - type_title = fields.CharField(attribute = 'type_title') - media = fields.CharField(attribute = 'media') - begin = fields.IntegerField(attribute = 'begin') - end = fields.IntegerField(attribute = 'end') - content = fields.DictField(attribute = 'content') - tags = fields.ListField(attribute = 'tags') - meta = fields.DictField(attribute = 'meta') - + id = fields.CharField(attribute='id') + project = fields.CharField(attribute='project') + type = fields.CharField(attribute='type') + type_title = fields.CharField(attribute='type_title') + media = fields.CharField(attribute='media') + begin = fields.IntegerField(attribute='begin') + end = fields.IntegerField(attribute='end') + content = fields.DictField(attribute='content') + tags = fields.ListField(attribute='tags') + meta = fields.DictField(attribute='meta') + class Meta: allowed_methods = ['post', 'put', 'delete'] resource_name = 'annotations' @@ -43,19 +44,19 @@ # always_return_data = True because we want the api returns the data with the updated ids always_return_data = True include_resource_uri = False - + def extract_annotation_data(self, data): # This method extracts and validates the data we receive from the user for adding or editing an annotation - + project_id = "" if data.has_key('project') : project_id = data["project"] - + if data.has_key('media') : iri_id = data["media"] else : raise BadRequest - + if project_id and project_id != "" : try: project = Project.objects.get(ldt_id=project_id) @@ -69,40 +70,40 @@ raise NotFound("Content not found. iri_id = " + iri_id) project = content.get_or_create_front_project() project_id = project.ldt_id - - ann_duration = -1 - ann_begin = -1 - ann_end = -1 + + ann_duration = 0 + ann_begin = 0 + ann_end = 0 if (data.has_key('begin') and data.has_key('end')): ann_duration = str(data['end'] - data['begin']) ann_begin = str(data['begin']) ann_end = str(data['end']) - + ann_audio_src = data.get('content', {}).get('audio', {}).get('src', "") ann_audio_href = data.get('content', {}).get('audio', {}).get('href', "") - + ann_author = data.get('meta', {}).get('creator', "") ann_date = data.get('meta', {}).get('created', "") - + ann_type_id = data.get('type', '') ann_type_title = data.get('type_title', '') ann_id = data.get("id", "") - ann_title = data.get('content', {}).get('title', "") + ann_title = data.get('content', {}).get('title', "") ann_description = data.get('content', {}).get('description') ann_tags = data.get('tags', []) - + content = project.contents.get(iri_id=iri_id) - + return { "project_obj" : project, "project_id" : project_id, - "content_obj" : content, + "content_obj" : content, "iri_id" : iri_id, - "ann_type_id" : ann_type_id, + "ann_type_id" : ann_type_id, "ann_type_title" : ann_type_title, "ann_id" : ann_id, - "ann_content" : { - "title" : ann_title, + "ann_content" : { + "title" : ann_title, "description" : ann_description, "audio" : { "src" : ann_audio_src, @@ -118,123 +119,49 @@ "ann_end" : ann_end, "ann_duration" : ann_duration, } - + def obj_delete_list(self, bundle, **kwargs): return True - + def obj_create(self, bundle, **kwargs): - # Here the a has the datas for only one annotation. Tastypie's post allows only one resource addition + # Here the a has the datas for only one annotation. Tastypie's post allows only one resource addition data_dict = self.extract_annotation_data(bundle.data) adder = LdtAnnotation(data_dict["project_obj"]) - - unprotect_models() # Allows anonymous user to modify models in this request only - type_id, new_id, ensemble_id = adder.add( - data_dict['iri_id'], # media - data_dict['ann_type_id'], # cutting_id - data_dict['ann_type_title'], # cutting_title - data_dict['ann_content']['title'], # title - data_dict['ann_content']['description'], # text - data_dict['ann_tags'], # tags_list - data_dict['ann_begin'], # begin - data_dict['ann_duration'], # dur - data_dict['ann_meta']['creator'], # author - data_dict['ann_meta']['created'], # date - None, - "2194379", - data_dict['ann_content']['audio']['src'], - data_dict['ann_content']['audio']['href'] - ) - - if not new_id: - protect_models() - raise BadRequest - - # We update the ids - data_dict['ann_type_id'] = type_id - data_dict['ensemble_id'] = ensemble_id - data_dict['ann_id'] = new_id + unprotect_models() # Allows anonymous user to modify models in this request only - #add segment - add_segment({ - "project" : data_dict["project_obj"], - "content" : data_dict["content_obj"], - "ensemble_id" : data_dict["ensemble_id"], - "cutting_id" : data_dict['ann_type_id'], - "element_id" : data_dict['ann_id'], - "title" : data_dict['ann_content']['title'], - "abstract" : data_dict['ann_content']['description'], - "tags" : ",".join(data_dict['ann_tags']), - "start_ts" : data_dict['ann_begin'], - "duration" : data_dict['ann_duration'], - "author" : data_dict['ann_meta']['creator'], - "date" : data_dict['ann_meta']['created'], - "audio_src" : data_dict['ann_content']['audio']['src'], - "audio_href" : data_dict['ann_content']['audio']['href'], - "polemics": adder.get_polemic_syntax(data_dict['ann_content']['title']) - }) - - # We save the added annotation and reprotect the contents and projects - adder.save(must_reindex=False) - protect_models() - # We update the AnnotationObject for the returned datas to be correct. - bundle.obj = AnnotationObject( - id = data_dict["ann_id"], - project = data_dict["project_id"], - type = data_dict["ann_type_id"], - type_title = data_dict["ann_type_title"], - ensemble = data_dict['ensemble_id'], - media = data_dict["iri_id"], - begin = data_dict["ann_begin"], - end = data_dict["ann_end"], - content = data_dict['ann_content'], - tags = data_dict['ann_tags'], - meta = data_dict['ann_meta'] - ) - return bundle - - def obj_update(self, bundle, **kwargs): - data_dict = self.extract_annotation_data(bundle.data) - if data_dict['ann_id'] == "": - data_dict['ann_id'] == kwargs["pk"] - - adder = LdtAnnotation(data_dict["project_obj"]) - unprotect_models() # Allows anonymous user to modify models in this request only - - ensemble_id = adder.edit( - data_dict['ann_id'], # annotation_id - data_dict['iri_id'], # media - data_dict['ann_type_id'], # cutting_id - data_dict['ann_type_title'], # cutting_title - data_dict['ann_content']['title'], # title - data_dict['ann_content']['description'], # text - data_dict['ann_tags'], # tags_list - data_dict['ann_begin'], # begin - data_dict['ann_duration'], # dur - data_dict['ann_meta']['creator'], # author - data_dict['ann_meta']['created'], # date - None, - "2194379", - data_dict['ann_content']['audio']['src'], - data_dict['ann_content']['audio']['href'] - ) - if not ensemble_id: - protect_models() - raise BadRequest - # We update the id - data_dict['ensemble_id'] = ensemble_id - #add segment - edit_segment( - data_dict["project_id"], - data_dict["iri_id"], - data_dict["ensemble_id"], - data_dict['ann_type_id'], - data_dict["ann_id"], - params = { + try: + type_id, new_id, ensemble_id = adder.add( + data_dict['iri_id'], # media + data_dict['ann_type_id'], # cutting_id + data_dict['ann_type_title'], # cutting_title + data_dict['ann_content']['title'], # title + data_dict['ann_content']['description'], # text + data_dict['ann_tags'], # tags_list + data_dict['ann_begin'], # begin + data_dict['ann_duration'], # dur + data_dict['ann_meta']['creator'], # author + data_dict['ann_meta']['created'], # date + None, + "2194379", + data_dict['ann_content']['audio']['src'], + data_dict['ann_content']['audio']['href'] + ) + + if not new_id: + raise BadRequest + + # We update the ids + data_dict['ann_type_id'] = type_id + data_dict['ensemble_id'] = ensemble_id + data_dict['ann_id'] = new_id + + # add segment + add_segment({ "project" : data_dict["project_obj"], "content" : data_dict["content_obj"], "ensemble_id" : data_dict["ensemble_id"], - "cutting_id" : data_dict['ann_type_id'], + "cutting_id" : data_dict['ann_type_id'], "element_id" : data_dict['ann_id'], "title" : data_dict['ann_content']['title'], "abstract" : data_dict['ann_content']['description'], @@ -242,58 +169,134 @@ "start_ts" : data_dict['ann_begin'], "duration" : data_dict['ann_duration'], "author" : data_dict['ann_meta']['creator'], - "date" : data_dict['ann_meta']['created'], - "audio_src" : data_dict['ann_content']['audio']['src'], + "date" : data_dict['ann_meta']['created'], + "audio_src" : data_dict['ann_content']['audio']['src'], "audio_href" : data_dict['ann_content']['audio']['href'], "polemics": adder.get_polemic_syntax(data_dict['ann_content']['title']) }) - - # We save the added annotation and reprotect the contents and projects - adder.save(must_reindex=False) - protect_models() + + # We save the added annotation and reprotect the contents and projects + adder.save(must_reindex=False) + finally: + protect_models() # We update the AnnotationObject for the returned datas to be correct. - bundle.obj = AnnotationObject( - id = data_dict["ann_id"], - project = data_dict["project_id"], - type = data_dict["ann_type_id"], - type_title = data_dict["ann_type_title"], - ensemble = data_dict['ensemble_id'], - media = data_dict["iri_id"], - begin = data_dict["ann_begin"], - end = data_dict["ann_end"], - content = data_dict['ann_content'], - tags = data_dict['ann_tags'], - meta = data_dict['ann_meta'] + id=data_dict["ann_id"], + project=data_dict["project_id"], + type=data_dict["ann_type_id"], + type_title=data_dict["ann_type_title"], + ensemble=data_dict['ensemble_id'], + media=data_dict["iri_id"], + begin=data_dict["ann_begin"], + end=data_dict["ann_end"], + content=data_dict['ann_content'], + tags=data_dict['ann_tags'], + meta=data_dict['ann_meta'] ) return bundle - + + def obj_update(self, bundle, **kwargs): + data_dict = self.extract_annotation_data(bundle.data) + if not data_dict['ann_id']: + data_dict['ann_id'] = kwargs["pk"] + + adder = LdtAnnotation(data_dict["project_obj"]) + try: + unprotect_models() # Allows anonymous user to modify models in this request only + + ensemble_id = adder.edit( + data_dict['ann_id'], # annotation_id + data_dict['iri_id'], # media + data_dict['ann_type_id'], # cutting_id + data_dict['ann_type_title'], # cutting_title + data_dict['ann_content']['title'], # title + data_dict['ann_content']['description'], # text + data_dict['ann_tags'], # tags_list + data_dict['ann_begin'], # begin + data_dict['ann_duration'], # dur + data_dict['ann_meta']['creator'], # author + data_dict['ann_meta']['created'], # date + None, + "2194379", + data_dict['ann_content']['audio']['src'], + data_dict['ann_content']['audio']['href'] + ) + if not ensemble_id: + raise BadRequest + # We update the id + data_dict['ensemble_id'] = ensemble_id + # add segment + edit_segment( + data_dict["project_id"], + data_dict["iri_id"], + data_dict["ensemble_id"], + data_dict['ann_type_id'], + data_dict["ann_id"], + params={ + "project" : data_dict["project_obj"], + "content" : data_dict["content_obj"], + "ensemble_id" : data_dict["ensemble_id"], + "cutting_id" : data_dict['ann_type_id'], + "element_id" : data_dict['ann_id'], + "title" : data_dict['ann_content']['title'], + "abstract" : data_dict['ann_content']['description'], + "tags" : ",".join(data_dict['ann_tags']), + "start_ts" : data_dict['ann_begin'], + "duration" : data_dict['ann_duration'], + "author" : data_dict['ann_meta']['creator'], + "date" : data_dict['ann_meta']['created'], + "audio_src" : data_dict['ann_content']['audio']['src'], + "audio_href" : data_dict['ann_content']['audio']['href'], + "polemics": adder.get_polemic_syntax(data_dict['ann_content']['title']) + }) + + # We save the added annotation and reprotect the contents and projects + adder.save(must_reindex=False) + finally: + protect_models() + # We update the AnnotationObject for the returned datas to be correct. + + bundle.obj = AnnotationObject( + id=data_dict["ann_id"], + project=data_dict["project_id"], + type=data_dict["ann_type_id"], + type_title=data_dict["ann_type_title"], + ensemble=data_dict['ensemble_id'], + media=data_dict["iri_id"], + begin=data_dict["ann_begin"], + end=data_dict["ann_end"], + content=data_dict['ann_content'], + tags=data_dict['ann_tags'], + meta=data_dict['ann_meta'] + ) + return bundle + def obj_delete(self, bundle, **kwargs): ann_id = kwargs.get("pk", "") - try: - seg_to_delete = Segment.objects.get(element_id = ann_id) + try: + seg_to_delete = Segment.objects.get(element_id=ann_id) except Segment.DoesNotExist: raise NotFound("Segment not found. element_id = " + ann_id) project_id = seg_to_delete.project_id try: - project = Project.objects.get(ldt_id = project_id) + project = Project.objects.get(ldt_id=project_id) except Project.DoesNotExist: raise NotFound("Project not found. ldt_id = " + project_id) ann_type_id = seg_to_delete.cutting_id ensemble_id = seg_to_delete.ensemble_id iri_id = seg_to_delete.iri_id adder = LdtAnnotation(project) - unprotect_models() - deleted = adder.delete(ann_id, iri_id, ann_type_id) - if not deleted: + try: + unprotect_models() + deleted = adder.delete(ann_id, iri_id, ann_type_id) + if not deleted: + raise BadRequest + delete_segment(project, project_id, iri_id, ensemble_id, ann_type_id, ann_id) + adder.save() + finally: protect_models() - raise BadRequest - delete_segment(project, project_id, iri_id, ensemble_id, ann_type_id, ann_id) - adder.save() - protect_models() return bundle - + def get_resource_uri(self, bundle_or_obj=None, url_name='api_dispatch_list'): return '' - \ No newline at end of file