diff options
Diffstat (limited to 'management/commands/timetables.py')
-rw-r--r-- | management/commands/timetables.py | 94 |
1 files changed, 55 insertions, 39 deletions
diff --git a/management/commands/timetables.py b/management/commands/timetables.py index ff00c8f..f92ad4e 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Alban Gruin +# Copyright (C) 2017-2018 Alban Gruin # # celcatsanitizer is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published @@ -20,12 +20,16 @@ from django.core.management.base import BaseCommand from django.db import transaction from django.db.models import Min -from edt.models import Course, Timetable -from edt.utils import get_week, tz_now -from ._private import delete_courses_in_week, get_events, get_update_date, get_weeks, get_xml +from ...models import Course, Source +from ...utils import get_week, tz_now + +from ._private import delete_courses_in_week, get_events, get_update_date, \ + get_weeks, get_xml + @transaction.atomic -def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, week=None): +def process_timetable_week(source, soup, weeks_in_soup, force, + year=None, week=None): if year is not None and week is not None: begin, end = get_week(year, week) @@ -40,75 +44,83 @@ def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, wee else: today = tz_now() - # On récupère la mise à jour la plus ancienne dans les cours de l’emploi du temps - last_update_date = Course.objects.filter(timetable=timetable) + # On récupère la mise à jour la plus ancienne dans les cours de + # l’emploi du temps + last_update_date = Course.objects.filter(source=source) if today is not None: - # Cette date concerne les éléments commençant à partir d’aujourd’hui si la valeur - # n’est pas nulle. + # Cette date concerne les éléments commençant à partir + # d’aujourd’hui si la valeur n’est pas nulle. last_update_date = last_update_date.filter(begin__gte=today) if year is not None and week is not None: - # Si jamais on traite une semaine spécifique, on limite les cours sélectionnés - # à ceux qui commencent entre le début du traitement et la fin de la semaine + # Si jamais on traite une semaine spécifique, on limite les + # cours sélectionnés à ceux qui commencent entre le début du + # traitement et la fin de la semaine last_update_date = last_update_date.filter(begin__lt=end) - last_update_date = last_update_date.aggregate(Min("last_update")) \ - ["last_update__min"] + last_update_date = last_update_date.aggregate( + Min("last_update"))["last_update__min"] # Date de mise à jour de Celcat, utilisée à des fins de statistiques new_update_date = get_update_date(soup) - # On ne fait pas la mise à jour si jamais la dernière date de MàJ est plus récente - # que celle indiquée par Celcat. - # Attention, le champ last_update de la classe Course représente l’heure à laquelle - # le cours a été inséré dans la base de données, et non pas la date indiquée par - # Celcat. - if not force and last_update_date is not None and new_update_date is not None and \ - last_update_date >= new_update_date: + # On ne fait pas la mise à jour si jamais la dernière date de MàJ + # est plus récente que celle indiquée par Celcat. Attention, le + # champ last_update de la classe Course représente l’heure à + # laquelle le cours a été inséré dans la base de données, et non + # pas la date indiquée par Celcat. + if not force and last_update_date is not None and \ + new_update_date is not None and last_update_date >= new_update_date: return if year is not None and week is not None: # On efface la semaine à partir de maintenant si jamais # on demande le traitement d’une seule semaine - delete_courses_in_week(timetable, year, week, today) + delete_courses_in_week(source, year, week, today) else: # Sinon, on efface tous les cours à partir de maintenant. # Précisément, on prend la plus grande valeur entre la première semaine # présente dans Celcat et maintenant. delete_from = min(weeks_in_soup.values()) if not force: - # Si jamais on force la MàJ, on efface tout à partir de la première semaine + # Si jamais on force la MàJ, on efface tout à partir de la + # première semaine delete_from = max(delete_from, today) - Course.objects.filter(timetable=timetable, begin__gte=delete_from).delete() + Course.objects.filter(source=source, begin__gte=delete_from).delete() # Tous les cours commençant sur la période traitée # sont parsés, puis enregistrés dans la base de données. - for course in get_events(timetable, soup, weeks_in_soup, today, year, week): + for course in get_events(source, soup, weeks_in_soup, today, year, week): course.save() # On renseigne la date de mise à jour de Celcat, à des fins de statistiques - timetable.last_update_date = new_update_date - timetable.save() + source.last_update_date = new_update_date + source.save() + -def process_timetable(timetable, force, year=None, weeks=None): - soup = get_xml(timetable.url) +def process_timetable(source, force, year=None, weeks=None): + soup = get_xml(source.url) weeks_in_soup = get_weeks(soup) if year is not None and weeks is not None: for week in weeks: - process_timetable_week(timetable, soup, weeks_in_soup, force, year, week) + process_timetable_week(source, soup, weeks_in_soup, force, + year, week) else: - process_timetable_week(timetable, soup, weeks_in_soup, force) + process_timetable_week(source, soup, weeks_in_soup, force) class Command(BaseCommand): help = "Fetches registered celcat timetables" def add_arguments(self, parser): - parser.add_argument("--all", const=True, default=False, action="store_const") - parser.add_argument("--force", const=True, default=False, action="store_const") - parser.add_argument("--week", type=int, choices=range(1, 54), nargs="+") + parser.add_argument("--all", const=True, default=False, + action="store_const") + parser.add_argument("--force", const=True, default=False, + action="store_const") + parser.add_argument("--week", type=int, choices=range(1, 54), + nargs="+") parser.add_argument("--year", type=int, nargs=1) def handle(self, *args, **options): @@ -120,7 +132,8 @@ class Command(BaseCommand): elif options["week"] is None: _, week, day = tz_now().isocalendar() if day >= 6: - year, week, _ = (tz_now() + datetime.timedelta(weeks=1)).isocalendar() + year, week, _ = (tz_now() + datetime.timedelta(weeks=1)) \ + .isocalendar() weeks = [week] else: weeks = options["week"] @@ -131,16 +144,18 @@ class Command(BaseCommand): elif year is None: year = options["year"][0] - for timetable in Timetable.objects.all(): - self.stdout.write("Processing {0}".format(timetable)) + for source in Source.objects.all(): + self.stdout.write("Processing {0}".format( + source.formatted_timetables)) try: - process_timetable(timetable, options["force"], year, weeks) + process_timetable(source, options["force"], year, weeks) except KeyboardInterrupt: break except Exception: self.stderr.write( - self.style.ERROR("Failed to process {0}:".format(timetable)) + self.style.ERROR("Failed to process {0}:".format( + source.formatted_timetables)) ) self.stderr.write(self.style.ERROR(traceback.format_exc())) errcount += 1 @@ -148,4 +163,5 @@ class Command(BaseCommand): if errcount == 0: self.stdout.write(self.style.SUCCESS("Done.")) else: - self.stdout.write(self.style.ERROR("Done with {0} errors.".format(errcount))) + self.stdout.write(self.style.ERROR("Done with {0} errors.".format( + errcount))) |