server/python/django2/renkanmanager/api/views.py
changeset 589 0ae11aa255a3
parent 588 95536fa18d0d
child 596 58bcb390c9e2
equal deleted inserted replaced
588:95536fa18d0d 589:0ae11aa255a3
       
     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.auth import CsrfExemptSessionAuthentication
       
    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, content_type='application/json')    
       
    47     
       
    48     def post(self, request, workspace_guid='', format=None):
       
    49         create_data = request.data
       
    50         source_renkan_guid = request.GET.get("source_renkan_id", request.data.get("source_renkan_id", None))
       
    51         source_revision_guid = request.GET.get("source_revision_id", request.data.get("source_revision_id", None))
       
    52         if source_renkan_guid is not None:
       
    53             try:
       
    54                 source_renkan=Renkan.objects.get(renkan_guid=source_renkan_guid)
       
    55             except Renkan.DoesNotExist:
       
    56                 return Response({'detail': 'Source renkan '+source_renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
    57             source_revision_guid = source_renkan.current_revision_guid
       
    58         if source_revision_guid is not None:
       
    59             try:
       
    60                 source_revision=Revision.objects.get(revision_guid=source_revision_guid)
       
    61             except Revision.DoesNotExist:
       
    62                 return Response({'detail': 'Source revision '+source_revision_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
    63             create_data["source_revision_id"] = source_revision.revision_guid
       
    64             create_data["title"] = request.data.get("title", source_revision.title)
       
    65             create_data["content"] = source_revision.content
       
    66         if workspace_guid:
       
    67             try:
       
    68                 workspace = Workspace.objects.get(workspace_guid=workspace_guid)
       
    69             except Workspace.DoesNotExist:
       
    70                 return Response({'detail': 'Workspace '+workspace_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
    71             create_data["workspace_id"] = workspace_guid
       
    72         
       
    73         serializer = RenkanSerializer(data=create_data)
       
    74         if serializer.is_valid():
       
    75             serializer.save(creator=request.user)       
       
    76             return Response(serializer.data, status=status.HTTP_201_CREATED, content_type='application/json')
       
    77         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
       
    78         
       
    79 
       
    80 class RenkanDetail(APIView):
       
    81     """
       
    82         View for retrieving, updating or deleting a single renkan
       
    83     """
       
    84     lookup_field = "renkan_guid"
       
    85     permission_classes = (
       
    86         permissions.IsAuthenticatedOrReadOnly, 
       
    87         CanEditRenkan,
       
    88         CanDeleteRenkan,
       
    89     )
       
    90     authentication_classes = (
       
    91         CsrfExemptSessionAuthentication,
       
    92     )
       
    93     @csrf_exempt
       
    94     def dispatch(self, *args, **kwargs):
       
    95         return super(RenkanDetail, self).dispatch(*args, **kwargs)
       
    96     
       
    97     def get_object(self, renkan_guid):
       
    98         return Renkan.objects.get(renkan_guid=renkan_guid)
       
    99     
       
   100     def get(self, request, renkan_guid, format=None):
       
   101         try:
       
   102             renkan = self.get_object(renkan_guid=renkan_guid)
       
   103         except Renkan.DoesNotExist:
       
   104             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   105         self.check_object_permissions(request, renkan)
       
   106         serializer = RenkanSerializer(renkan)
       
   107         if {'true': True, 'false': False, "0": False, "1": True}.get(request.GET.get("content_only", "false").lower()):
       
   108             return Response(json.loads(serializer.data["content"]), status=status.HTTP_200_OK, content_type='application/json')
       
   109         return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
       
   110     
       
   111     def put(self, request, renkan_guid, format=None):
       
   112         try:
       
   113             renkan = self.get_object(renkan_guid=renkan_guid)
       
   114         except Renkan.DoesNotExist:
       
   115             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   116         self.check_object_permissions(request, renkan)
       
   117         if {'true': True, 'false': False, "0": False, "1": True}.get(request.GET.get("content_only", "false").lower()):
       
   118             put_data = {}
       
   119             put_data["content"] = json.dumps(request.data)
       
   120             put_data["title"] = request.data.get("title", "")
       
   121         else: 
       
   122             put_data = request.data
       
   123         serializer = RenkanSerializer(renkan, data=put_data)
       
   124         if serializer.is_valid():
       
   125             serializer.save(updator=request.user)
       
   126             return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
       
   127         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
       
   128     
       
   129     def delete(self, request, renkan_guid, format=None):
       
   130         try:
       
   131             to_delete_renkan = self.get_object(renkan_guid=renkan_guid)
       
   132         except Renkan.DoesNotExist:
       
   133             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   134         self.check_object_permissions(request, to_delete_renkan)
       
   135         renkan_revisions = Revision.objects.filter(parent_renkan_guid = to_delete_renkan.renkan_guid)
       
   136         for child_revision in renkan_revisions:
       
   137             # Deleting reference to revision in renkans copied from this revision
       
   138             for related_renkan in Renkan.objects.filter(source_revision_guid=child_revision.revision_guid):
       
   139                 related_renkan.source_revision_guid = ''
       
   140                 related_renkan.save()
       
   141             child_revision.delete()
       
   142         to_delete_renkan.delete()
       
   143         return Response(status=status.HTTP_204_NO_CONTENT)
       
   144 
       
   145 class WorkspaceList(APIView):
       
   146     """
       
   147         View for listing workspaces or creating new workspace
       
   148     """
       
   149     permission_classes = (
       
   150         permissions.IsAuthenticatedOrReadOnly,
       
   151         CanCreateWorkspace,
       
   152     )
       
   153     
       
   154     def get(self, request, format=None):
       
   155         workspaces = Workspace.objects.all()
       
   156         serializer = WorkspaceSerializer(workspaces, many=True)
       
   157         return Response(serializer.data)
       
   158     
       
   159     def post(self, request, format=None):
       
   160         serializer = WorkspaceSerializer(data=request.data)
       
   161         if serializer.is_valid():
       
   162             serializer.save(creator=request.user)       
       
   163             return Response(serializer.data, status=status.HTTP_201_CREATED, content_type='application/json')
       
   164         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
       
   165     
       
   166 class WorkspaceDetail(APIView):
       
   167     """
       
   168         View for retrieving, updating or deleting a single workspace
       
   169     """
       
   170     permission_classes = (
       
   171         permissions.IsAuthenticatedOrReadOnly,
       
   172         CanEditWorkspace,
       
   173         CanDeleteWorkspace,
       
   174     )
       
   175     
       
   176     def get_object(self, workspace_guid):
       
   177         return Workspace.objects.get(workspace_guid=workspace_guid)
       
   178     
       
   179     def get(self, request, workspace_guid, format=None):
       
   180         try:
       
   181             workspace = Workspace.objects.get(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, workspace)
       
   185         serializer = WorkspaceSerializer(workspace)
       
   186         return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
       
   187     
       
   188     def put(self, request, workspace_guid, format=None):
       
   189         try:
       
   190             workspace = Workspace.objects.get(workspace_guid=workspace_guid)
       
   191         except Workspace.DoesNotExist:
       
   192             return Response({'detail': 'Workspace '+workspace_guid+' does not exist.'}, status=status.HTTP_404_NOT_FOUND)
       
   193         self.check_object_permissions(request, workspace)
       
   194         serializer = WorkspaceSerializer(workspace, data=request.data)
       
   195         if serializer.is_valid():
       
   196             serializer.save()       
       
   197             return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
       
   198         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
       
   199     
       
   200     def delete(self, request, workspace_guid, format=None):
       
   201         try:
       
   202             to_delete_workspace = self.get_object(workspace_guid=workspace_guid)
       
   203         except Workspace.DoesNotExist:
       
   204             return Response({'detail': 'Workspace '+workspace_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   205         self.check_object_permissions(request, to_delete_workspace)
       
   206         if to_delete_workspace.renkan_count != 0:
       
   207             return Response({'detail': 'Workspace '+workspace_guid+' cannot be deleted because it is not empty'}, status=status.HTTP_400_BAD_REQUEST)
       
   208         to_delete_workspace.delete()
       
   209         return Response(status=status.HTTP_204_NO_CONTENT)
       
   210 
       
   211 class RevisionList(APIView):
       
   212     """
       
   213         View for listing revisions from a given renkan
       
   214     """
       
   215     permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
       
   216     
       
   217     def get_queryset(self, renkan_guid):
       
   218         return Revision.objects.filter(parent_renkan_guid=renkan_guid)
       
   219     
       
   220     def get(self, request, renkan_guid, format=None):
       
   221         revisions = self.get_queryset(renkan_guid)
       
   222         if not revisions:
       
   223             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   224         serializer = RevisionSerializer(revisions.all(), many=True)
       
   225         return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
       
   226 
       
   227 class RevisionDetail(APIView):
       
   228     """
       
   229         View for retrieving or deleting a single revision from a given renkan
       
   230     """
       
   231     permission_classes = (
       
   232         permissions.IsAuthenticatedOrReadOnly,
       
   233         CanDeleteRevision,
       
   234     )
       
   235     
       
   236     def get_queryset(self, renkan_guid):
       
   237         return Revision.objects.filter(parent_renkan_guid=renkan_guid)
       
   238     
       
   239     def get(self, request, renkan_guid, revision_guid, format=None):
       
   240         revisions = self.get_queryset(renkan_guid)
       
   241         if not revisions:
       
   242             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   243         try:
       
   244             revision = revisions.get(revision_guid=revision_guid)
       
   245         except Revision.DoesNotExist:
       
   246             return Response({'detail': 'Revision '+revision_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   247         self.check_object_permissions(request, revision)
       
   248         serializer = RevisionSerializer(revision)
       
   249         return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json')
       
   250     
       
   251     def delete(self, request, renkan_guid, revision_guid, format=None):
       
   252         revisions = self.get_queryset(renkan_guid)
       
   253         if not revisions:
       
   254             return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   255         try:
       
   256             revision = revisions.get(revision_guid=revision_guid)
       
   257         except Revision.DoesNotExist:
       
   258             return Response({'detail': 'Revision '+revision_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND)
       
   259         self.check_object_permissions(request, revision)
       
   260         if revisions.count() == 1:
       
   261             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)
       
   262         if revision.is_current_revision:
       
   263             return Response({'detail': 'You cannot delete the current revision of a renkan from the Revision API.'}, status=status.HTTP_400_BAD_REQUEST)
       
   264         
       
   265         # Deleting reference to revision in renkans copied from this revision
       
   266         for related_renkan in Renkan.objects.filter(source_revision_guid=revision_guid):
       
   267             related_renkan.source_revision_guid = ''
       
   268             related_renkan.save()
       
   269         revision.delete()
       
   270         return Response(status=status.HTTP_204_NO_CONTENT)