From e9d4b61b1fb0d5efa78df56a2529185d3d8fabf5 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 19 Jan 2017 13:51:46 +0100 Subject: Association des cours et groupes à des emplois du temps spécifiques --- admin.py | 18 +++++++++++++----- management/commands/_private.py | 25 ++++++++++++++++++------- management/commands/timetables.py | 33 ++++++++++++++------------------- models.py | 19 ++++++++++++++++++- 4 files changed, 63 insertions(+), 32 deletions(-) diff --git a/admin.py b/admin.py index 99f3398..bdf59a2 100644 --- a/admin.py +++ b/admin.py @@ -1,10 +1,17 @@ from django.contrib import admin -from edt.models import Group, Room, Course +from edt.models import Timetable, Group, Room, Course + + +@admin.register(Timetable) +class TimetableAdmin(admin.ModelAdmin): + prepopulated_fields = {"slug": ("name",)} + list_display = ("name", "url",) @admin.register(Group) class GroupAdmin(admin.ModelAdmin): - pass + list_display = ("name", "timetable",) + list_filter = ("timetable__name",) @admin.register(Room) @@ -15,7 +22,8 @@ class RoomAdmin(admin.ModelAdmin): @admin.register(Course) class CourseAdmin(admin.ModelAdmin): fieldsets = ( - (None, {"fields": ("name", "type", "groups", "rooms",)}), + (None, {"fields": ("name", "type", "timetable", "groups", "rooms",)}), ("Horaires", {"fields": ("begin", "end",)}),) - list_display = ("name", "type", "begin", "end",) - list_filter = ("type", "groups",) + list_display = ("name", "type", "timetable", "begin", "end",) + list_filter = ("type", "timetable__name", "groups",) + ordering = ("begin",) diff --git a/management/commands/_private.py b/management/commands/_private.py index 4000f6b..4e84363 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -1,6 +1,6 @@ from bs4 import BeautifulSoup from django.utils import timezone -from edt.models import Group, Room +from edt.models import Group, Room, Course import datetime import requests @@ -18,15 +18,26 @@ def add_time(date, time): delta = datetime.timedelta(hours=time.hour, minutes=time.minute) return date + delta -def get_from_db_or_create(cls, name): - obj = cls.objects.all().filter(name=name).first() - if obj == None: +def delete_courses_in_week(year, week): + start = timezone.make_aware(datetime.datetime.strptime("{0}-W{1:02d}-1".format(year, week), "%Y-W%W-%w")) + end = start + datetime.timedelta(weeks=1) + + Course.objects.filter(begin__gte=start, begin__lt=end).delete() + +def get_from_db_or_create(cls, name, timetable=None): + obj = cls.objects.all().filter(name=name) + if timetable is not None: + obj = obj.filter(timetable=timetable) + + obj = obj.first() + if obj is None: obj = cls(name=name) + obj.timetable = timetable obj.save() return obj -def get_events(soup, weeks, week): +def get_events(soup, weeks, week, timetable): for event in soup.find_all("event"): title = None type_ = None @@ -43,7 +54,7 @@ def get_events(soup, weeks, week): type_ = event.category.text if event.resources.group is not None and type_ is not None: - groups = [get_from_db_or_create(Group, item.text) for item in event.resources.group.find_all("item")] + groups = [get_from_db_or_create(Group, item.text, timetable) for item in event.resources.group.find_all("item")] if event.resources.room is not None and groups is not None: rooms = [get_from_db_or_create(Room, item.text) for item in event.resources.room.find_all("item")] @@ -52,7 +63,7 @@ def get_events(soup, weeks, week): begin = add_time(date, datetime.datetime.strptime(event.starttime.text, "%H:%M")) end = add_time(date, datetime.datetime.strptime(event.endtime.text, "%H:%M")) - yield (title, type_, groups, rooms, begin, end,) + yield title, type_, groups, rooms, begin, end def get_weeks(soup): weeks = {} diff --git a/management/commands/timetables.py b/management/commands/timetables.py index 58897a1..60c9eb5 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -1,38 +1,33 @@ from django.core.management.base import BaseCommand, CommandError from django.utils import timezone -from edt.models import Group, Room, Course +from edt.models import Timetable, Group, Room, Course from bs4 import BeautifulSoup -from ._private import get_events, get_weeks, get_xml, Week +from ._private import delete_courses_in_week, get_events, get_weeks, get_xml, Week import datetime import requests + class Command(BaseCommand): help = "Fetches the specified celcat timetable" - def add_arguments(self, parser): - parser.add_argument("url", type=str) - def handle(self, *args, **options): - url = options["url"] - - _, week, day = timezone.now().isocalendar() + year, week, day = timezone.now().isocalendar() if day >= 6: - _, week, _ = (timezone.now() + datetime.timedelta(weeks=1)).isocalendar() + year, week, _ = (timezone.now() + datetime.timedelta(weeks=1)).isocalendar() - soup = get_xml(url) - weeks = get_weeks(soup) + delete_courses_in_week(year, week) - for name, type_, groups, rooms, begin, end in get_events(soup, weeks, week): - - course = Course.objects.create(begin=begin, end=end) + for timetable in Timetable.objects.all(): + soup = get_xml(timetable.url) + weeks = get_weeks(soup) - course.name = name - course.type = type_ - course.groups.add(*groups) - course.rooms.add(*rooms) - course.save() + for name, type_, groups, rooms, begin, end in get_events(soup, weeks, week, timetable): + course = Course.objects.create(name=name, type=type_, timetable=timetable, begin=begin, end=end) + course.groups.add(*groups) + course.rooms.add(*rooms) + course.save() self.stdout.write(self.style.SUCCESS("Done.")) diff --git a/models.py b/models.py index a70e15c..09bf876 100644 --- a/models.py +++ b/models.py @@ -1,8 +1,23 @@ from django.db import models +class Timetable(models.Model): + name = models.CharField(max_length=64, unique=True, verbose_name="nom") + url = models.URLField(max_length=255, unique=True, verbose_name="URL") + slug = models.SlugField(max_length=64, unique=True, default="") + + def __str__(self): + return self.name + + + class Meta: + verbose_name = "emploi du temps" + verbose_name_plural = "emplois du temps" + + class Group(models.Model): - name = models.CharField(max_length=255, unique=True, verbose_name="nom") + name = models.CharField(max_length=255, verbose_name="nom") + timetable = models.ForeignKey(Timetable, on_delete=models.CASCADE, verbose_name="emploi du temps") def __str__(self): return self.name @@ -11,6 +26,7 @@ class Group(models.Model): class Meta: verbose_name = "groupe" verbose_name_plural = "groupes" + unique_together = ("name", "timetable",) class Room(models.Model): @@ -28,6 +44,7 @@ class Room(models.Model): class Course(models.Model): name = models.CharField(max_length=255, verbose_name="nom") type_ = models.CharField(name="type", max_length=255, verbose_name="type de cours") + timetable = models.ForeignKey(Timetable, on_delete=models.CASCADE, verbose_name="emploi du temps") groups = models.ManyToManyField(Group, verbose_name="groupes") rooms = models.ManyToManyField(Room, verbose_name="salles") -- cgit v1.2.1