# HG changeset patch # User verrierj # Date 1318253516 -7200 # Node ID 6dfdc12e338aadae927e5aa7f2ac5b30dda0175c # Parent b939a58d13b071780774b6d3c3653483612a7b38 Improved API for annotations sent in XML diff -r b939a58d13b0 -r 6dfdc12e338a src/ldt/ldt/api/ldt/handlers.py --- a/src/ldt/ldt/api/ldt/handlers.py Mon Oct 10 11:54:34 2011 +0200 +++ b/src/ldt/ldt/api/ldt/handlers.py Mon Oct 10 15:31:56 2011 +0200 @@ -3,6 +3,7 @@ from piston.utils import rc, require_extended from ldt.ldt_utils.utils import LdtAnnotation import logging #@UnresolvedImport +import lxml.etree class ProjectHandler(BaseHandler): @@ -20,19 +21,22 @@ """ This method is called when a PUT request is sent to http:///api/ldt/projects/.format. The request should contain a content-type header whose value can be either "application/json" or "text/xml" and a valid utf-8 - encoded JSON/Cinelab or LDT/XML file. + encoded JSON Cinelab or LDT XML file. is the ldt_id field of the project. If does not match any project on the platform, a 410 ("Gone") error will be returned. - can be 'json', 'yaml', 'xml', 'pickle' + is the format of the data sent back by the server. It can be 'json', 'yaml', 'xml' or 'pickle'. If the submitted file is not valid or if the file refers to a media that is not contained in the project, a 500 ("Bad Request") error will be returned. If the "type" field of an annotation matches an already existing cutting, it will be added to that cutting. Otherwise, a new cutting will be added (as well as a new ensemble if needed). Several annotations can be added at - the same time if the submitted file contains multiple annotations. In addition to annotations, the submitted file should contain a - meta section with two fields :"date" and "creator". The server returns a 201 ("Created") code if annotations have been added. + the same time if the submitted file contains multiple annotations. The server returns a 201 ("Created") code if annotations have + been added successfully. Example : + Remark : Both files below contain the minimum necessary fields and attributes for the handler to work. If one field or attribute is + missing (e.g. author, or date) during submission, an error will occur. + A platform is reachable at http://localhost/. It contains a project with ID a0593b58-f258-11df-80e1-00145ea4a2be. This project has a content milosforman_amadeus, which has a cutting Salieri. The following JSON file exists in the current directory : @@ -68,20 +72,66 @@ If we send a PUT request with curl : $curl -X PUT http://localhost/api/ldt/projects/a0593b58-f258-11df-80e1-00145ea4a2be.json -d @example.JSON -H "content-type:application/json" - A new cutting titled "New cutting name" will be created with one annotation inside, and the annotation "Annotation about Salieri" - will be added to the Salieri cutting. + A new cutting titled "New cutting name" will be created with the first annotation inside, and the annotation "Annotation about Salieri" + will be added to the Salieri cutting. + + Similar results can be obtained using the following xml file : + + + + + + + New cutting name + + + + new annotation + + + + + + Salieri + + + + Annotation about Salieri + + + + + + + + + + and the command : + + $curl -X PUT http://localhost/api/ldt/projects/a0593b58-f258-11df-80e1-00145ea4a2be.json -d @example.LDT -H "content-type:text/xml" """ try: project = Project.objects.get(ldt_id=project_id) except Project.DoesNotExist: - return rc.NOT_HERE - + return rc.NOT_HERE + + adder = LdtAnnotation(project) + if request.content_type == 'application/json': - logging.debug("request json " + repr(request)) - adder = LdtAnnotation(project) + logging.debug("request json " + repr(request.data)) meta = request.data['meta'] author = meta['creator'] @@ -94,21 +144,32 @@ if not adder.add(a['media'], a['type'], a['content']['data'], '', a['tags'], begin, dur, author, date): return rc.BAD_REQUEST - return rc.ALL_OK + return rc.ALL_OK elif request.content_type == "text/xml": logging.debug("request xml" + repr(request)) - data = request.data - ldt_str = data["ldt"] - logging.debug("request data" + repr(ldt_str)) + ldtdoc = lxml.etree.fromstring(request.raw_post_data) - if not ldt_str: - return rc.ALL_OK - - project.ldt = ldt_str - - project.save() + for content in ldtdoc.xpath('/iri/annotations/content'): + content_id = content.get('id') + + for decoupage in content.xpath('ensemble/decoupage'): + dec_title = decoupage.xpath('title')[0].text + author = decoupage.get('author') + + for element in decoupage.xpath('elements/element'): + begin = element.get('begin') + dur = element.get('dur') + date = element.get('date') + title = element.xpath('title')[0].text + abstract = element.xpath('abstract')[0].text + tags = [] + for tag in element.xpath('tags/tag'): + tags.append(tag.text) + + if not adder.add(content_id, dec_title, title, abstract, tags, begin, dur, author, date): + return rc.BAD_REQUEST return rc.ALL_OK diff -r b939a58d13b0 -r 6dfdc12e338a src/ldt/ldt/ldt_utils/tests.py --- a/src/ldt/ldt/ldt_utils/tests.py Mon Oct 10 11:54:34 2011 +0200 +++ b/src/ldt/ldt/ldt_utils/tests.py Mon Oct 10 15:31:56 2011 +0200 @@ -67,8 +67,8 @@ doc.write(f, pretty_print=True) f.seek(0) ldoc = lxml.etree.parse(f) - self.assertEqual(ldoc.xpath("/iri/displays/display/content")[11].get("id"), self.cont2.iri_id) - self.assertEqual(ldoc.xpath("/iri/medias/media")[10].get("id"), self.cont1.iri_id) + self.assertEqual(ldoc.xpath("/iri/displays/display/content")[10].get("id"), self.cont2.iri_id) + self.assertEqual(ldoc.xpath("/iri/medias/media")[9].get("id"), self.cont1.iri_id) f.close() def test_generate_init(self): @@ -147,11 +147,7 @@ self.cont11.iri_id = "id11" self.cont11.save() - self.cont12 = Content(iriurl="id12/iriurl2") - self.cont12.iri_id = "id12" - self.cont12.save() - - self.project.contents.add(self.cont11, self.cont12) + self.project.contents.add(self.cont11) self.project.ldt = "" create_ldt(self.project, self.user)