server/python/django2/renkanmanager/api/views.py
changeset 615 f3875fbe206a
parent 613 e00a24b711a0
child 618 3051b847c124
equal deleted inserted replaced
614:23416a833ca8 615:f3875fbe206a
     8 import json
     8 import json
     9 import logging
     9 import logging
    10 import uuid
    10 import uuid
    11 
    11 
    12 from django.db import transaction
    12 from django.db import transaction
       
    13 from django.core.exceptions import ObjectDoesNotExist
    13 from django.core.urlresolvers import reverse
    14 from django.core.urlresolvers import reverse
    14 from django.http import Http404
    15 from django.http import Http404
    15 from django.http.response import HttpResponse, HttpResponseBadRequest
    16 from django.http.response import HttpResponse, HttpResponseBadRequest
    16 from django.shortcuts import get_object_or_404, redirect
    17 from django.shortcuts import get_object_or_404, redirect
    17 from django.views.generic import View
    18 from django.views.generic import View
    39         serializer = RenkanSerializer(renkans, many=True)
    40         serializer = RenkanSerializer(renkans, many=True)
    40         return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
    41         return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
    41 
    42 
    42     def post(self, request, workspace_guid='', format=None):
    43     def post(self, request, workspace_guid='', format=None):
    43         create_data = {key:request.data[key] for key in request.data.keys()}
    44         create_data = {key:request.data[key] for key in request.data.keys()}
    44         source_renkan_guid = request.GET.get("source_renkan_id", request.data.get("source_renkan_id", None))
    45         logger.debug("HELLO %r", create_data)
    45         source_revision_guid = request.GET.get("source_revision_id", request.data.get("source_revision_id", None))
    46 
       
    47         source_renkan_guid_str = request.GET.get("source_renkan_id", request.data.get("source_renkan_id", None))
       
    48         source_revision_guid_str = request.GET.get("source_revision_id", request.data.get("source_revision_id", None))
       
    49         try:
       
    50             source_renkan_guid =  source_renkan_guid_str and uuid.UUID(source_renkan_guid_str) or None
       
    51             source_revision_guid = source_revision_guid_str and uuid.UUID(source_revision_guid_str) or None
       
    52         except ValueError:
       
    53             return Response({'detail': 'Source renkan guid %s or source revision guid %s not correctly formatted'%(source_revision_guid_str, source_revision_guid_str)}, status=status.HTTP_400_BAD_REQUEST)
       
    54 
       
    55         source_revision = None
    46         if source_renkan_guid is not None:
    56         if source_renkan_guid is not None:
    47             try:
    57             try:
    48                 source_renkan=Renkan.objects.get(renkan_guid=source_renkan_guid)
    58                 source_renkan=Renkan.objects.get(renkan_guid=source_renkan_guid)
    49             except Renkan.DoesNotExist:
    59             except Renkan.DoesNotExist:
    50                 return Response({'detail': 'Source renkan '+source_renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
    60                 return Response({'detail': 'Source renkan %s does not exist'%source_renkan_guid}, status=status.HTTP_404_NOT_FOUND)
    51             source_revision_guid = source_renkan.current_revision.revision_guid
    61             source_revision = source_renkan.current_revision
    52         if source_revision_guid is not None:
    62         elif source_revision_guid is not None:
    53             try:
    63             try:
    54                 source_revision=Revision.objects.get(revision_guid=source_revision_guid)
    64                 source_revision=Revision.objects.get(revision_guid=source_revision_guid)
    55             except Revision.DoesNotExist:
    65             except Revision.DoesNotExist:
    56                 return Response({'detail': 'Source revision '+source_revision_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
    66                 return Response({'detail': 'Source revision %s does not exist'%source_revision_guid}, status=status.HTTP_404_NOT_FOUND)
       
    67 
       
    68         if source_revision:
    57             create_data["source_revision_id"] = source_revision.revision_guid
    69             create_data["source_revision_id"] = source_revision.revision_guid
    58             create_data["title"] = request.data.get("title", source_revision.title)
    70             create_data["title"] = request.data.get("title", source_revision.title)
    59             create_data["content"] = source_revision.content
    71             create_data["content"] = source_revision.content
    60         if workspace_guid:
    72             logger.debug("SOURCE_REVISION CONTENT %r", create_data["content"])
       
    73 
       
    74         try:
       
    75             workspace_guid_uuid =  workspace_guid and uuid.UUID(workspace_guid) or None
       
    76         except ValueError:
       
    77             return Response({'detail': 'workspace guid %r not correctly formatted'%workspace_guid}, status=status.HTTP_400_BAD_REQUEST)
       
    78 
       
    79         if workspace_guid_uuid:
    61             try:
    80             try:
    62                 workspace = Workspace.objects.get(workspace_guid=workspace_guid)
    81                 workspace = Workspace.objects.get(workspace_guid=workspace_guid_uuid)
    63             except Workspace.DoesNotExist:
    82             except Workspace.DoesNotExist:
    64                 return Response({'detail': 'Workspace '+workspace_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
    83                 return Response({'detail': 'Workspace '+workspace_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
    65             create_data["workspace_id"] = workspace_guid
    84             create_data["workspace_id"] = workspace_guid
    66         serializer = RenkanSerializer(data=create_data)
    85         serializer = RenkanSerializer(data=create_data)
       
    86         logger.debug("BEFORE SERIALIZER VALID %r", create_data)
    67         if serializer.is_valid():
    87         if serializer.is_valid():
    68             creator = request.user if request.user and not request.user.is_anonymous() else None
    88             creator = request.user if request.user and not request.user.is_anonymous() else None
    69             serializer.save(creator=creator)
    89             serializer.save(creator=creator)
       
    90             logger.debug("AFTER SAVE SERIALIZER DATA %r", serializer.data)
    70             return Response(serializer.data, status=status.HTTP_201_CREATED, content_type='application/json')
    91             return Response(serializer.data, status=status.HTTP_201_CREATED, content_type='application/json')
    71         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    92         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    72 
    93 
    73 
    94 
    74 class RenkanDetail(APIView):
    95 class RenkanDetail(APIView):
    77     """
    98     """
    78     lookup_field = "renkan_guid"
    99     lookup_field = "renkan_guid"
    79     queryset = Renkan.objects
   100     queryset = Renkan.objects
    80 
   101 
    81     def get_object(self, renkan_guid):
   102     def get_object(self, renkan_guid):
    82         return self.queryset.get(renkan_guid=renkan_guid)
   103         try:
       
   104             renkan_uuid = uuid.UUID(renkan_guid)
       
   105         except:
       
   106             raise ValueError('renkan guid %r bad format'%renkan_guid)
       
   107         return self.queryset.get(renkan_guid=renkan_uuid)
    83 
   108 
    84     def dispatch(self, *args, **kwargs):
   109     def dispatch(self, *args, **kwargs):
    85         return super(RenkanDetail, self).dispatch(*args, **kwargs)
   110         return super(RenkanDetail, self).dispatch(*args, **kwargs)
    86 
   111 
    87     def get(self, request, renkan_guid, format=None):
   112     def get(self, request, renkan_guid, format=None):
    88         try:
   113         try:
    89             renkan = self.get_object(renkan_guid=renkan_guid)
   114             renkan = self.get_object(renkan_guid=renkan_guid)
       
   115         except ValueError:
       
   116             return Response({'detail': 'Renkan project %r guid badly formatted'%renkan_guid}, status=status.HTTP_400_BAD_REQUEST)
    90         except Renkan.DoesNotExist:
   117         except Renkan.DoesNotExist:
    91             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
   118             return Response({'detail': 'Renkan project %r does not exist'%renkan_guid}, status=status.HTTP_404_NOT_FOUND)
       
   119 
    92         self.check_object_permissions(request, renkan)
   120         self.check_object_permissions(request, renkan)
    93         serializer = RenkanSerializer(renkan)
   121         serializer = RenkanSerializer(renkan)
    94         if {'true': True, 'false': False, "0": False, "1": True}.get(request.GET.get("content_only", "false").lower()):
   122         if {'true': True, 'false': False, "0": False, "1": True}.get(request.GET.get("content_only", "false").lower()):
    95             return Response(json.loads(serializer.data["content"]), status=status.HTTP_200_OK, content_type='application/json')
   123             return Response(json.loads(serializer.data["content"]), status=status.HTTP_200_OK, content_type='application/json')
    96         return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
   124         return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
    97 
   125 
    98     def put(self, request, renkan_guid, format=None):
   126     def put(self, request, renkan_guid, format=None):
    99         try:
   127         try:
   100             renkan = self.get_object(renkan_guid=renkan_guid)
   128             renkan = self.get_object(renkan_guid=renkan_guid)
       
   129         except ValueError:
       
   130             return Response({'detail': 'Renkan project %r guid badly formatted'%renkan_guid}, status=status.HTTP_400_BAD_REQUEST)
   101         except Renkan.DoesNotExist:
   131         except Renkan.DoesNotExist:
   102             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
   132             return Response({'detail': 'Renkan project %r does not exist'%renkan_guid}, status=status.HTTP_404_NOT_FOUND)
   103         logger.debug("RENKAN PUT %r : CHECKING OBJECT PERMISSION", renkan_guid)
   133         logger.debug("RENKAN PUT %r : CHECKING OBJECT PERMISSION", renkan_guid)
   104         logger.debug("RENKAN PUT: permission? %r", request.user.has_perm("change_renkan", renkan))
   134         logger.debug("RENKAN PUT: permission? %r", request.user.has_perm("change_renkan", renkan))
   105         self.check_object_permissions(request, renkan)
   135         self.check_object_permissions(request, renkan)
   106         logger.debug("RENKAN PUT: PERMISSION GRANTED")
   136         logger.debug("RENKAN PUT: PERMISSION GRANTED")
   107         if {'true': True, 'false': False, "0": False, "1": True}.get(request.GET.get("content_only", "false").lower()):
   137         if {'true': True, 'false': False, "0": False, "1": True}.get(request.GET.get("content_only", "false").lower()):
   115         serializer = RenkanSerializer(renkan, data=put_data)
   145         serializer = RenkanSerializer(renkan, data=put_data)
   116         if serializer.is_valid():
   146         if serializer.is_valid():
   117             serializer.save(updator=request.user)
   147             serializer.save(updator=request.user)
   118             if {'true': True, 'false': False, "0": False, "1": True}.get(request.GET.get("content_only", "false").lower()):
   148             if {'true': True, 'false': False, "0": False, "1": True}.get(request.GET.get("content_only", "false").lower()):
   119                 return Response(json.loads(serializer.data["content"]), status=status.HTTP_200_OK, content_type='application/json')
   149                 return Response(json.loads(serializer.data["content"]), status=status.HTTP_200_OK, content_type='application/json')
       
   150             logger.debug("RENKAN PUT: SERIALIZER DATA %r", serializer.data)
   120             return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
   151             return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
   121         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
   152         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
   122 
   153 
   123     @transaction.atomic
   154     @transaction.atomic
   124     def delete(self, request, renkan_guid, format=None):
   155     def delete(self, request, renkan_guid, format=None):
   125         try:
   156         try:
   126             to_delete_renkan = self.get_object(renkan_guid=renkan_guid)
   157             to_delete_renkan = self.get_object(renkan_guid=renkan_guid)
       
   158         except ValueError:
       
   159             return Response({'detail': 'Renkan project %r guid badly formatted'%renkan_guid}, status=status.HTTP_400_BAD_REQUEST)
   127         except Renkan.DoesNotExist:
   160         except Renkan.DoesNotExist:
   128             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
   161             return Response({'detail': 'Renkan project %r does not exist'%renkan_guid}, status=status.HTTP_404_NOT_FOUND)
   129         self.check_object_permissions(request, to_delete_renkan)
   162         self.check_object_permissions(request, to_delete_renkan)
   130         to_delete_renkan.delete()
   163         to_delete_renkan.delete()
   131         return Response(status=status.HTTP_204_NO_CONTENT)
   164         return Response(status=status.HTTP_204_NO_CONTENT)
   132 
   165 
   133 class WorkspaceList(APIView):
   166 class WorkspaceList(APIView):
   157 
   190 
   158     lookup_field = "workspace_guid"
   191     lookup_field = "workspace_guid"
   159     queryset = Workspace.objects
   192     queryset = Workspace.objects
   160 
   193 
   161     def get_object(self, workspace_guid):
   194     def get_object(self, workspace_guid):
   162         return self.queryset.get(workspace_guid=workspace_guid)
   195         try:
       
   196             workspace_uuid = uuid.UUID(workspace_guid)
       
   197         except:
       
   198             raise ValueError('workspace guid %r bad format'%workspace_guid)
       
   199 
       
   200         return self.queryset.get(workspace_guid=workspace_uuid)
   163 
   201 
   164     def get(self, request, workspace_guid, format=None):
   202     def get(self, request, workspace_guid, format=None):
   165         try:
   203         try:
   166             workspace = self.get_object(workspace_guid=workspace_guid)
   204             workspace = self.get_object(workspace_guid=workspace_guid)
       
   205         except ValueError:
       
   206             return Response({'detail': 'Workspace %r guid badly formatted'%workspace_guid}, status=status.HTTP_400_BAD_REQUEST)
   167         except Workspace.DoesNotExist:
   207         except Workspace.DoesNotExist:
   168             return Response({'detail': 'Workspace '+workspace_guid+' does not exist.'}, status=status.HTTP_404_NOT_FOUND)
   208             return Response({'detail': 'Workspace %r does not exist.'%workspace_guid}, status=status.HTTP_404_NOT_FOUND)
       
   209 
       
   210 
   169         self.check_object_permissions(request, workspace)
   211         self.check_object_permissions(request, workspace)
   170         serializer = WorkspaceSerializer(workspace)
   212         serializer = WorkspaceSerializer(workspace)
   171         return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
   213         return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
   172 
   214 
   173     def put(self, request, workspace_guid, format=None):
   215     def put(self, request, workspace_guid, format=None):
   174         try:
   216         try:
   175             workspace = self.get_object(workspace_guid=workspace_guid)
   217             workspace = self.get_object(workspace_guid=workspace_guid)
       
   218         except ValueError:
       
   219             return Response({'detail': 'Workspace %r guid badly formatted'%workspace_guid}, status=status.HTTP_400_BAD_REQUEST)
   176         except Workspace.DoesNotExist:
   220         except Workspace.DoesNotExist:
   177             return Response({'detail': 'Workspace '+workspace_guid+' does not exist.'}, status=status.HTTP_404_NOT_FOUND)
   221             return Response({'detail': 'Workspace %r does not exist.'%workspace_guid}, status=status.HTTP_404_NOT_FOUND)
       
   222 
   178         self.check_object_permissions(request, workspace)
   223         self.check_object_permissions(request, workspace)
   179         serializer = WorkspaceSerializer(workspace, data=request.data)
   224         serializer = WorkspaceSerializer(workspace, data=request.data)
   180         if serializer.is_valid():
   225         if serializer.is_valid():
   181             serializer.save()
   226             serializer.save()
   182             return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
   227             return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
   183         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
   228         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
   184 
   229 
   185     def delete(self, request, workspace_guid, format=None):
   230     def delete(self, request, workspace_guid, format=None):
   186         try:
   231         try:
   187             to_delete_workspace = self.get_object(workspace_guid=workspace_guid)
   232             to_delete_workspace = self.get_object(workspace_guid=workspace_guid)
       
   233         except ValueError:
       
   234             return Response({'detail': 'Workspace %r guid badly formatted'%workspace_guid}, status=status.HTTP_400_BAD_REQUEST)
   188         except Workspace.DoesNotExist:
   235         except Workspace.DoesNotExist:
   189             return Response({'detail': 'Workspace '+workspace_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
   236             return Response({'detail': 'Workspace %r does not exist.'%workspace_guid}, status=status.HTTP_404_NOT_FOUND)
       
   237 
   190         self.check_object_permissions(request, to_delete_workspace)
   238         self.check_object_permissions(request, to_delete_workspace)
   191         if to_delete_workspace.renkan_count != 0:
   239         if to_delete_workspace.renkan_count != 0:
   192             return Response({'detail': 'Workspace '+workspace_guid+' cannot be deleted because it is not empty'}, status=status.HTTP_400_BAD_REQUEST)
   240             return Response({'detail': 'Workspace '+workspace_guid+' cannot be deleted because it is not empty'}, status=status.HTTP_400_BAD_REQUEST)
   193         to_delete_workspace.delete()
   241         to_delete_workspace.delete()
   194         return Response(status=status.HTTP_204_NO_CONTENT)
   242         return Response(status=status.HTTP_204_NO_CONTENT)
   217     """
   265     """
   218 
   266 
   219     lookup_field = "revision_guid"
   267     lookup_field = "revision_guid"
   220 
   268 
   221     def get_queryset(self, renkan_guid=""):
   269     def get_queryset(self, renkan_guid=""):
   222         if renkan_guid:
   270         try:
   223             return Revision.objects.filter(parent_renkan__renkan_guid=renkan_guid)
   271             renkan_uuid = renkan_guid and uuid.UUID(renkan_guid)
       
   272         except:
       
   273             raise ValueError("renkan guid %r not correctly formatted"%renkan_guid)
       
   274 
       
   275 
       
   276     def get_revision(self, renkan_guid, revision_guid):
       
   277         try:
       
   278             renkan_uuid = renkan_guid and uuid.UUID(renkan_guid)
       
   279         except:
       
   280             raise ValueError('Renkan project %r guid bad format'%renkan_guid)
       
   281         try:
       
   282             revision_uuid = revision_guid and uuid.UUID(revision_guid)
       
   283         except:
       
   284             raise ValueError('Revision %r guid bad format'%revision_guid)
       
   285 
       
   286         revisions = None
       
   287         if renkan_uuid:
       
   288             revisions = Revision.objects.filter(parent_renkan__renkan_guid=renkan_uuid)
   224         else:
   289         else:
   225             return Revision.objects
   290             revisions = Revision.objects
       
   291         if not revisions:
       
   292             raise ObjectDoesNotExist('Renkan project %r does not exist'%renkan_guid)
       
   293         try:
       
   294             revision = revisions.get(revision_guid=revision_uuid)
       
   295         except Revision.DoesNotExist:
       
   296             raise ObjectDoesNotExist('Revision %r does not exist'%revision_guid)
       
   297         return revisions, revision
   226 
   298 
   227     def get(self, request, renkan_guid, revision_guid, format=None):
   299     def get(self, request, renkan_guid, revision_guid, format=None):
   228         revisions = self.get_queryset(renkan_guid)
   300 
   229         if not revisions:
   301         try:
   230             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
   302             _, revision = self.get_revision(renkan_guid, revision_guid)
   231         try:
   303         except ValueError as e:
   232             revision = revisions.get(revision_guid=revision_guid)
   304             return Response({'detail': e.args[0]}, status=status.HTTP_400_BAD_REQUEST)
   233         except Revision.DoesNotExist:
   305         except ObjectDoesNotExist as e:
   234             return Response({'detail': 'Revision '+revision_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
   306             return Response({'detail': e.args[0]}, status=status.HTTP_404_NOT_FOUND)
       
   307 
   235         self.check_object_permissions(request, revision)
   308         self.check_object_permissions(request, revision)
   236         serializer = RevisionSerializer(revision)
   309         serializer = RevisionSerializer(revision)
   237         return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
   310         return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
   238 
   311 
   239     def delete(self, request, renkan_guid, revision_guid, format=None):
   312     def delete(self, request, renkan_guid, revision_guid, format=None):
   240         revisions = self.get_queryset(renkan_guid)
   313         try:
   241         if not revisions:
   314             revisions, revision = self.get_revision(renkan_guid, revision_guid)
   242             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
   315         except ValueError as e:
   243         try:
   316             return Response({'detail': e.args[0]}, status=status.HTTP_400_BAD_REQUEST)
   244             revision = revisions.get(revision_guid=revision_guid)
   317         except ObjectDoesNotExist as e:
   245         except Revision.DoesNotExist:
   318             return Response({'detail': e.args[0]}, status=status.HTTP_404_NOT_FOUND)
   246             return Response({'detail': 'Revision '+revision_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
   319 
   247         self.check_object_permissions(request, revision)
   320         self.check_object_permissions(request, revision)
   248         if revisions.count() == 1:
   321         if revisions.count() == 1:
   249             return Response({'detail': 'You cannot delete the last remaining revision of a renkan from the Revision API. Try deleting the parent Renkan with the Renkan API'}, status=status.HTTP_400_BAD_REQUEST)
   322             return Response({'detail': 'You cannot delete the last remaining revision of a renkan from the Revision API. Try deleting the parent Renkan with the Renkan API'}, status=status.HTTP_400_BAD_REQUEST)
   250         if revision.is_current_revision:
   323         if revision.is_current_revision:
   251             return Response({'detail': 'You cannot delete the current revision of a renkan from the Revision API.'}, status=status.HTTP_400_BAD_REQUEST)
   324             return Response({'detail': 'You cannot delete the current revision of a renkan from the Revision API.'}, status=status.HTTP_400_BAD_REQUEST)