diff options
| -rw-r--r-- | api/views.py | 124 | 
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")  | 
