aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlban Gruin2019-01-27 19:29:33 +0100
committerAlban Gruin2019-01-27 19:36:51 +0100
commit549e087ac32484d661197745bccc801856bc2d26 (patch)
tree496dcc1dbb94dcdac58b7f6cd444e95e33af92bb
parent1764d2d8f4ae02a81dd6bea1c9f8a374d9706b63 (diff)
api: complétion des vues de l’API
Ajout de vues permettant de consulter les emplois du temps associés à une année ou à une source, les groupes associés à un emploi du temps, les cours d’un groupe ou d’une salle (soit tous, soit ceux de la semaine courante, soit ceux d’une semaine précise), de lister les semaines de cours, et d’accéder à QSJPS. Signed-off-by: Alban Gruin <alban at pa1ch dot fr>
-rw-r--r--api/views.py124
1 files changed, 122 insertions, 2 deletions
diff --git a/api/views.py b/api/views.py
index c58c9c0..f6aa620 100644
--- a/api/views.py
+++ b/api/views.py
@@ -13,8 +13,20 @@
# You should have received a copy of the GNU Affero General Public License
# along with celcatsanitizer. If not, see <http://www.gnu.org/licenses/>.
+import datetime
+
+from django.db.models import Count
+from django.db.models.functions import ExtractWeek, ExtractYear
+from django.utils import timezone
+
from rest_framework import viewsets
+from rest_framework.decorators import action, detail_route
+from rest_framework.response import Response
+
+from ..forms import QSJPSForm
from ..models import Course, Group, Room, Source, Timetable, Year
+from ..utils import get_current_or_next_week, get_week
+
from .serializers import CourseSerializer, GroupSerializer, RoomSerializer, \
SourceSerializer, TimetableSerializer, YearSerializer
@@ -23,27 +35,135 @@ class YearViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Year.objects.all().order_by("name")
serializer_class = YearSerializer
+ @detail_route(methods=["get"], url_path="timetables")
+ def timetable_list(self, request, pk):
+ year = self.get_object()
+ timetables = Timetable.objects.filter(year=year).distinct() \
+ .order_by("name")
+ timetables_json = TimetableSerializer(
+ self.paginate_queryset(timetables), many=True)
+ return self.get_paginated_response(timetables_json.data)
+
class SourceViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Source.objects.all().order_by("pk")
serializer_class = SourceSerializer
+ @detail_route(methods=["get"], url_path="timetables")
+ def timetable_list(self, request, pk):
+ source = self.get_object()
+ timetables = Timetable.objects.filter(source=source).distinct() \
+ .order_by("name")
+ timetables_json = TimetableSerializer(
+ self.paginate_queryset(timetables), many=True)
+ return self.get_paginated_response(timetables_json.data)
+
class TimetableViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Timetable.objects.all().select_related("source") \
.order_by("year", "name")
serializer_class = TimetableSerializer
+ @detail_route(methods=["get"], url_path="groups")
+ def group_list(self, request, pk):
+ timetable = self.get_object()
+ groups = Group.objects.filter(source=timetable.source).distinct() \
+ .order_by("name")
+ groups_json = GroupSerializer(self.paginate_queryset(groups),
+ many=True)
+ return self.get_paginated_response(groups_json.data)
+
+
+class CourseListGroupSet(viewsets.ReadOnlyModelViewSet):
+ @detail_route(methods=["get"], url_path="courses")
+ def course_list(self, request, pk):
+ obj = self.get_object()
+ courses = Course.objects.get_courses(obj).prefetch_related("groups")
+ courses_json = CourseSerializer(self.paginate_queryset(courses),
+ many=True)
+ return self.get_paginated_response(courses_json.data)
+
+ @detail_route(methods=["get"], url_path="courses/weeks/current")
+ def current_week(self, request, pk):
+ obj = self.get_object()
+ start, end = get_week(*get_current_or_next_week())
+
+ courses = Course.objects.get_courses(obj,
+ begin__gte=start, end__lt=end) \
+ .prefetch_related("groups")
+ courses_json = CourseSerializer(self.paginate_queryset(courses),
+ many=True)
+ return self.get_paginated_response(courses_json.data)
+
+ @detail_route(methods=["get"],
+ url_path="courses/weeks/(?P<year>\d+)/(?P<week>\d+)")
+ def other_week(self, request, pk, year, week):
+ obj = self.get_object()
+
+ errors = {}
+ if not year.isdigit():
+ errors["year"] = "Rentrez une année valide"
+ if not week.isdigit() or not 0 < int(week) <= 53:
+ errors["week"] = "Rentrez une semaine valide"
+ if errors:
+ return Response(errors, status=400)
-class GroupViewSet(viewsets.ReadOnlyModelViewSet):
+ start, end = get_week(int(year), int(week))
+
+ courses = Course.objects.get_courses(obj,
+ begin__gte=start, end__lt=end) \
+ .prefetch_related("groups")
+ courses_json = CourseSerializer(self.paginate_queryset(courses),
+ many=True)
+ return self.get_paginated_response(courses_json.data)
+
+
+class GroupViewSet(CourseListGroupSet):
queryset = Group.objects.all().order_by("name")
serializer_class = GroupSerializer
+ @detail_route(methods=["get"], url_path="courses/weeks")
+ def weeks(self, request, pk):
+ group = self.get_object()
+ groups = Group.objects.get_parents(group)
+
+ courses = Course.objects.filter(groups__in=groups) \
+ .order_by("year", "week") \
+ .annotate(year=ExtractYear("begin"),
+ week=ExtractWeek("begin")) \
+ .values("year", "week") \
+ .annotate(c=Count("*"))
+
+ weeks = [get_week(course["year"], course["week"])[0]
+ for course in courses]
+
+ return Response(weeks)
-class RoomViewSet(viewsets.ReadOnlyModelViewSet):
+
+class RoomViewSet(CourseListGroupSet):
queryset = Room.objects.all().order_by("name")
serializer_class = RoomSerializer
+ @action(
+ methods=["get"],
+ detail=False,
+ url_path="qsjps/(?P<day>[0-9\-]+)/(?P<begin>[0-9:]+)/(?P<end>[0-9:]+)")
+ def qsjps(self, request, day, begin, end):
+ form = QSJPSForm({"day": day, "begin": begin, "end": end})
+ if not form.is_valid():
+ return Response(form.errors, status=400)
+
+ day = form.cleaned_data["day"]
+ begin_hour = form.cleaned_data["begin"]
+ end_hour = form.cleaned_data["end"]
+
+ begin = timezone.make_aware(datetime.datetime.combine(day, begin_hour))
+ end = timezone.make_aware(datetime.datetime.combine(day, end_hour))
+
+ rooms = Room.objects.qsjps(begin, end)
+ rooms_json = RoomSerializer(rooms, many=True)
+ return Response(rooms_json.data)
+
class CourseViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Course.objects.all().prefetch_related("groups", "rooms")