add api entry to update project.
authorcavaliet
Mon, 29 Apr 2013 15:42:25 +0200
changeset 1171 01e9351b1390
parent 1170 dd595544826f
child 1176 af204bb19efa
add api entry to update project.
src/ldt/ldt/api/ldt/resources/project.py
src/ldt/ldt/api/ldt/serializers/cinelabserializer.py
--- a/src/ldt/ldt/api/ldt/resources/project.py	Thu Apr 25 15:56:21 2013 +0200
+++ b/src/ldt/ldt/api/ldt/resources/project.py	Mon Apr 29 15:42:25 2013 +0200
@@ -8,10 +8,12 @@
 from ldt.api.ldt.resources import ContentResource
 from ldt.api.ldt.resources.user import UserResource
 from ldt.security import protect_models, unprotect_models
+from ldt.security.permissionchecker import check_object_perm_for_user
+from tastypie import fields, http
 from tastypie.authorization import Authorization
+from tastypie.exceptions import BadRequest
 from tastypie.resources import Bundle, ModelResource, ALL
-from tastypie import fields
-from tastypie.exceptions import BadRequest
+from tastypie.utils import dict_strip_unicode_keys
 
 
 class ProjectResource(ModelResource):
@@ -53,6 +55,7 @@
             kwargs['ldt_id'] = bundle_or_obj.ldt_id
         return self._build_reverse_url("api_dispatch_detail", kwargs=kwargs)
         
+    # Create a new project. Used with post_detail and with no ldt_id in the url
     def obj_create(self, bundle, request=None, **kwargs):
         unprotect_models()
         bundle = super(ProjectResource, self).obj_create(bundle, request)
@@ -65,6 +68,44 @@
         protect_models()
         return bundle
     
+    
+    # Prevent for put_list and delete all objects.
     def obj_delete_list(self, request=None, **kwargs):
         raise BadRequest("PUT with a list of projects is forbidden.")
+    
+    
+    # Updates an existing project. Used with post_detail and with a ldt_id in the url
+    def post_detail(self, request, **kwargs):
+        # Inspired by put_detail but we only update an object. We can not create one.
+        """
+        Since always_return_data is not set to True, 
+        the request returns accepted (202) if the project is well updated
+        and Not Found (404) if the id in url or datas were incorrect.
+        """
+        deserialized = self.deserialize(request, request.raw_post_data, format=request.META.get('CONTENT_TYPE', 'application/json'))
+        deserialized = self.alter_deserialized_detail_data(request, deserialized)
+        bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized), request=request)
+        self.is_valid(bundle, request)
+        try:
+            # We have to check if the user can change the project BEFORE calling obj_update
+            proj = Project.objects.get(ldt_id=bundle.data['ldt_id'])
+            if check_object_perm_for_user(proj, "change_project", request.user):
+                # Even if the user has the guardian right to change the project, 
+                # tastypie's save_m2m will raise an error. So we unprotect just for this saving.
+                unprotect_models()
+                updated_bundle = self.obj_update(bundle, request=request, **self.remove_api_resource_names(kwargs))
+                protect_models()
+            else:
+                raise BadRequest("User has no right to change the project.")
+            
+            if not self._meta.always_return_data:
+                return http.HttpAccepted()
+            else:
+                updated_bundle = self.full_dehydrate(updated_bundle)
+                updated_bundle = self.alter_detail_data_to_serialize(request, updated_bundle)
+                return self.create_response(request, updated_bundle, response_class=http.HttpAccepted)
+        except Exception as e:
+            return http.HttpNotFound("Object does not exist or Datas are not correct.\nError = " + str(e) + "\n")
+        return http.HttpResponse("fuuuuu")
+    
     
\ No newline at end of file
--- a/src/ldt/ldt/api/ldt/serializers/cinelabserializer.py	Thu Apr 25 15:56:21 2013 +0200
+++ b/src/ldt/ldt/api/ldt/serializers/cinelabserializer.py	Mon Apr 29 15:42:25 2013 +0200
@@ -63,7 +63,10 @@
         
         cinelab = simplejson.loads(content)
         meta = cinelab["meta"]
-        ldt_id = generate_uuid()
+        if "id" in meta and meta["id"]!="":
+            ldt_id = meta["id"]
+        else:
+            ldt_id = generate_uuid()
         # default state = (1, 'edition') OR (2, 'published')
         state = 2
         contents = [reverse("api_dispatch_detail", kwargs={"api_name":"1.0", "resource_name":"contents", "iri_id":c["id"]}) for c in cinelab["medias"]]