From e7f2ccdd870f998b9199b85bf2c486f8d1d0cceb Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sat, 25 Aug 2018 22:54:33 +0200 Subject: management: création d’un sous-module parser Signed-off-by: Alban Gruin --- management/commands/timetables.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'management/commands/timetables.py') diff --git a/management/commands/timetables.py b/management/commands/timetables.py index f92ad4e..8fc8ed6 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -23,8 +23,8 @@ from django.db.models import Min 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 +from ..parsers.ups2017 import delete_courses_in_week, get_events, \ + get_update_date, get_weeks, get_xml @transaction.atomic -- cgit v1.2.1 From 77b6ade4a7d465ca0fbc6b82950f3b54689d60e3 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sat, 25 Aug 2018 23:01:31 +0200 Subject: parsers: déplacement de delete_courses_in_week() vers timetable.py Signed-off-by: Alban Gruin --- management/commands/timetables.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'management/commands/timetables.py') diff --git a/management/commands/timetables.py b/management/commands/timetables.py index 8fc8ed6..c148fed 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -23,8 +23,14 @@ from django.db.models import Min from ...models import Course, Source from ...utils import get_week, tz_now -from ..parsers.ups2017 import delete_courses_in_week, get_events, \ - get_update_date, get_weeks, get_xml +from ..parsers.ups2017 import get_events, get_update_date, get_weeks, \ + get_source + + +def delete_courses_in_week(source, year, week, today): + start, end = get_week(year, week) + Course.objects.filter(begin__gte=max(start, today), begin__lt=end, + source=source).delete() @transaction.atomic @@ -100,7 +106,7 @@ def process_timetable_week(source, soup, weeks_in_soup, force, def process_timetable(source, force, year=None, weeks=None): - soup = get_xml(source.url) + soup = get_source(source.url) weeks_in_soup = get_weeks(soup) if year is not None and weeks is not None: -- cgit v1.2.1 From d02046f9255a07c4eb2bda9eb73d229cdb4f4a53 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Mon, 27 Aug 2018 17:43:16 +0200 Subject: parsers: parseur orienté objet avec une classe abstraite Signed-off-by: Alban Gruin --- management/commands/timetables.py | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'management/commands/timetables.py') diff --git a/management/commands/timetables.py b/management/commands/timetables.py index c148fed..c5159b7 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -13,9 +13,12 @@ # You should have received a copy of the GNU Affero General Public License # along with celcatsanitizer. If not, see . +from importlib import import_module + import datetime import traceback +from django.conf import settings from django.core.management.base import BaseCommand from django.db import transaction from django.db.models import Min @@ -23,8 +26,7 @@ from django.db.models import Min from ...models import Course, Source from ...utils import get_week, tz_now -from ..parsers.ups2017 import get_events, get_update_date, get_weeks, \ - get_source +DEFAULT_PARSER = "edt.management.parsers.ups2017" def delete_courses_in_week(source, year, week, today): @@ -34,8 +36,7 @@ def delete_courses_in_week(source, year, week, today): @transaction.atomic -def process_timetable_week(source, soup, weeks_in_soup, force, - year=None, week=None): +def process_timetable_week(source, force, parser, year=None, week=None): if year is not None and week is not None: begin, end = get_week(year, week) @@ -69,7 +70,7 @@ def process_timetable_week(source, soup, weeks_in_soup, force, 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) + new_update_date = parser.get_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 @@ -88,7 +89,7 @@ def process_timetable_week(source, soup, weeks_in_soup, force, # 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()) + delete_from = min(parser.weeks.values()) if not force: # Si jamais on force la MàJ, on efface tout à partir de la # première semaine @@ -97,7 +98,7 @@ def process_timetable_week(source, soup, weeks_in_soup, force, # 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(source, soup, weeks_in_soup, today, year, week): + for course in parser.get_events(today, year, week): course.save() # On renseigne la date de mise à jour de Celcat, à des fins de statistiques @@ -105,16 +106,16 @@ def process_timetable_week(source, soup, weeks_in_soup, force, source.save() -def process_timetable(source, force, year=None, weeks=None): - soup = get_source(source.url) - weeks_in_soup = get_weeks(soup) +def process_timetable(source, force, parser_cls, year=None, weeks=None): + parser = parser_cls(source) + parser.get_source() + parser.get_weeks() if year is not None and weeks is not None: for week in weeks: - process_timetable_week(source, soup, weeks_in_soup, force, - year, week) + process_timetable_week(source, force, parser, year, week) else: - process_timetable_week(source, soup, weeks_in_soup, force) + process_timetable_week(source, force, parser) class Command(BaseCommand): @@ -129,9 +130,14 @@ class Command(BaseCommand): nargs="+") parser.add_argument("--year", type=int, nargs=1) + def __get_parser(self): + parser_module = getattr(settings, "CS_PARSER", DEFAULT_PARSER) + return getattr(import_module(parser_module), "Parser") + def handle(self, *args, **options): year = None errcount = 0 + parser = self.__get_parser() if options["all"]: weeks = None @@ -155,7 +161,8 @@ class Command(BaseCommand): source.formatted_timetables)) try: - process_timetable(source, options["force"], year, weeks) + process_timetable(source, options["force"], parser, + year, weeks) except KeyboardInterrupt: break except Exception: -- cgit v1.2.1 From 066391b376649214266f48ab95a021cb98b9dfa2 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Mon, 3 Sep 2018 13:50:59 +0200 Subject: timetables: ne rien faire si une source ne contient pas de semaines Correction d’un bogue qui faisait planter le parseur si on demandait une mise à jour complète alors que la source ne contenait pas de semaines. Désormais, si une source ne contient pas de semaines, la date de mise à jour de la source est modifiée, et aucun cours n’est supprimé ou rajouté. Signed-off-by: Alban Gruin --- management/commands/timetables.py | 42 +++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'management/commands/timetables.py') diff --git a/management/commands/timetables.py b/management/commands/timetables.py index c5159b7..ee33f7e 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -81,25 +81,29 @@ def process_timetable_week(source, force, parser, year=None, week=None): 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(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(parser.weeks.values()) - if not force: - # 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(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 parser.get_events(today, year, week): - course.save() + # Pas de traitement si il n’y a pas de semaine dans l’emploi du temps + if len(parser.weeks.values()): + 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(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(parser.weeks.values()) + if not force: + # 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( + 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 parser.get_events(today, year, week): + course.save() # On renseigne la date de mise à jour de Celcat, à des fins de statistiques source.last_update_date = new_update_date -- cgit v1.2.1