From 295f8cbd261cf588f1f5f8eb2b0d82b1ae9c1fe0 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 5 Oct 2017 09:35:14 +0200 Subject: On ne supprime pas les cours qui commencent avant le début du traitement --- management/commands/_private.py | 13 +++++++++---- management/commands/timetables.py | 9 +++++---- 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index 8f195a1..d576daf 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -65,9 +65,9 @@ def consolidate_groups(groups): if group.parent is None: consolidate_group(group) -def delete_courses_in_week(timetable, year, week): +def delete_courses_in_week(timetable, year, week, today): start, end = get_week(year, week) - Course.objects.filter(begin__gte=start, begin__lt=end, + Course.objects.filter(begin__gte=max(start, today), begin__lt=end, timetable=timetable).delete() def get_from_db_or_create(cls, **kwargs): @@ -128,7 +128,7 @@ def get_event(timetable, event, event_week): return course -def get_events(timetable, soup, weeks_in_soup, year=None, week=None): +def get_events(timetable, soup, weeks_in_soup, today, year=None, week=None): """Récupère tous les cours disponibles dans l’emploi du temps Celcat. Le traîtement se limitera à la semaine indiquée si il y en a une.""" for event in soup.find_all("event"): @@ -142,7 +142,12 @@ def get_events(timetable, soup, weeks_in_soup, year=None, week=None): year is None or week is None) and \ event.resources.group is not None and \ event.starttime is not None and event.endtime is not None: - yield get_event(timetable, event, event_week) + course = get_event(timetable, event, event_week) + + # On ne sauvegarde le cours que si il ne + # commence après le moment du traitement + if course.begin >= today: + yield course def get_update_date(soup): # Explication de la regex diff --git a/management/commands/timetables.py b/management/commands/timetables.py index 76f0a7c..8b37a5d 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -27,6 +27,7 @@ from ._private import delete_courses_in_week, get_events, get_update_date, get_w @transaction.atomic def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, week=None): criteria = {} + today = timezone.make_aware(datetime.now()) if year is not None and week is not None: begin, end = get_week(year, week) criteria["begin__gte"] = begin @@ -42,12 +43,12 @@ def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, wee return if year is not None and week is not None: - delete_courses_in_week(timetable, year, week) + delete_courses_in_week(timetable, year, week, today) else: - Course.objects.filter(timetable=timetable, - begin__gte=min(weeks_in_soup.values())).delete() + delete_from = max(min(weeks_in_soup.values()), today) + Course.objects.filter(timetable=timetable, begin__gte=delete_from).delete() - for course in get_events(timetable, soup, weeks_in_soup, year, week): + for course in get_events(timetable, soup, weeks_in_soup, today, year, week): course.save() timetable.last_update_date = new_update_date -- cgit v1.2.1 From ccfedd0bbb8f9e5229b4007157fb0c2aa8484668 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 5 Oct 2017 12:45:01 +0200 Subject: Mauvais module --- management/commands/timetables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'management') diff --git a/management/commands/timetables.py b/management/commands/timetables.py index 8b37a5d..8ba8768 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -27,7 +27,7 @@ from ._private import delete_courses_in_week, get_events, get_update_date, get_w @transaction.atomic def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, week=None): criteria = {} - today = timezone.make_aware(datetime.now()) + today = timezone.make_aware(datetime.datetime.now()) if year is not None and week is not None: begin, end = get_week(year, week) criteria["begin__gte"] = begin -- cgit v1.2.1 From 76e344f68c1616693e93791f55348272cc61267e Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 5 Oct 2017 22:02:05 +0200 Subject: Simplification du filtrage de process_timetable_week() (pourquoi réinventer la roue carrée ?…) Ajout de commentaires --- management/commands/timetables.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'management') diff --git a/management/commands/timetables.py b/management/commands/timetables.py index 8ba8768..8945950 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -26,31 +26,49 @@ from ._private import delete_courses_in_week, get_events, get_update_date, get_w @transaction.atomic def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, week=None): - criteria = {} today = timezone.make_aware(datetime.datetime.now()) + + # On récupère la mise à jour la plus ancienne dans les cours de l’emploi du temps + # commençant à partir de maintenant + last_update_date = Course.objects.filter(timetable=timetable, begin__gte=today) if year is not None and week is not None: - begin, end = get_week(year, week) - criteria["begin__gte"] = begin - criteria["begin__lt"] = end + # 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 + _, end = get_week(year, week) + 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 = Course.objects.filter(timetable=timetable, **criteria) \ - .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: 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) else: - delete_from = max(min(weeks_in_soup.values()), today) + # 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 = max(min(weeks_in_soup.values()), today) # Vraiment utile ? Course.objects.filter(timetable=timetable, 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): course.save() + # On renseigne la date de mise à jour de Celcat, à des fins de statistiques timetable.last_update_date = new_update_date timetable.save() -- cgit v1.2.1 From 7f0dac074465ef838788202b80988005c35c0833 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Fri, 6 Oct 2017 18:52:52 +0200 Subject: Si on force une mise à jour, on efface les cours autant qu’on peut au lieu de le faire à partir du lancement du traitement --- management/commands/timetables.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'management') diff --git a/management/commands/timetables.py b/management/commands/timetables.py index 8945950..a152f9e 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -26,7 +26,13 @@ from ._private import delete_courses_in_week, get_events, get_update_date, get_w @transaction.atomic def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, week=None): - today = timezone.make_aware(datetime.datetime.now()) + begin, end = get_week(year, week) + # Si on force la mise à jour, on définit de moment + # de la mise à jour au début de la semaine + if force: + today = begin + else: + today = timezone.make_aware(datetime.datetime.now()) # On récupère la mise à jour la plus ancienne dans les cours de l’emploi du temps # commençant à partir de maintenant @@ -34,7 +40,6 @@ def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, wee 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 - _, end = get_week(year, week) last_update_date = last_update_date.filter(begin__lt=end) last_update_date = last_update_date.aggregate(Min("last_update")) \ @@ -60,7 +65,10 @@ def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, wee # 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 = max(min(weeks_in_soup.values()), today) # Vraiment utile ? + 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 + delete_from = max(delete_from, today) Course.objects.filter(timetable=timetable, begin__gte=delete_from).delete() # Tous les cours commençant sur la période traitée -- cgit v1.2.1 From ab47155c3d7eb9b5bf421c5f9c9c903602ebb175 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sat, 7 Oct 2017 11:13:09 +0200 Subject: La fonction create() des modèles créée un objet en base, donc ne pas sauvegarder après coup, comme ce qui était fait jusque là créait des cours sans nom ni type, faisant crasher le générateur d’ICS. La comparaison du début d’un cours se fait maintenant directement dans get_event(), avant que l’objet Course ne soit créé. --- management/commands/_private.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index d576daf..bad6e6f 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -80,7 +80,7 @@ def get_from_db_or_create(cls, **kwargs): return obj -def get_event(timetable, event, event_week): +def get_event(timetable, event, event_week, today): """Renvoie une classe Course à partir d’un événement récupéré par BS4""" # On récupère la date de l’évènement à partir de la semaine # et de la semaine référencée, puis l’heure de début et de fin @@ -88,6 +88,10 @@ def get_event(timetable, event, event_week): begin = add_time(date, event.starttime.text) end = add_time(date, event.endtime.text) + # On ne traite pas le cours si il commence après le moment du traitement + if begin < today: + return + # Création de l’objet cours course = Course.objects.create(timetable=timetable, begin=begin, end=end) @@ -142,11 +146,10 @@ def get_events(timetable, soup, weeks_in_soup, today, year=None, week=None): year is None or week is None) and \ event.resources.group is not None and \ event.starttime is not None and event.endtime is not None: - course = get_event(timetable, event, event_week) + course = get_event(timetable, event, event_week, today) - # On ne sauvegarde le cours que si il ne - # commence après le moment du traitement - if course.begin >= today: + # On renvoie le cours si il n’est pas nul + if course is not None: yield course def get_update_date(soup): -- cgit v1.2.1 From 72dcae5c9d58005af71b293d1ec09a4c50335c64 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Mon, 9 Oct 2017 23:11:16 +0200 Subject: Lorsque le nom d’un cours et son champ remarque est vide, le nom de l’objet cours final était égal à None et faisait crasher les flux RSS et Atom, ainsi que l’ICS et n’affichait aucun cours à la semaine du cours problématique. C’est maintenant corrigé. --- management/commands/_private.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index bad6e6f..3b6a164 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -103,20 +103,19 @@ def get_event(timetable, event, event_week, today): consolidate_groups(groups) course.groups.add(*groups) - # On récupère le champ « remarque » - if event.notes is not None: - course.notes = event.notes.text - - # On récupère le nom du cours + # On récupère le nom du cours et le champ « remarque » if event.resources.module is not None: course.name = event.resources.module.item.text - else: + if course.notes is not None: + course.notes = event.notes.text + + elif event.resources.module is None and event.notes is not None: # Il est possible qu’un cours n’ait pas de nom. Oui oui. # Qui sont les concepteurs de ce système ? Quels sont leurs # réseaux ? - # Bref, dans ce cas, on déplace le champ « remarque » de - # l’objet dans le champ « nom ». - course.name, course.notes = course.notes, None + # Bref, dans ce cas, si le cours possède une remarque, elle + # devient le nom du cours. + course.name = event.notes.text # Récupération du type de cours if event.category is not None: -- cgit v1.2.1 From e80ab8a7232a73d8a0f09f8e41a88893d4c65d63 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 10 Oct 2017 21:26:39 +0200 Subject: Envoi d’un user-agent personnalisé --- management/commands/_private.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index 3b6a164..943a3fb 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -23,6 +23,7 @@ from edt.models import Group, Room, Course from edt.utils import get_week import requests +import edt def add_time(date, time): ptime = datetime.datetime.strptime(time, "%H:%M") @@ -194,7 +195,8 @@ def get_weeks(soup): return weeks def get_xml(url): - req = requests.get(url) + user_agent = "celcatsanitizer/" + edt.VERSION + req = requests.get(url, headers={"User-Agent": user_agent}) req.encoding = "utf8" soup = BeautifulSoup(req.content, "html.parser") -- cgit v1.2.1 From 0e0e59e3530dcfbb8e92b5a3926edad4f58d72a1 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 10 Oct 2017 21:34:26 +0200 Subject: Il est plus pertinent de remplacer le nom du cours par son type lorsqu’il n’y en a pas que par sa remarque. --- management/commands/_private.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index 943a3fb..e7f0a3c 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -104,19 +104,21 @@ def get_event(timetable, event, event_week, today): consolidate_groups(groups) course.groups.add(*groups) - # On récupère le nom du cours et le champ « remarque » + # On récupère le champ « remarque » + if course.notes is not None: + course.notes = event.notes.text + + # On récupère le champ « nom » if event.resources.module is not None: course.name = event.resources.module.item.text - if course.notes is not None: - course.notes = event.notes.text - - elif event.resources.module is None and event.notes is not None: + elif event.category is not None: # Il est possible qu’un cours n’ait pas de nom. Oui oui. # Qui sont les concepteurs de ce système ? Quels sont leurs # réseaux ? - # Bref, dans ce cas, si le cours possède une remarque, elle - # devient le nom du cours. - course.name = event.notes.text + # Bref, dans ce cas, si le cours a un type, il devient son nom. + course.type = event.category.text + # Si il n’a pas de type (mais je ne pense pas que ça soit possible…), + # il obtiendra une valeur par défaut définie à l’avance. # Récupération du type de cours if event.category is not None: -- cgit v1.2.1 From 640496deb262349101567de12d2476cbfe5065b3 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sat, 14 Oct 2017 11:25:46 +0200 Subject: timezone.now() retourne l’heure UTC, ce qui empêche la mise à jour de la semaine prochaine le samedi à minuit. Remplacement de ces appels par une fonction qui retourne la bonne heure dans le bon fuseau horaire. --- management/commands/timetables.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'management') diff --git a/management/commands/timetables.py b/management/commands/timetables.py index a152f9e..35fb26e 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -21,7 +21,7 @@ from django.db.models import Min from django.utils import timezone from edt.models import Course, Timetable -from edt.utils import get_week +from edt.utils import get_week, tz_now from ._private import delete_courses_in_week, get_events, get_update_date, get_weeks, get_xml @transaction.atomic @@ -32,7 +32,7 @@ def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, wee if force: today = begin else: - today = timezone.make_aware(datetime.datetime.now()) + today = tz_now() # On récupère la mise à jour la plus ancienne dans les cours de l’emploi du temps # commençant à partir de maintenant @@ -107,16 +107,16 @@ class Command(BaseCommand): if options["all"]: weeks = None elif options["week"] is None: - _, week, day = timezone.now().isocalendar() + _, week, day = tz_now().isocalendar() if day >= 6: - year, week, _ = (timezone.now() + datetime.timedelta(weeks=1)).isocalendar() + year, week, _ = (tz_now() + datetime.timedelta(weeks=1)).isocalendar() weeks = [week] else: weeks = options["week"] if not options["all"]: if options["year"] is None and year is None: - year = timezone.now().year + year = tz_now().year elif year is None: year = options["year"][0] -- cgit v1.2.1 From 3830f9c786f1a790d67958b0a6d38bea75679159 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 22 Oct 2017 12:43:23 +0200 Subject: Le parseur de cours récupère à nouveau le champ « remarque ». Pour récupérer ce champ, le parseur est censé vérifier que la valeur existe dans un cours, sinon il ne faisait rien. Sauf que depuis un moment (commit 72dcae5c), la valeur qu’il vérifiait était celle de l’objet en cours de création, forcément nul, et non pas celle du XML. --- management/commands/_private.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index e7f0a3c..a9d283d 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -105,7 +105,7 @@ def get_event(timetable, event, event_week, today): course.groups.add(*groups) # On récupère le champ « remarque » - if course.notes is not None: + if event.notes is not None: course.notes = event.notes.text # On récupère le champ « nom » -- cgit v1.2.1 From 00bd85d3d19ad829566835d20cb04fecf324a6c1 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Wed, 18 Oct 2017 13:37:36 +0200 Subject: Suppression des imports inutiles --- management/commands/timetables.py | 1 - 1 file changed, 1 deletion(-) (limited to 'management') diff --git a/management/commands/timetables.py b/management/commands/timetables.py index 35fb26e..2d8a17e 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -18,7 +18,6 @@ import datetime from django.core.management.base import BaseCommand from django.db import transaction from django.db.models import Min -from django.utils import timezone from edt.models import Course, Timetable from edt.utils import get_week, tz_now -- cgit v1.2.1 From a7f533b2ddedf69a79d7ec68200ece5bedd59b2d Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 19 Oct 2017 22:41:47 +0200 Subject: Suppression de l’étape de consolidation --- management/commands/_private.py | 40 +--------------------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index a9d283d..b663454 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -30,42 +30,6 @@ def add_time(date, time): delta = datetime.timedelta(hours=ptime.hour, minutes=ptime.minute) return date + delta -def consolidate_group(group): - group_content_key = ("mention", "subgroup", "td", "tp") - group_content_list = group.group_info[1:] - - if group.subgroup is not None: - group_content = dict(zip(group_content_key, group_content_list)) - - for i in range(len(group_content_list))[::-1]: - del group_content[group_content_key[i]] - group_content[group_content_key[i] + "__isnull"] = True - - if group_content_list[i] is not None: - break - - group.parent = Group.objects.filter(timetable=group.timetable, - **group_content).first() - group.save() - - if group.tp is None: - group_content = dict(zip(group_content_key, group_content_list)) - last_is_none = False - - for i, key in enumerate(group_content_key): - if group_content_list[i] is None or last_is_none: - del group_content[key] - group_content[key + "__isnull"] = last_is_none - last_is_none = True - - Group.objects.filter(timetable=group.timetable, parent__isnull=True, - **group_content).update(parent=group) - -def consolidate_groups(groups): - for group in groups: - if group.parent is None: - consolidate_group(group) - def delete_courses_in_week(timetable, year, week, today): start, end = get_week(year, week) Course.objects.filter(begin__gte=max(start, today), begin__lt=end, @@ -96,12 +60,10 @@ def get_event(timetable, event, event_week, today): # Création de l’objet cours course = Course.objects.create(timetable=timetable, begin=begin, end=end) - # On récupère les groupes concernés par les cours, on les - # « consolide », puis on les insère dans l’objet cours. + # On récupère les groupes concernés par les cours groups = [get_from_db_or_create(Group, timetable=timetable, celcat_name=item.text) for item in event.resources.group.find_all("item")] - consolidate_groups(groups) course.groups.add(*groups) # On récupère le champ « remarque » -- cgit v1.2.1 From c476a83d3c92d705d0bdea8b37a9aa6f10cb50ac Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sat, 4 Nov 2017 12:24:25 +0100 Subject: Correction d’un bug qui empêche la mise à jour complète de l’emploi du temps Lorsqu’on demande une mise à jour, la semaine et le mois à mettre à jour sont passés en paramètre de la fonction de mise à jour. Mais quand on demande la mise à jour de tout l’emploi du temps, ces deux paramètres sont à None, faisant planter la fonction qui calcul le début et la fin de la semaine. --- management/commands/timetables.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'management') diff --git a/management/commands/timetables.py b/management/commands/timetables.py index 2d8a17e..d0bf0bd 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -25,17 +25,28 @@ from ._private import delete_courses_in_week, get_events, get_update_date, get_w @transaction.atomic def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, week=None): - begin, end = get_week(year, week) + if year is not None and week is not None: + begin, end = get_week(year, week) + # Si on force la mise à jour, on définit de moment # de la mise à jour au début de la semaine - if force: + if force and year is not None and week is not None: today = begin + elif force: + # Si la mise à jour est faite sur tout l’emploi du temps, + # alors la date de début est indéfinie. + today = None else: today = tz_now() # On récupère la mise à jour la plus ancienne dans les cours de l’emploi du temps - # commençant à partir de maintenant - last_update_date = Course.objects.filter(timetable=timetable, begin__gte=today) + last_update_date = Course.objects.filter(timetable=timetable) + + if today is not None: + # 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 -- cgit v1.2.1 From 37a95855076035470e7484804ed48b779ed22277 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sat, 4 Nov 2017 12:32:26 +0100 Subject: Affichage de la pile d’exécution lors d’une erreur de màj d’emploi du temps --- management/commands/timetables.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'management') diff --git a/management/commands/timetables.py b/management/commands/timetables.py index d0bf0bd..b254788 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -14,6 +14,7 @@ # along with celcatsanitizer. If not, see . import datetime +import traceback from django.core.management.base import BaseCommand from django.db import transaction @@ -135,9 +136,11 @@ class Command(BaseCommand): try: process_timetable(timetable, options["force"], year, weeks) - except Exception as exc: + except Exception: self.stderr.write( - self.style.ERROR("Failed to process {0}: {1}".format(timetable, exc))) + self.style.ERROR("Failed to process {0}:".format(timetable)) + ) + self.stderr.write(self.style.ERROR(traceback.format_exc())) errcount += 1 if errcount == 0: -- cgit v1.2.1 From 9447e0865c9d8a374ff6feb1bcf501c5eb73faf2 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 7 Nov 2017 17:40:44 +0100 Subject: La commande `timetables` n’affiche pas de trace d’erreur lorsqu’on l’arrête avec un Ctrl-C. --- management/commands/timetables.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'management') diff --git a/management/commands/timetables.py b/management/commands/timetables.py index b254788..ff00c8f 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -136,6 +136,8 @@ class Command(BaseCommand): try: process_timetable(timetable, options["force"], year, weeks) + except KeyboardInterrupt: + break except Exception: self.stderr.write( self.style.ERROR("Failed to process {0}:".format(timetable)) -- cgit v1.2.1