Added support for project copy in api/ldt/1.0/projects POST requests with a "source" parameter that has the id of the project to copy
authordurandn
Mon, 20 Jul 2015 18:38:38 +0200
changeset 1405 1878f6371f87
parent 1404 f82cb73c5260
child 1406 de1b8dfbb637
Added support for project copy in api/ldt/1.0/projects POST requests with a "source" parameter that has the id of the project to copy
src/ldt/ldt/api/ldt/resources/project.py
--- a/src/ldt/ldt/api/ldt/resources/project.py	Sun Jul 19 23:41:33 2015 +0200
+++ b/src/ldt/ldt/api/ldt/resources/project.py	Mon Jul 20 18:38:38 2015 +0200
@@ -1,6 +1,7 @@
 import logging
 
 from django import VERSION as django_version
+from django.db import transaction
 from django.conf import settings
 from django.conf.urls import url
 from django.contrib.auth.models import Group
@@ -38,7 +39,8 @@
             'state' : ALL,
             'ldt_id' : ALL,
             'title' : ALL
-        }
+        },
+        always_return_data = True
         # In the future version :
         # detail_uri_name = 'ldt_id'
     
@@ -65,12 +67,32 @@
         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
+    # If there is a "source" argument in the data with a valid id, then it will create a copy of the source project
+    # Additionally if there is also a "publish" argument in the data, the copied project will immediately be published
+    @transaction.atomic
     def obj_create(self, bundle, **kwargs):
         request = bundle.request
+        
         if request is None:
             raise BadRequest("Request object must be passed as an argument")
         unprotect_models()
-        bundle = super(ProjectResource, self).obj_create(bundle, **kwargs)
+        # if source is not none then try copy
+        if bundle.data["source"] is not None:
+            try: 
+                source_proj = Project.objects.get(ldt_id=bundle.data['source'])
+            except ObjectDoesNotExist:
+                return http.HttpNotFound("A model instance matching the provided arguments could not be found.")
+            if check_object_perm_for_user(source_proj, "change_project", request.user):
+                bundle.data["title"] = bundle.data.get("title", source_proj.title)
+                bundle.data["description"] = bundle.data.get("description", source_proj.description)
+                publish_bool = {'true': True, 'false': False, "0": False, "1": True}.get(bundle.data.get('publish', 'false').lower())
+            else:
+                raise BadRequest("User has no right to change the project.")
+            bundle.obj = source_proj.copy_project(user=request.user, title=bundle.data["title"], description=bundle.data["description"])
+            if publish_bool:
+                bundle.obj.publish()
+        else:    
+            bundle = super(ProjectResource, self).obj_create(bundle, **kwargs)
         # Assign permission for the owner
         assign_perm('view_project', request.user, bundle.obj)
         assign_perm('change_project', request.user, bundle.obj)
@@ -93,6 +115,7 @@
         return bundle
     
     # Updates an existing project. Used with post_detail and with a ldt_id in the url
+    @transaction.atomic
     def post_detail(self, request, **kwargs):
         # Inspired by put_detail but we only update an object. We can not create one.
         """