aboutsummaryrefslogtreecommitdiff
path: root/management/commands
diff options
context:
space:
mode:
authorAlban Gruin2017-01-20 11:16:15 +0100
committerAlban Gruin2017-01-20 11:16:15 +0100
commitd9ae54412cfee62da29340d9f46a3e797750b883 (patch)
treedd6351f3801a7ecc68dcae7536a33030199e55fe /management/commands
parentd8b1738aacc08c3ff28a7bdd0c29e276458a902f (diff)
Le traitement est effectué par emploi du temps puis pas semaine et non plus l'inverse.
Cela permet de réduire le nombre d'appels au serveur distant. Séparation du traitement en fonction pour pouvoir le réutiliser autre part sans duplication de code.
Diffstat (limited to 'management/commands')
-rw-r--r--management/commands/_private.py32
-rw-r--r--management/commands/timetables.py64
2 files changed, 62 insertions, 34 deletions
diff --git a/management/commands/_private.py b/management/commands/_private.py
index 8767aa8..65772a4 100644
--- a/management/commands/_private.py
+++ b/management/commands/_private.py
@@ -14,15 +14,21 @@ class Week:
def get_day(self, id):
return self.start + datetime.timedelta(id)
+ @property
+ def year(self):
+ return self.start.year
+
def add_time(date, time):
delta = datetime.timedelta(hours=time.hour, minutes=time.minute)
return date + delta
-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"))
+def delete_courses_in_week(timetable, 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()
+ Course.objects.filter(begin__gte=start, begin__lt=end,
+ timetable=timetable).delete()
def get_from_db_or_create(cls, name, timetable=None):
obj = cls.objects.all().filter(name=name)
@@ -37,7 +43,7 @@ def get_from_db_or_create(cls, name, timetable=None):
return obj
-def get_events(soup, weeks, week, timetable):
+def get_events(soup, weeks, year, week, timetable):
for event in soup.find_all("event"):
title = None
type_ = None
@@ -45,12 +51,19 @@ def get_events(soup, weeks, week, timetable):
rooms = None
notes = None
- if weeks[event.rawweeks.text].number == week and event.resources.group is not None and event.starttime is not None and event.endtime is not None:
+ if weeks[event.rawweeks.text].number == week and \
+ weeks[event.rawweeks.text].year == year and \
+ event.resources.group is not None and \
+ event.starttime is not None and event.endtime is not None:
date = weeks[event.rawweeks.text].get_day(int(event.day.text))
- begin = add_time(date, datetime.datetime.strptime(event.starttime.text, "%H:%M"))
- end = add_time(date, datetime.datetime.strptime(event.endtime.text, "%H:%M"))
- groups = [get_from_db_or_create(Group, item.text, timetable) for item in event.resources.group.find_all("item")]
+ begin = add_time(date, datetime.datetime.strptime(
+ event.starttime.text, "%H:%M"))
+ end = add_time(date, datetime.datetime.strptime(
+ event.endtime.text, "%H:%M"))
+
+ groups = [get_from_db_or_create(Group, item.text, timetable)
+ for item in event.resources.group.find_all("item")]
if event.notes is not None:
notes = event.notes.text
@@ -67,7 +80,8 @@ def get_events(soup, weeks, week, timetable):
type_ = event.category.text
if event.resources.room is not None:
- rooms = [get_from_db_or_create(Room, item.text) for item in event.resources.room.find_all("item")]
+ rooms = [get_from_db_or_create(Room, item.text)
+ for item in event.resources.room.find_all("item")]
yield title, type_, groups, rooms, notes, begin, end
diff --git a/management/commands/timetables.py b/management/commands/timetables.py
index 37a5201..9882759 100644
--- a/management/commands/timetables.py
+++ b/management/commands/timetables.py
@@ -10,43 +10,57 @@ from ._private import delete_courses_in_week, get_events, get_weeks, get_xml, We
import datetime
import requests
+@transaction.atomic
+def process_timetable_week(timetable, year, week, soup, weeks_in_soup):
+ delete_courses_in_week(timetable, year, week)
+ for name, type_, groups, rooms, notes, begin, end in get_events(soup, weeks_in_soup, year, week, timetable):
+ course = Course.objects.create(timetable=timetable, begin=begin, end=end)
+ course.name = name
+ course.type = type_
+ course.notes = notes
+
+ course.groups.add(*groups)
+ if rooms is not None:
+ course.rooms.add(*rooms)
+
+ course.save()
+
+def process_timetable(timetable, year, weeks):
+ soup = get_xml(timetable.url)
+ weeks_in_soup = get_weeks(soup)
+
+ for week in weeks:
+ process_timetable_week(timetable, year, week, soup, weeks_in_soup)
+
class Command(BaseCommand):
help = "Fetches registered celcat timetables"
def add_arguments(self, parser):
parser.add_argument("--week", type=int, choices=range(1, 54), nargs="+")
+ parser.add_argument("--year", type=int, nargs=1)
- def __get_weeks(self, weeks):
- if weeks is None:
- year, week, day = timezone.now().isocalendar()
+ def handle(self, *args, **options):
+ year = None
+ if options["week"] is None:
+ _, week, day = timezone.now().isocalendar()
if day >= 6:
year, week, _ = (timezone.now() + datetime.timedelta(weeks=1)).isocalendar()
-
- yield year, week
+ weeks = [week]
else:
- year = timezone.now().year
- for week in weeks:
- yield year, week
-
- @transaction.atomic
- def handle(self, *args, **options):
- for year, week in self.__get_weeks(options["week"]):
- delete_courses_in_week(year, week)
-
- for timetable in Timetable.objects.all():
- self.stdout.write("Processing {0}, week {1}".format(timetable, week))
+ weeks = options["week"]
- soup = get_xml(timetable.url)
- weeks = get_weeks(soup)
-
- for name, type_, groups, rooms, notes, begin, end in get_events(soup, weeks, week, timetable):
- course = Course.objects.create(name=name, type=type_, notes=notes, timetable=timetable, begin=begin, end=end)
+ if options["year"] is None and year is None:
+ year = timezone.now().year
+ else:
+ year = options["year"][0]
- course.groups.add(*groups)
- if rooms is not None:
- course.rooms.add(*rooms)
+ for timetable in Timetable.objects.all():
+ self.stdout.write("Processing {0}".format(timetable))
- course.save()
+ try:
+ process_timetable(timetable, year, weeks)
+ except Exception as e:
+ self.stderr.write(self.style.error("Failed to process {0}: {1}".format(timetable, e)))
self.stdout.write(self.style.SUCCESS("Done."))