Merge pull request '118_API_update' (#119) from 118_API_update into master
Reviewed-on: SGD-Nord/konova#119
This commit is contained in:
		
						commit
						a58532322e
					
				@ -36,7 +36,12 @@ class APIV1GetTestCase(BaseAPIV1TestCase):
 | 
			
		||||
        """
 | 
			
		||||
        response = self._run_get_request(url)
 | 
			
		||||
        content = json.loads(response.content)
 | 
			
		||||
        geojson = content[str(obj.id)]
 | 
			
		||||
        self.assertIn("rpp", content)
 | 
			
		||||
        self.assertIn("p", content)
 | 
			
		||||
        self.assertIn("next", content)
 | 
			
		||||
        self.assertIn("results", content)
 | 
			
		||||
        paginated_content = content["results"]
 | 
			
		||||
        geojson = paginated_content[str(obj.id)]
 | 
			
		||||
        self.assertEqual(response.status_code, 200, msg=response.content)
 | 
			
		||||
        return geojson
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ from abc import abstractmethod
 | 
			
		||||
 | 
			
		||||
from django.contrib.gis import geos
 | 
			
		||||
from django.contrib.gis.geos import GEOSGeometry
 | 
			
		||||
from django.core.paginator import Paginator
 | 
			
		||||
 | 
			
		||||
from konova.utils.message_templates import DATA_UNSHARED
 | 
			
		||||
 | 
			
		||||
@ -19,6 +20,10 @@ class AbstractModelAPISerializer:
 | 
			
		||||
    lookup = None
 | 
			
		||||
    properties_data = None
 | 
			
		||||
 | 
			
		||||
    rpp = None
 | 
			
		||||
    page_number = None
 | 
			
		||||
    paginator = None
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        abstract = True
 | 
			
		||||
 | 
			
		||||
@ -80,9 +85,12 @@ class AbstractModelAPISerializer:
 | 
			
		||||
        Returns:
 | 
			
		||||
            serialized_data (dict)
 | 
			
		||||
        """
 | 
			
		||||
        entries = self.model.objects.filter(**self.lookup)
 | 
			
		||||
        entries = self.model.objects.filter(**self.lookup).order_by("id")
 | 
			
		||||
        self.paginator = Paginator(entries, self.rpp)
 | 
			
		||||
        requested_entries = self.paginator.page(self.page_number)
 | 
			
		||||
 | 
			
		||||
        serialized_data = {}
 | 
			
		||||
        for entry in entries:
 | 
			
		||||
        for entry in requested_entries.object_list:
 | 
			
		||||
            serialized_data[str(entry.id)] = self._model_to_geo_json(entry)
 | 
			
		||||
        return serialized_data
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -367,7 +367,9 @@ class AbstractCompensationAPISerializerV1Mixin:
 | 
			
		||||
        """
 | 
			
		||||
        actions = []
 | 
			
		||||
        for entry in actions_data:
 | 
			
		||||
            action = entry["action"]
 | 
			
		||||
            action_types = [
 | 
			
		||||
                self._konova_code_from_json(e, CODELIST_COMPENSATION_ACTION_ID) for e in entry["action_types"]
 | 
			
		||||
            ]
 | 
			
		||||
            action_details = [
 | 
			
		||||
                self._konova_code_from_json(e, CODELIST_COMPENSATION_ACTION_DETAIL_ID) for e in entry["action_details"]
 | 
			
		||||
            ]
 | 
			
		||||
@ -384,7 +386,7 @@ class AbstractCompensationAPISerializerV1Mixin:
 | 
			
		||||
            # If this exact data is already existing, we do not create it new. Instead put it's id in the list of
 | 
			
		||||
            # entries, we will use to set the new actions
 | 
			
		||||
            action_entry = obj.actions.filter(
 | 
			
		||||
                action_type__atom_id=action,
 | 
			
		||||
                action_type__in=action_types,
 | 
			
		||||
                amount=amount,
 | 
			
		||||
                unit=unit,
 | 
			
		||||
                comment=comment,
 | 
			
		||||
@ -396,13 +398,13 @@ class AbstractCompensationAPISerializerV1Mixin:
 | 
			
		||||
            else:
 | 
			
		||||
                # Create and add id to list
 | 
			
		||||
                action_entry = CompensationAction.objects.create(
 | 
			
		||||
                    action_type=self._konova_code_from_json(action, CODELIST_COMPENSATION_ACTION_ID),
 | 
			
		||||
                    amount=amount,
 | 
			
		||||
                    unit=unit,
 | 
			
		||||
                    comment=comment,
 | 
			
		||||
                )
 | 
			
		||||
                actions.append(action_entry.id)
 | 
			
		||||
 | 
			
		||||
            action_entry.action_type.set(action_types)
 | 
			
		||||
            action_entry.action_type_details.set(action_details)
 | 
			
		||||
        obj.actions.set(actions)
 | 
			
		||||
        return obj
 | 
			
		||||
@ -438,7 +440,9 @@ class AbstractCompensationAPISerializerV1Mixin:
 | 
			
		||||
        """
 | 
			
		||||
        return [
 | 
			
		||||
            {
 | 
			
		||||
                "action": self._konova_code_to_json(entry.action_type),
 | 
			
		||||
                "action_types": [
 | 
			
		||||
                    self._konova_code_to_json(action) for action in entry.action_type.all()
 | 
			
		||||
                ],
 | 
			
		||||
                "action_details": [
 | 
			
		||||
                    self._konova_code_to_json(detail) for detail in entry.action_type_details.all()
 | 
			
		||||
                ],
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,6 @@ class AbstractAPIViewV1(AbstractAPIView):
 | 
			
		||||
    """ Holds general serialization functions for API v1
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    serializer = None
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        self.lookup = {
 | 
			
		||||
@ -45,11 +44,17 @@ class AbstractAPIViewV1(AbstractAPIView):
 | 
			
		||||
            response (JsonResponse)
 | 
			
		||||
        """
 | 
			
		||||
        try:
 | 
			
		||||
            self.rpp = int(request.GET.get("rpp", self.rpp))
 | 
			
		||||
            self.page_number = int(request.GET.get("p", self.page_number))
 | 
			
		||||
 | 
			
		||||
            self.serializer.rpp = self.rpp
 | 
			
		||||
            self.serializer.page_number = self.page_number
 | 
			
		||||
 | 
			
		||||
            self.serializer.prepare_lookup(id, self.user)
 | 
			
		||||
            data = self.serializer.fetch_and_serialize()
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            return self.return_error_response(e, 500)
 | 
			
		||||
        return JsonResponse(data)
 | 
			
		||||
            return self._return_error_response(e, 500)
 | 
			
		||||
        return self._return_response(request, data)
 | 
			
		||||
 | 
			
		||||
    def post(self, request: HttpRequest):
 | 
			
		||||
        """ Handles the POST request
 | 
			
		||||
@ -67,7 +72,7 @@ class AbstractAPIViewV1(AbstractAPIView):
 | 
			
		||||
            body = json.loads(body)
 | 
			
		||||
            created_id = self.serializer.create_model_from_json(body, self.user)
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            return self.return_error_response(e, 500)
 | 
			
		||||
            return self._return_error_response(e, 500)
 | 
			
		||||
        return JsonResponse({"id": created_id})
 | 
			
		||||
 | 
			
		||||
    def put(self, request: HttpRequest, id=None):
 | 
			
		||||
@ -87,7 +92,7 @@ class AbstractAPIViewV1(AbstractAPIView):
 | 
			
		||||
            body = json.loads(body)
 | 
			
		||||
            updated_id = self.serializer.update_model_from_json(id, body, self.user)
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            return self.return_error_response(e, 500)
 | 
			
		||||
            return self._return_error_response(e, 500)
 | 
			
		||||
        return JsonResponse({"id": updated_id})
 | 
			
		||||
 | 
			
		||||
    def delete(self, request: HttpRequest, id=None):
 | 
			
		||||
@ -104,7 +109,7 @@ class AbstractAPIViewV1(AbstractAPIView):
 | 
			
		||||
        try:
 | 
			
		||||
            success = self.serializer.delete_entry(id, self.user)
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            return self.return_error_response(e, 500)
 | 
			
		||||
            return self._return_error_response(e, 500)
 | 
			
		||||
        return JsonResponse(
 | 
			
		||||
            {
 | 
			
		||||
                "success": success,
 | 
			
		||||
 | 
			
		||||
@ -31,10 +31,22 @@ class AbstractAPIView(View):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    user = None
 | 
			
		||||
    serializer = None
 | 
			
		||||
    rpp = 5  # Results per page default
 | 
			
		||||
    page_number = 1  # Page number default
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        abstract = True
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.response_body_base = {
 | 
			
		||||
            "rpp": None,
 | 
			
		||||
            "p": None,
 | 
			
		||||
            "next": None,
 | 
			
		||||
            "results": None
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    @csrf_exempt
 | 
			
		||||
    def dispatch(self, request, *args, **kwargs):
 | 
			
		||||
        try:
 | 
			
		||||
@ -42,13 +54,14 @@ class AbstractAPIView(View):
 | 
			
		||||
            ksp_token = request.headers.get(KSP_TOKEN_HEADER_IDENTIFIER, None)
 | 
			
		||||
            ksp_user = request.headers.get(KSP_USER_HEADER_IDENTIFIER, None)
 | 
			
		||||
            self.user = APIUserToken.get_user_from_token(ksp_token, ksp_user)
 | 
			
		||||
            request.user = self.user
 | 
			
		||||
            if not self.user.is_default_user():
 | 
			
		||||
                raise PermissionError("Default permissions required")
 | 
			
		||||
        except PermissionError as e:
 | 
			
		||||
            return self.return_error_response(e, 403)
 | 
			
		||||
            return self._return_error_response(e, 403)
 | 
			
		||||
        return super().dispatch(request, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def return_error_response(self, error, status_code=500):
 | 
			
		||||
    def _return_error_response(self, error, status_code=500):
 | 
			
		||||
        """ Returns an error as JsonReponse
 | 
			
		||||
 | 
			
		||||
        Args:
 | 
			
		||||
@ -68,6 +81,31 @@ class AbstractAPIView(View):
 | 
			
		||||
            status=status_code
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def _return_response(self, request: HttpRequest, data):
 | 
			
		||||
        """ Returns all important data into a response object
 | 
			
		||||
 | 
			
		||||
        Args:
 | 
			
		||||
            request (HttpRequest): The incoming request
 | 
			
		||||
            data (dict): The serialized data
 | 
			
		||||
 | 
			
		||||
        Returns:
 | 
			
		||||
            response (JsonResponse): The response to be returned
 | 
			
		||||
        """
 | 
			
		||||
        response = self.response_body_base
 | 
			
		||||
        next_page = self.page_number + 1
 | 
			
		||||
        next_page = next_page if next_page in self.serializer.paginator.page_range else None
 | 
			
		||||
        if next_page is not None:
 | 
			
		||||
            next_url = request.build_absolute_uri(
 | 
			
		||||
                request.path + f"?rpp={self.rpp}&p={next_page}"
 | 
			
		||||
            )
 | 
			
		||||
        else:
 | 
			
		||||
            next_url = None
 | 
			
		||||
        response["rpp"] = self.rpp
 | 
			
		||||
        response["p"] = self.page_number
 | 
			
		||||
        response["next"] = next_url
 | 
			
		||||
        response["results"] = data
 | 
			
		||||
        return JsonResponse(response)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class InterventionCheckAPIView(AbstractAPIView):
 | 
			
		||||
 | 
			
		||||
@ -82,14 +120,14 @@ class InterventionCheckAPIView(AbstractAPIView):
 | 
			
		||||
            response (JsonResponse)
 | 
			
		||||
        """
 | 
			
		||||
        if not self.user.is_zb_user():
 | 
			
		||||
            return self.return_error_response("Permission not granted", 403)
 | 
			
		||||
            return self._return_error_response("Permission not granted", 403)
 | 
			
		||||
        try:
 | 
			
		||||
            obj = Intervention.objects.get(
 | 
			
		||||
                id=id,
 | 
			
		||||
                users__in=[self.user]
 | 
			
		||||
            )
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            return self.return_error_response(e)
 | 
			
		||||
            return self._return_error_response(e)
 | 
			
		||||
 | 
			
		||||
        all_valid, check_details = self.run_quality_checks(obj)
 | 
			
		||||
 | 
			
		||||
@ -161,7 +199,7 @@ class AbstractModelShareAPIView(AbstractAPIView):
 | 
			
		||||
        try:
 | 
			
		||||
            users = self._get_shared_users_of_object(id)
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            return self.return_error_response(e)
 | 
			
		||||
            return self._return_error_response(e)
 | 
			
		||||
 | 
			
		||||
        data = {
 | 
			
		||||
            "users": [
 | 
			
		||||
@ -185,7 +223,7 @@ class AbstractModelShareAPIView(AbstractAPIView):
 | 
			
		||||
        try:
 | 
			
		||||
            success = self._process_put_body(request.body, id)
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            return self.return_error_response(e)
 | 
			
		||||
            return self._return_error_response(e)
 | 
			
		||||
        data = {
 | 
			
		||||
            "success": success,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user