server/python2/django/renkanmanager/api/views.py
changeset 587 fb0041aa74d3
child 588 95536fa18d0d
equal deleted inserted replaced
586:e2e952fcaf7c 587:fb0041aa74d3
       
     1 # -*- coding: utf-8 -*-
       
     2 '''
       
     3 Created on Jul 01, 2014
       
     4 
       
     5 @author: tc
       
     6 '''
       
     7 from datetime import datetime
       
     8 import json
       
     9 import logging
       
    10 import uuid
       
    11 
       
    12 from django.core.urlresolvers import reverse
       
    13 from django.http import Http404
       
    14 from django.http.response import HttpResponse, HttpResponseBadRequest
       
    15 from django.shortcuts import get_object_or_404, redirect
       
    16 from django.views.decorators.csrf import csrf_exempt
       
    17 from django.views.generic import View
       
    18 from renkanmanager.models import Renkan, Revision, Workspace
       
    19 from renkanmanager.permissions import CanEditRenkan, CanDeleteRenkan, CanCreateRenkan, \
       
    20                                       CanEditWorkspace, CanDeleteWorkspace, CanCreateWorkspace, \
       
    21                                       CanDeleteRevision
       
    22 from renkanmanager.serializers import RenkanSerializer, RevisionSerializer, WorkspaceSerializer
       
    23 from renkanmanager.utils import LineNodePlacer, renkan_copier, renkan_deleter
       
    24 from rest_framework import permissions, status
       
    25 from rest_framework.response import Response
       
    26 from rest_framework.views import APIView
       
    27 
       
    28 
       
    29 logger = logging.getLogger(__name__)
       
    30             
       
    31 class RenkanList(APIView):
       
    32     """
       
    33         View for listing renkans or posting new renkan
       
    34     """
       
    35     permission_classes = (
       
    36         permissions.IsAuthenticatedOrReadOnly,
       
    37         CanCreateRenkan,
       
    38     )
       
    39     
       
    40     def get(self, request, workspace_guid='', format=None):
       
    41         if workspace_guid == '':
       
    42             renkans = Renkan.objects.all()
       
    43         else:
       
    44             renkans = Renkan.objects.filter(workspace_guid=workspace_guid)
       
    45         serializer = RenkanSerializer(renkans, many=True)
       
    46         return Response(serializer.data, status=status.HTTP_200_OK)    
       
    47     
       
    48     def post(self, request, workspace_guid='', format=None):
       
    49         create_data = request.data
       
    50         # We check if the POST request is a copy request, either with ?source="id" query arg or with source_revision_guid present in the data
       
    51         source_revision_guid = request.GET.get("source", None) if request.GET.get("source", None) is not None else request.data.get("source_revision_guid", None)
       
    52         if source_revision_guid is not None:
       
    53             try:
       
    54                 source_revision=Revision.objects.get(revision_guid=source_revision_guid)
       
    55             except Revision.DoesNotExist:
       
    56                 return Response({'detail': 'Source revision '+source_revision_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
    57             create_data["source_revision_guid"] = source_revision.revision_guid
       
    58             create_data["title"] = source_revision.title
       
    59             create_data["content"] = source_revision.content
       
    60         if workspace_guid:
       
    61             try:
       
    62                 workspace = Workspace.objects.get(workspace_guid=workspace_guid)
       
    63             except Workspace.DoesNotExist:
       
    64                 return Response({'detail': 'Workspace '+workspace_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
    65             create_data["workspace_guid"] = workspace_guid
       
    66         serializer = RenkanSerializer(data=create_data)
       
    67         if serializer.is_valid():
       
    68             serializer.save(creator=request.user)       
       
    69             return Response(serializer.data, status=status.HTTP_201_CREATED)
       
    70         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
       
    71         
       
    72 
       
    73 class RenkanDetail(APIView):
       
    74     """
       
    75         View for retrieving, updating or deleting a single renkan
       
    76     """
       
    77     lookup_field = "renkan_guid"
       
    78     permission_classes = (
       
    79         permissions.IsAuthenticatedOrReadOnly, 
       
    80         CanEditRenkan,
       
    81         CanDeleteRenkan,
       
    82     )
       
    83     
       
    84     def get_object(self, renkan_guid):
       
    85         return Renkan.objects.get(renkan_guid=renkan_guid)
       
    86     
       
    87     def get(self, request, renkan_guid, format=None):
       
    88         try:
       
    89             renkan = self.get_object(renkan_guid=renkan_guid)
       
    90         except Renkan.DoesNotExist:
       
    91             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
    92         self.check_object_permissions(request, renkan)
       
    93         serializer = RenkanSerializer(renkan)
       
    94         return Response(serializer.data, status=status.HTTP_200_OK)
       
    95     
       
    96     def put(self, request, renkan_guid, format=None):
       
    97         try:
       
    98             renkan = self.get_object(renkan_guid=renkan_guid)
       
    99         except Renkan.DoesNotExist:
       
   100             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   101         self.check_object_permissions(request, renkan)
       
   102         serializer = RenkanSerializer(renkan, data=request.data)
       
   103         if serializer.is_valid():
       
   104             serializer.save(updator=request.user)
       
   105             return Response(serializer.data, status=status.HTTP_200_OK)
       
   106         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
       
   107     
       
   108     def delete(self, request, renkan_guid, format=None):
       
   109         try:
       
   110             to_delete_renkan = self.get_object(renkan_guid=renkan_guid)
       
   111         except Renkan.DoesNotExist:
       
   112             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   113         self.check_object_permissions(request, to_delete_renkan)
       
   114         renkan_revisions = Revision.objects.filter(parent_renkan_guid = to_delete_renkan.renkan_guid)
       
   115         for child_revision in renkan_revisions:
       
   116             # Deleting reference to revision in renkans copied from this revision
       
   117             for related_renkan in Renkan.objects.filter(source_revision_guid=child_revision.revision_guid):
       
   118                 related_renkan.source_revision_guid = ''
       
   119                 related_renkan.save()
       
   120             child_revision.delete()
       
   121         to_delete_renkan.delete()
       
   122         return Response(status=status.HTTP_204_NO_CONTENT)
       
   123 
       
   124 class WorkspaceList(APIView):
       
   125     """
       
   126         View for listing workspaces or creating new workspace
       
   127     """
       
   128     permission_classes = (
       
   129         permissions.IsAuthenticatedOrReadOnly,
       
   130         CanCreateWorkspace,
       
   131     )
       
   132     
       
   133     def get(self, request, format=None):
       
   134         workspaces = Workspace.objects.all()
       
   135         serializer = WorkspaceSerializer(workspaces, many=True)
       
   136         return Response(serializer.data)
       
   137     
       
   138     def post(self, request, format=None):
       
   139         serializer = WorkspaceSerializer(data=request.data)
       
   140         if serializer.is_valid():
       
   141             serializer.save(creator=request.user)       
       
   142             return Response(serializer.data, status=status.HTTP_201_CREATED)
       
   143         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
       
   144     
       
   145 class WorkspaceDetail(APIView):
       
   146     """
       
   147         View for retrieving, updating or deleting a single workspace
       
   148     """
       
   149     permission_classes = (
       
   150         permissions.IsAuthenticatedOrReadOnly,
       
   151         CanEditWorkspace,
       
   152         CanDeleteWorkspace,
       
   153     )
       
   154     
       
   155     def get_object(self, workspace_guid):
       
   156         return Workspace.objects.get(workspace_guid=workspace_guid)
       
   157     
       
   158     def get(self, request, workspace_guid, format=None):
       
   159         try:
       
   160             workspace = Workspace.objects.get(workspace_guid=workspace_guid)
       
   161         except Workspace.DoesNotExist:
       
   162             return Response({'detail': 'Workspace '+workspace_guid+' does not exist.'}, status=status.HTTP_404_NOT_FOUND)
       
   163         self.check_object_permissions(request, workspace)
       
   164         serializer = WorkspaceSerializer(workspace)
       
   165         return Response(serializer.data, status=status.HTTP_200_OK)
       
   166     
       
   167     def put(self, request, workspace_guid, format=None):
       
   168         try:
       
   169             workspace = Workspace.objects.get(workspace_guid=workspace_guid)
       
   170         except Workspace.DoesNotExist:
       
   171             return Response({'detail': 'Workspace '+workspace_guid+' does not exist.'}, status=status.HTTP_404_NOT_FOUND)
       
   172         self.check_object_permissions(request, workspace)
       
   173         serializer = WorkspaceSerializer(workspace, data=request.data)
       
   174         if serializer.is_valid():
       
   175             serializer.save()       
       
   176             return Response(serializer.data, status=status.HTTP_200_OK)
       
   177         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
       
   178     
       
   179     def delete(self, request, workspace_guid, format=None):
       
   180         try:
       
   181             to_delete_workspace = self.get_object(workspace_guid=workspace_guid)
       
   182         except Workspace.DoesNotExist:
       
   183             return Response({'detail': 'Workspace '+workspace_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   184         self.check_object_permissions(request, to_delete_workspace)
       
   185         if to_delete_workspace.renkan_count != 0:
       
   186             return Response({'detail': 'Workspace '+workspace_guid+' cannot be deleted because it is not empty'}, status=status.HTTP_400_BAD_REQUEST)
       
   187         to_delete_workspace.delete()
       
   188         return Response(status=status.HTTP_204_NO_CONTENT)
       
   189 
       
   190 class RevisionList(APIView):
       
   191     """
       
   192         View for listing revisions from a given renkan
       
   193     """
       
   194     permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
       
   195     
       
   196     def get_queryset(self, renkan_guid):
       
   197         return Revision.objects.filter(parent_renkan_guid=renkan_guid)
       
   198     
       
   199     def get(self, request, renkan_guid, format=None):
       
   200         revisions = self.get_queryset(renkan_guid)
       
   201         if not revisions:
       
   202             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   203         serializer = RevisionSerializer(revisions.all(), many=True)
       
   204         return Response(serializer.data, status=status.HTTP_200_OK)
       
   205 
       
   206 class RevisionDetail(APIView):
       
   207     """
       
   208         View for retrieving or deleting a single revision from a given renkan
       
   209     """
       
   210     permission_classes = (
       
   211         permissions.IsAuthenticatedOrReadOnly,
       
   212         CanDeleteRevision,
       
   213     )
       
   214     
       
   215     def get_queryset(self, renkan_guid):
       
   216         return Revision.objects.filter(parent_renkan_guid=renkan_guid)
       
   217     
       
   218     def get(self, request, renkan_guid, revision_guid, format=None):
       
   219         revisions = self.get_queryset(renkan_guid)
       
   220         if not revisions:
       
   221             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   222         try:
       
   223             revision = revisions.get(revision_guid=revision_guid)
       
   224         except Revision.DoesNotExist:
       
   225             return Response({'detail': 'Revision '+revision_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   226         self.check_object_permissions(request, revision)
       
   227         serializer = RevisionSerializer(revision)
       
   228         return Response(serializer.data, status=status.HTTP_200_OK)
       
   229     
       
   230     def delete(self, request, renkan_guid, revision_guid, format=None):
       
   231         revisions = self.get_queryset(renkan_guid)
       
   232         if not revisions:
       
   233             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   234         try:
       
   235             revision = revisions.get(revision_guid=revision_guid)
       
   236         except Revision.DoesNotExist:
       
   237             return Response({'detail': 'Revision '+revision_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   238         self.check_object_permissions(request, revision)
       
   239         if revisions.count() == 1:
       
   240             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)
       
   241         if revision.is_current_revision:
       
   242             return Response({'detail': 'You cannot delete the current revision of a renkan from the Revision API.'}, status=status.HTTP_400_BAD_REQUEST)
       
   243         
       
   244         # Deleting reference to revision in renkans copied from this revision
       
   245         for related_renkan in Renkan.objects.filter(source_revision_guid=revision_guid):
       
   246             related_renkan.source_revision_guid = ''
       
   247             related_renkan.save()
       
   248         revision.delete()
       
   249         return Response(status=status.HTTP_204_NO_CONTENT)