From aaa92af032d59e8a6633583aca564b5df537ea69 Mon Sep 17 00:00:00 2001 From: Ethan Roseman Date: Wed, 24 Aug 2022 10:58:55 +0900 Subject: [PATCH] CategoryDigestView --- frog_api/urls.py | 8 +++--- frog_api/views.py | 63 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/frog_api/urls.py b/frog_api/urls.py index 5ba13a8..7f4f941 100644 --- a/frog_api/urls.py +++ b/frog_api/urls.py @@ -3,10 +3,10 @@ from frog_api import views urlpatterns = [ path("projects/", views.ProjectView.as_view()), - # re_path( - # "data/(?P.+)/(?P.+)/(?P.+)/$", - # views.EntryView.as_view(), - # ), + re_path( + "data/(?P.+)/(?P.+)/(?P.+)/$", + views.CategoryDigestView.as_view(), + ), re_path( "data/(?P.+)/(?P.+)/$", views.VersionDigestView.as_view(), diff --git a/frog_api/views.py b/frog_api/views.py index 4654aa3..e8f921a 100644 --- a/frog_api/views.py +++ b/frog_api/views.py @@ -1,9 +1,9 @@ -from typing import Optional from rest_framework import status +from rest_framework.exceptions import APIException from rest_framework.response import Response from rest_framework.views import APIView -from frog_api.models import Entry, Project, Version +from frog_api.models import Category, Entry, Project, Version from frog_api.serializers import ( ProjectSerializer, TerseEntrySerializer, @@ -24,15 +24,36 @@ class ProjectView(APIView): return Response(serializer.data) -def get_latest_entry(project, version, category) -> Optional[Entry]: - return Entry.objects.filter( +def get_latest_entry(project, version, category) -> dict: + if not Project.objects.filter(slug=project).exists(): + raise APIException( + f"Project {project} not found", code=status.HTTP_404_NOT_FOUND + ) + + if not Version.objects.filter(slug=version, project__slug=project).exists(): + raise APIException( + f"Version '{version}' not found for project '{project}'", + code=status.HTTP_404_NOT_FOUND, + ) + + if not Category.objects.filter( + slug=category, version__slug=version, version__project__slug=project + ).exists(): + raise APIException( + f"Category '{category}' not found for project '{project}' and version '{version}'", + code=status.HTTP_404_NOT_FOUND, + ) + + entry = Entry.objects.filter( category__slug=category, category__version__slug=version, category__version__project__slug=project, ).first() + if entry is None: + raise APIException("Entry is None", code=status.HTTP_404_NOT_FOUND) -def get_entry_json(entry) -> dict: + # Re-format the measures (TODO: DRF-ify this?) entry_data = TerseEntrySerializer(entry).data entry_data["measures"] = {m["type"]: m["value"] for m in entry_data["measures"]} return entry_data @@ -43,7 +64,7 @@ def get_versions_digest_for_project(project) -> dict: for version in Version.objects.filter(project__slug=project): entry = get_latest_entry(project, version.slug, "total") if entry is not None: - versions[version.slug] = get_entry_json(entry) + versions[version.slug] = entry return versions @@ -92,7 +113,7 @@ class ProjectDigestView(APIView): class VersionDigestView(APIView): """ - API endpoint that returns the most recent entry for a version of a project. + API endpoint that returns the most recent entry for overall progress for a version of a project. """ def get(self, request, project, version): @@ -100,17 +121,21 @@ class VersionDigestView(APIView): Return the most recent entry for overall progress for a version of a project. """ - if not Project.objects.filter(slug=project).exists(): - return Response( - f"Project {project} not found", status=status.HTTP_404_NOT_FOUND - ) - - if not Version.objects.filter(slug=version, project__slug=project).exists(): - return Response( - f"Version {version} not found", status=status.HTTP_404_NOT_FOUND - ) - entry = get_latest_entry(project, version, "total") - entry_json = get_entry_json(entry) - return Response(entry_json) + return Response(entry) + + +class CategoryDigestView(APIView): + """ + API endpoint that returns the most recent entry for a specific cagory and a version of a project. + """ + + def get(self, request, project, version, category): + """ + Return the most recent entry for a specific cagory and a version of a project. + """ + + entry = get_latest_entry(project, version, category) + + return Response(entry)