From 90414449f9f74b675d3793c2c48a796f9bfe4b29 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Mon, 27 Nov 2017 17:14:14 +0100 Subject: Adaptation de la commande de mise à jour des emplois du temps aux changements effectués sur la structure de la base de données --- management/commands/_private.py | 16 ++++++++-------- management/commands/timetables.py | 33 +++++++++++++++++---------------- 2 files changed, 25 insertions(+), 24 deletions(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index 4dd9262..171b6e9 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -19,7 +19,7 @@ import re from bs4 import BeautifulSoup from django.utils import timezone -from edt.models import Group, Room, Course +from edt.models import Course, Group, Room from edt.utils import get_week import requests @@ -30,10 +30,10 @@ def add_time(date, time): delta = datetime.timedelta(hours=ptime.hour, minutes=ptime.minute) return date + delta -def delete_courses_in_week(timetable, year, week, today): +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, - timetable=timetable).delete() + source=source).delete() def get_from_db_or_create(cls, **kwargs): obj = cls.objects.all().filter(**kwargs) @@ -45,7 +45,7 @@ def get_from_db_or_create(cls, **kwargs): return obj -def get_event(timetable, event, event_week, today): +def get_event(source, 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 @@ -58,10 +58,10 @@ def get_event(timetable, event, event_week, today): return # Création de l’objet cours - course = Course.objects.create(timetable=timetable, begin=begin, end=end) + course = Course.objects.create(source=source, begin=begin, end=end) # On récupère les groupes concernés par les cours - groups = [get_from_db_or_create(Group, timetable=timetable, + groups = [get_from_db_or_create(Group, source=source, celcat_name=item.text) for item in event.resources.group.find_all("item")] course.groups.add(*groups) @@ -96,7 +96,7 @@ def get_event(timetable, event, event_week, today): return course -def get_events(timetable, soup, weeks_in_soup, today, year=None, week=None): +def get_events(source, 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"): @@ -110,7 +110,7 @@ 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, today) + course = get_event(source, event, event_week, today) # On renvoie le cours si il n’est pas nul if course is not None: diff --git a/management/commands/timetables.py b/management/commands/timetables.py index ff00c8f..9734d13 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -20,12 +20,12 @@ 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.models import Course, Source 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 -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) @@ -41,7 +41,7 @@ def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, wee 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) + 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 @@ -71,7 +71,7 @@ def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, wee 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 @@ -80,26 +80,26 @@ def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, wee 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() + 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): @@ -131,16 +131,17 @@ 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(): + timetables = ", ".join([str(timetable) for timetable in source.timetables.all()]) + self.stdout.write("Processing {0}".format(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(timetables)) ) self.stderr.write(self.style.ERROR(traceback.format_exc())) errcount += 1 -- cgit v1.2.1 From a5b0d082a728b06e5e02f4d64632ac0b0a572aec Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Mon, 27 Nov 2017 17:18:41 +0100 Subject: Adaptation des commandes cleancourses et listtimetables au changements --- management/commands/cleancourses.py | 8 ++++---- management/commands/listtimetables.py | 13 ++++++------- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'management') diff --git a/management/commands/cleancourses.py b/management/commands/cleancourses.py index f6041ef..310c843 100644 --- a/management/commands/cleancourses.py +++ b/management/commands/cleancourses.py @@ -22,15 +22,15 @@ class Command(BaseCommand): help = "Remove all courses and groups from the database" def add_arguments(self, parser): - parser.add_argument("--timetable", type=int, nargs="+") + parser.add_argument("--source", type=int, nargs="+") def handle(self, *args, **options): with transaction.atomic(): - if options["timetable"] is None: + if options["source"] is None: Course.objects.all().delete() Group.objects.all().delete() else: - Course.objects.filter(timetable__id__in=options["timetable"]).delete() - Group.objects.filter(timetable__id__in=options["timetable"]).delete() + Course.objects.filter(source__id__in=options["source"]).delete() + Group.objects.filter(source__id__in=options["source"]).delete() self.stdout.write(self.style.SUCCESS("Done.")) diff --git a/management/commands/listtimetables.py b/management/commands/listtimetables.py index 6df7ba5..171fc2b 100644 --- a/management/commands/listtimetables.py +++ b/management/commands/listtimetables.py @@ -14,7 +14,7 @@ # along with celcatsanitizer. If not, see . from django.core.management.base import BaseCommand -from edt.models import Timetable +from edt.models import Source class Command(BaseCommand): @@ -24,14 +24,13 @@ class Command(BaseCommand): parser.add_argument("--order-by-id", action="store_true") def handle(self, *args, **options): - timetables = Timetable.objects.all() + sources = Source.objects.all() if options["order_by_id"]: - timetables = timetables.order_by("id") - else: - timetables = timetables.order_by("year__name", "name") + sources = sources.order_by("id") - for timetable in timetables: - self.stdout.write("{0} (id: {1})".format(timetable, timetable.id)) + for source in sources: + self.stdout.write("{0}\t: {1} (id: {2})".format(", ".join([str(timetable) for timetable in source.timetables.all()]), + source, source.id)) self.stdout.write("") self.stdout.write(self.style.SUCCESS("Done.")) -- cgit v1.2.1 From 8a71b0a55847e8783006b5a9514f64e0129578c9 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Mon, 27 Nov 2017 17:23:11 +0100 Subject: Fonction pour formater les emplois du temps à partir d’une source --- management/commands/listtimetables.py | 4 ++-- management/commands/timetables.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'management') diff --git a/management/commands/listtimetables.py b/management/commands/listtimetables.py index 171fc2b..25f641b 100644 --- a/management/commands/listtimetables.py +++ b/management/commands/listtimetables.py @@ -29,8 +29,8 @@ class Command(BaseCommand): sources = sources.order_by("id") for source in sources: - self.stdout.write("{0}\t: {1} (id: {2})".format(", ".join([str(timetable) for timetable in source.timetables.all()]), - source, source.id)) + self.stdout.write("{0}\t: {1} (id: {2})".format(source.formatted_timetables, + source, source.id)) self.stdout.write("") self.stdout.write(self.style.SUCCESS("Done.")) diff --git a/management/commands/timetables.py b/management/commands/timetables.py index 9734d13..86f389e 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -132,8 +132,7 @@ class Command(BaseCommand): year = options["year"][0] for source in Source.objects.all(): - timetables = ", ".join([str(timetable) for timetable in source.timetables.all()]) - self.stdout.write("Processing {0}".format(timetables)) + self.stdout.write("Processing {0}".format(source.formatted_timetables)) try: process_timetable(source, options["force"], year, weeks) @@ -141,7 +140,7 @@ class Command(BaseCommand): break except Exception: self.stderr.write( - self.style.ERROR("Failed to process {0}:".format(timetables)) + self.style.ERROR("Failed to process {0}:".format(source.formatted_timetables)) ) self.stderr.write(self.style.ERROR(traceback.format_exc())) errcount += 1 -- cgit v1.2.1 From 81cb9b8c6a96fa8529c6d7f6ca55dfd56a1f2e5d Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 11 Jan 2018 14:09:33 +0100 Subject: On remplace les
dans le champ remarque par des retours à la ligne lors du parsage, puis on les remplace à nouveau par des
lors du rendu des templates. --- 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 171b6e9..0a3d5fb 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -68,7 +68,7 @@ def get_event(source, event, event_week, today): # On récupère le champ « remarque » if event.notes is not None: - course.notes = event.notes.text + course.notes = "\n".join(event.notes.find_all(text=True)) # On récupère le champ « nom » if event.resources.module is not None: -- cgit v1.2.1 From 76fef8f3e0b3ad77f632a9e4d2c048607a1cf21b Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Thu, 18 Jan 2018 13:42:49 +0100 Subject: Mise à jour des copyrights --- 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 0a3d5fb..e78c3c2 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.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 -- cgit v1.2.1 From c9388e29b2f9ee18a9e190683a8a33fb710684c5 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sat, 27 Jan 2018 17:56:45 +0100 Subject: PEP8 --- management/commands/_private.py | 14 ++++++-- management/commands/cleancourses.py | 3 +- management/commands/listtimetables.py | 5 +-- management/commands/timetables.py | 65 +++++++++++++++++++++-------------- 4 files changed, 56 insertions(+), 31 deletions(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index e78c3c2..bac749b 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -25,16 +25,19 @@ from edt.utils import get_week import requests import edt + def add_time(date, time): ptime = datetime.datetime.strptime(time, "%H:%M") delta = datetime.timedelta(hours=ptime.hour, minutes=ptime.minute) return date + delta + 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() + def get_from_db_or_create(cls, **kwargs): obj = cls.objects.all().filter(**kwargs) @@ -45,6 +48,7 @@ def get_from_db_or_create(cls, **kwargs): return obj + def get_event(source, 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 @@ -96,17 +100,18 @@ def get_event(source, event, event_week, today): return course + def get_events(source, 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"): event_week = weeks_in_soup[event.rawweeks.text] - event_week_num = event_week.isocalendar()[1] # Numéro de semaine + event_week_num = event_week.isocalendar()[1] # Numéro de semaine # On passe le traitement si la semaine de l’événement ne correspond pas # à la semaine passée, ou qu’il ne contient pas de groupe ou n’a pas de # date de début ou de fin. - if (event_week_num == week and event_week.year == year or \ + if (event_week_num == week and event_week.year == year or 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: @@ -116,6 +121,7 @@ def get_events(source, soup, weeks_in_soup, today, year=None, week=None): if course is not None: yield course + def get_update_date(soup): # Explication de la regex # @@ -140,6 +146,7 @@ def get_update_date(soup): date = datetime.datetime(year, month, day, hour, minute, second) return timezone.make_aware(date) + def get_weeks(soup): # Les semaines sont référencées de manière assez… exotique # En gros, il y a une liste d’éléments span qui contiennent une sorte d’ID @@ -151,13 +158,14 @@ def get_weeks(soup): # Un cours contient donc un ID de semaine, puis le nombre de jours après le # début de cette semaine. weeks = {} - for span in soup.find_all("span"): # Liste de toutes les semaines définies + for span in soup.find_all("span"): # Liste de toutes les semaines définies # On parse la date et on la fait correspondre à l’ID weeks[span.alleventweeks.text] = timezone.make_aware( datetime.datetime.strptime(span["date"], "%d/%m/%Y")) return weeks + def get_xml(url): user_agent = "celcatsanitizer/" + edt.VERSION req = requests.get(url, headers={"User-Agent": user_agent}) diff --git a/management/commands/cleancourses.py b/management/commands/cleancourses.py index 310c843..88eec64 100644 --- a/management/commands/cleancourses.py +++ b/management/commands/cleancourses.py @@ -30,7 +30,8 @@ class Command(BaseCommand): Course.objects.all().delete() Group.objects.all().delete() else: - Course.objects.filter(source__id__in=options["source"]).delete() + Course.objects.filter(source__id__in=options["source"]) \ + .delete() Group.objects.filter(source__id__in=options["source"]).delete() self.stdout.write(self.style.SUCCESS("Done.")) diff --git a/management/commands/listtimetables.py b/management/commands/listtimetables.py index 25f641b..7892855 100644 --- a/management/commands/listtimetables.py +++ b/management/commands/listtimetables.py @@ -29,8 +29,9 @@ class Command(BaseCommand): sources = sources.order_by("id") for source in sources: - self.stdout.write("{0}\t: {1} (id: {2})".format(source.formatted_timetables, - source, source.id)) + self.stdout.write("{0}\t: {1} (id: {2})" + .format(source.formatted_timetables, + source, source.id)) self.stdout.write("") self.stdout.write(self.style.SUCCESS("Done.")) diff --git a/management/commands/timetables.py b/management/commands/timetables.py index 86f389e..cf48af6 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -22,10 +22,13 @@ from django.db.models import Min from edt.models import Course, Source 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 ._private import delete_courses_in_week, get_events, get_update_date, \ + get_weeks, get_xml + @transaction.atomic -def process_timetable_week(source, 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,32 +43,34 @@ def process_timetable_week(source, soup, weeks_in_soup, force, year=None, week=N else: today = tz_now() - # On récupère la mise à jour la plus ancienne dans les cours de l’emploi du temps + # 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: @@ -78,7 +83,8 @@ def process_timetable_week(source, soup, weeks_in_soup, force, year=None, week=N # 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(source=source, begin__gte=delete_from).delete() @@ -91,13 +97,15 @@ def process_timetable_week(source, soup, weeks_in_soup, force, year=None, week=N source.last_update_date = new_update_date source.save() + 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(source, soup, weeks_in_soup, force, year, week) + process_timetable_week(source, soup, weeks_in_soup, force, + year, week) else: process_timetable_week(source, soup, weeks_in_soup, force) @@ -106,9 +114,12 @@ 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 +131,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"] @@ -132,7 +144,8 @@ class Command(BaseCommand): year = options["year"][0] for source in Source.objects.all(): - self.stdout.write("Processing {0}".format(source.formatted_timetables)) + self.stdout.write("Processing {0}".format( + source.formatted_timetables)) try: process_timetable(source, options["force"], year, weeks) @@ -140,7 +153,8 @@ class Command(BaseCommand): break except Exception: self.stderr.write( - self.style.ERROR("Failed to process {0}:".format(source.formatted_timetables)) + self.style.ERROR("Failed to process {0}:".format( + source.formatted_timetables)) ) self.stderr.write(self.style.ERROR(traceback.format_exc())) errcount += 1 @@ -148,4 +162,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))) -- cgit v1.2.1 From 77a4b75431cfab7348db73b563dd005ce64be14a Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 28 Jan 2018 11:14:34 +0100 Subject: Changements dans le formatage du code pour le rendre plus lisible --- management/commands/listtimetables.py | 7 +++---- management/commands/timetables.py | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'management') diff --git a/management/commands/listtimetables.py b/management/commands/listtimetables.py index 7892855..a3ef223 100644 --- a/management/commands/listtimetables.py +++ b/management/commands/listtimetables.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 @@ -29,9 +29,8 @@ class Command(BaseCommand): sources = sources.order_by("id") for source in sources: - self.stdout.write("{0}\t: {1} (id: {2})" - .format(source.formatted_timetables, - source, source.id)) + self.stdout.write("{0}\t: {1} (id: {2})".format( + source.formatted_timetables, source, source.id)) self.stdout.write("") self.stdout.write(self.style.SUCCESS("Done.")) diff --git a/management/commands/timetables.py b/management/commands/timetables.py index cf48af6..2c299de 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 @@ -58,8 +58,8 @@ def process_timetable_week(source, soup, weeks_in_soup, force, # 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) -- cgit v1.2.1 From aab8372b27c27becbdf875d6c30fa49ea218abf4 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 28 Jan 2018 11:20:49 +0100 Subject: Remplacement de la fonction get_from_db_or_create() par objects.get_or_create() --- management/commands/_private.py | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index bac749b..0f87179 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -38,17 +38,6 @@ def delete_courses_in_week(source, year, week, today): source=source).delete() -def get_from_db_or_create(cls, **kwargs): - obj = cls.objects.all().filter(**kwargs) - - obj = obj.first() - if obj is None: - obj = cls(**kwargs) - obj.save() - - return obj - - def get_event(source, 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 @@ -65,8 +54,8 @@ def get_event(source, event, event_week, today): course = Course.objects.create(source=source, begin=begin, end=end) # On récupère les groupes concernés par les cours - groups = [get_from_db_or_create(Group, source=source, - celcat_name=item.text) + groups = [Group.objects.get_or_create(source=source, + celcat_name=item.text)[0] for item in event.resources.group.find_all("item")] course.groups.add(*groups) @@ -94,7 +83,7 @@ def get_event(source, event, event_week, today): # en ait pas… qui sont ils, leurs réseaux, tout ça…), on les insère # dans la base de données, et on les ajoute dans l’objet cours if event.resources.room is not None: - rooms = [get_from_db_or_create(Room, name=item.text) + rooms = [Room.objects.get_or_create(name=item.text)[0] for item in event.resources.room.find_all("item")] course.rooms.add(*rooms) -- cgit v1.2.1 From 37d80d84d8ce6cb0a17a0e4179e4c7a453f7fcc2 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 28 Jan 2018 11:26:56 +0100 Subject: Remplacement de l’arithmétique de date et heure par datetime.combine() --- management/commands/_private.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index 0f87179..4e35990 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -28,8 +28,7 @@ import edt def add_time(date, time): ptime = datetime.datetime.strptime(time, "%H:%M") - delta = datetime.timedelta(hours=ptime.hour, minutes=ptime.minute) - return date + delta + return datetime.datetime.combine(date, ptime) def delete_courses_in_week(source, year, week, today): -- cgit v1.2.1 From ca745d43066dcc1b9f8abd9e242f6af164630b94 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 28 Jan 2018 11:54:06 +0100 Subject: Revert "Remplacement de l’arithmétique de date et heure par datetime.combine()" This reverts commit 37d80d84d8ce6cb0a17a0e4179e4c7a453f7fcc2. --- management/commands/_private.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index 4e35990..0f87179 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -28,7 +28,8 @@ import edt def add_time(date, time): ptime = datetime.datetime.strptime(time, "%H:%M") - return datetime.datetime.combine(date, ptime) + delta = datetime.timedelta(hours=ptime.hour, minutes=ptime.minute) + return date + delta def delete_courses_in_week(source, year, week, today): -- cgit v1.2.1 From 3354c34fa1f58750597b9e6213a81e3443721ac0 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sat, 10 Feb 2018 15:13:38 +0100 Subject: Ajout d’une commande pour reparser les groupes --- management/commands/reparse.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 management/commands/reparse.py (limited to 'management') diff --git a/management/commands/reparse.py b/management/commands/reparse.py new file mode 100644 index 0000000..20eb1b4 --- /dev/null +++ b/management/commands/reparse.py @@ -0,0 +1,30 @@ +# Copyright (C) 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 +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# celcatsanitizer is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with celcatsanitizer. If not, see . + +from django.core.management.base import BaseCommand +from ...models import Group + + +class Command(BaseCommand): + help = "Reparses all groups in database" + + def handle(self, *args, **options): + self.stdout.write("Processing {0} groups…".format( + Group.objects.count())) + + for group in Group.objects.all(): + group.save() + + self.stdout.write(self.style.SUCCESS("Done.")) -- cgit v1.2.1 From 9b312281e0f2a9668ab90d77f212c9618daec7db Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sat, 10 Feb 2018 15:13:20 +0100 Subject: Correction des imports --- management/commands/_private.py | 4 ++-- management/commands/cleancourses.py | 3 ++- management/commands/listtimetables.py | 2 +- management/commands/timetables.py | 5 +++-- 4 files changed, 8 insertions(+), 6 deletions(-) (limited to 'management') diff --git a/management/commands/_private.py b/management/commands/_private.py index 0f87179..94c1918 100644 --- a/management/commands/_private.py +++ b/management/commands/_private.py @@ -19,8 +19,8 @@ import re from bs4 import BeautifulSoup from django.utils import timezone -from edt.models import Course, Group, Room -from edt.utils import get_week +from ...models import Course, Group, Room +from ...utils import get_week import requests import edt diff --git a/management/commands/cleancourses.py b/management/commands/cleancourses.py index 88eec64..246cfcc 100644 --- a/management/commands/cleancourses.py +++ b/management/commands/cleancourses.py @@ -15,7 +15,8 @@ from django.core.management.base import BaseCommand from django.db import transaction -from edt.models import Course, Group + +from ...models import Course, Group class Command(BaseCommand): diff --git a/management/commands/listtimetables.py b/management/commands/listtimetables.py index a3ef223..d17399a 100644 --- a/management/commands/listtimetables.py +++ b/management/commands/listtimetables.py @@ -14,7 +14,7 @@ # along with celcatsanitizer. If not, see . from django.core.management.base import BaseCommand -from edt.models import Source +from ...models import Source class Command(BaseCommand): diff --git a/management/commands/timetables.py b/management/commands/timetables.py index 2c299de..f92ad4e 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -20,8 +20,9 @@ from django.core.management.base import BaseCommand from django.db import transaction from django.db.models import Min -from edt.models import Course, Source -from edt.utils import get_week, tz_now +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 -- cgit v1.2.1 From f36bceaddcd3315235fe9ce9172ea4f73ce405ba Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sun, 22 Apr 2018 12:44:03 +0200 Subject: Suppression du paramètre --order-by-id dans listtimetables Ce paramètre est devenu inutile depuis l’ajout des sources, qui sont déjà triées par leur ID. --- management/commands/listtimetables.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'management') diff --git a/management/commands/listtimetables.py b/management/commands/listtimetables.py index d17399a..bd27e92 100644 --- a/management/commands/listtimetables.py +++ b/management/commands/listtimetables.py @@ -20,13 +20,8 @@ from ...models import Source class Command(BaseCommand): help = "List timetables in the database" - def add_arguments(self, parser): - parser.add_argument("--order-by-id", action="store_true") - def handle(self, *args, **options): sources = Source.objects.all() - if options["order_by_id"]: - sources = sources.order_by("id") for source in sources: self.stdout.write("{0}\t: {1} (id: {2})".format( -- cgit v1.2.1