aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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."))