Changed API handler for XML files back to its original behavior
authorverrierj
Thu, 13 Oct 2011 10:43:00 +0200
changeset 200 a38c4759ce8a
parent 199 3d919c59b46f
child 201 d9e364e0694d
child 205 49c9890dce4a
Changed API handler for XML files back to its original behavior
src/ldt/ldt/api/ldt/handlers.py
src/ldt/ldt/ldt_utils/utils.py
--- a/src/ldt/ldt/api/ldt/handlers.py	Tue Oct 11 17:52:00 2011 +0200
+++ b/src/ldt/ldt/api/ldt/handlers.py	Thu Oct 13 10:43:00 2011 +0200
@@ -19,26 +19,30 @@
     @require_extended
     def update(self, request, project_id):
         """
-        This method is called when a PUT request is sent to http://<plateform_location>/api/ldt/projects/<project_id>.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 or XML file.
+        This method is called when a PUT request is sent to http://<plateform_location>/api/ldt/projects/<project_id>.format. 
             <project_id> is the ldt_id field of the project. If <projet_id> does not match any project on the platform, a 410 ("Gone")
             error will be returned.
             <format> is the format of the data sent back by the server. It can be 'json', 'yaml', 'xml' or 'pickle'.
+            
+        If the request contains a content-type header whose value is set to "application/json" and a valid utf-8 encoded JSON file,
+        the following conditions will be checked before the annotations are added : 
+            If the submitted file is not valid or 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). New cuttings are added to the view 
+            "View at the last recording" if it exists, or the the view "Init view" else. If none of those views exist, the server will 
+            not add the cutting to a view. Several annotations can be added at the same time if the submitted file contains multiple 
+            annotations. The server returns a 201 ("Created") code if annotations have been added successfully. 
         
-        If the submitted file is not valid or 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. The server returns a 201 ("Created") code if annotations have
-        been added successfully.   
+        If no content-type header is set, the file submitted must be a valid XML file and will replace entirely the ldt field
+        of the project without any verifications.  
         
         Example :
         
-        Remark : Both files below contain the minimum necessary fields and attributes for the handler to work. If one field or attribute is
+        Remark : The file 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 :
+        a content milosforman_amadeus, which has a cutting Salieri inside the view "View at the last recording". The following JSON file exists in the current directory :
     
         {
             "annotations": [
@@ -75,62 +79,15 @@
         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 :
-        
-        <iri>
-          <annotations>
-            <content id="milosforman_amadeus">
-              <ensemble>
-                <decoupage>
-                  <title>New cutting name</title>
-                  <abstract/>
-                  <elements>
-                    <element begin="50000" dur="895000" date="2011-09-10T09:12:58" author="John Doe">
-                      <title>new annotation</title>
-                      <abstract/>
-                      <audio source=""/>
-                      <tags>
-                        <tag>json</tag>
-                      </tags>
-                    </element>            
-                  </elements>
-                </decoupage>
-                <decoupage >
-                  <title>Salieri</title>
-                  <abstract/>
-                  <elements>
-                    <element begin="700000" dur="500000" date="2011-09-10T09:12:58" author="John Doe">
-                      <title>Annotation about Salieri</title>
-                      <abstract/>
-                      <audio source=""/>
-                      <tags>
-                          <tag>xml</tag>
-                          <tag>test</tag>
-                          <tag>blop</tag>
-                      </tags>
-                    </element>            
-                  </elements>
-                </decoupage>
-            </ensemble>
-           </content>
-          </annotations>
-        </iri>
-        
-        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 
-
-        adder = LdtAnnotation(project)           
-          
         if request.content_type == 'application/json':
-            
+            try:
+                project = Project.objects.get(ldt_id=project_id)
+            except Project.DoesNotExist:
+                return rc.NOT_HERE 
+        
+            adder = LdtAnnotation(project)
             logging.debug("request json " + repr(request.data))       
 
             meta = request.data['meta']
@@ -146,31 +103,20 @@
 
             return rc.ALL_OK
             
-        elif request.content_type == "text/xml":        
-            logging.debug("request xml" + repr(request))
+        else:
+            logging.debug("request " + repr(request))
+            data = request.data
+            ldt_str = data["ldt"] 
             
-            ldtdoc = lxml.etree.fromstring(request.raw_post_data) 
+            logging.debug("request data" + repr(ldt_str))
             
-            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
+            if not ldt_str:
+                return rc.ALL_OK
+            
+            project = Project.objects.get(ldt_id=project_id)
+            
+            project.ldt = ldt_str
+            
+            project.save()
         
             return rc.ALL_OK
-        
-        return rc.NOT_IMPLEMENTED
--- a/src/ldt/ldt/ldt_utils/utils.py	Tue Oct 11 17:52:00 2011 +0200
+++ b/src/ldt/ldt/ldt_utils/utils.py	Thu Oct 13 10:43:00 2011 +0200
@@ -179,12 +179,7 @@
         if len(path_media) == 0:
             self.to_add = False
             return False
-                
-        path_view = self.ldtdoc.xpath('/iri/displays/display[@title="%s"]' % view)
-        if len(path_view) == 0:
-            self.to_add = False,
-            return False
-                
+                                
         path_annotations = self.ldtdoc.xpath('/iri/annotations')[0]
         path_content = path_annotations.xpath('content[@id="%s"]' % media)
                 
@@ -217,18 +212,23 @@
             decoupage_elements = lxml.etree.SubElement(decoupage, 'elements')
             decoupage_elements = [decoupage_elements]
         else:
-            cutting_id = decoupage_elements[0].get('id')     
+            cutting_id = path_ensemble[0].xpath('decoupage[title="%s"]' % cutting)[0].get('id')     
+        
+        path_view = self.ldtdoc.xpath('/iri/displays/display[@title="%s"]' % view)
+        if len(path_view) == 0:
+            path_view = self.ldtdoc.xpath('/iri/displays/display[@title="Init view"]')
         
-        content_display = path_view[0].xpath('content[@id="%s"]' % media)
-        if len(content_display) == 0:
-            content_display = lxml.etree.SubElement(path_view[0], 'content')
-            content_display.set('id', media)
-            content_display = [content_display]
-        
-        dec = lxml.etree.SubElement(content_display[0], 'decoupage')
-        dec.set('idens', ensemble_id)
-        dec.set('id', cutting_id)
-        dec.set('tagsSelect', '')                           
+        if len(path_view) != 0:        
+            content_display = path_view[0].xpath('content[@id="%s"]' % media)
+            if len(content_display) == 0:
+                content_display = lxml.etree.SubElement(path_view[0], 'content')
+                content_display.set('id', media)
+                content_display = [content_display]
+            
+            dec = lxml.etree.SubElement(content_display[0], 'decoupage')
+            dec.set('idens', ensemble_id)
+            dec.set('id', cutting_id)
+            dec.set('tagsSelect', '')                           
                 
         element = lxml.etree.SubElement(decoupage_elements[0], 'element')
         element.set('id', 's_' + generate_uuid())