diff options
Diffstat (limited to 'management/commands/timetables.py')
-rw-r--r-- | management/commands/timetables.py | 80 |
1 files changed, 44 insertions, 36 deletions
diff --git a/management/commands/timetables.py b/management/commands/timetables.py index c82b0e4..76f0a7c 100644 --- a/management/commands/timetables.py +++ b/management/commands/timetables.py @@ -13,59 +13,63 @@ # You should have received a copy of the GNU Affero General Public License # along with celcatsanitizer. If not, see <http://www.gnu.org/licenses/>. +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 Timetable, LastUpdate, Course +from edt.models import Course, Timetable +from edt.utils import get_week from ._private import delete_courses_in_week, get_events, get_update_date, get_weeks, get_xml -import datetime - @transaction.atomic -def process_timetable_week(timetable, year, week, soup, weeks_in_soup): - last_update_date = None +def process_timetable_week(timetable, soup, weeks_in_soup, force, year=None, week=None): + criteria = {} + if year is not None and week is not None: + begin, end = get_week(year, week) + criteria["begin__gte"] = begin + criteria["begin__lt"] = end + + last_update_date = Course.objects.filter(timetable=timetable, **criteria) \ + .aggregate(Min("last_update")) \ + ["last_update__min"] new_update_date = get_update_date(soup) - try: - last_update = LastUpdate.objects.get(timetable=timetable, year=year, week=week) - last_update_date = last_update.updated_at - except: - last_update = LastUpdate(timetable=timetable, year=year, week=week) - if last_update_date is not None and new_update_date is not None and \ + 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 - delete_courses_in_week(timetable, year, week) - for name, type_, groups, rooms, notes, begin, end in \ - get_events(timetable, year, week, soup, weeks_in_soup): - 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) + if year is not None and week is not None: + delete_courses_in_week(timetable, year, week) + else: + Course.objects.filter(timetable=timetable, + begin__gte=min(weeks_in_soup.values())).delete() + for course in get_events(timetable, soup, weeks_in_soup, year, week): course.save() - last_update.date = timezone.make_aware(datetime.datetime.now()) - last_update.updated_at = new_update_date - last_update.save() + timetable.last_update_date = new_update_date + timetable.save() -def process_timetable(timetable, year, weeks): +def process_timetable(timetable, force, year=None, weeks=None): 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) + 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) + else: + process_timetable_week(timetable, soup, weeks_in_soup, force) 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("--year", type=int, nargs=1) @@ -73,7 +77,9 @@ class Command(BaseCommand): year = None errcount = 0 - if options["week"] is None: + if options["all"]: + weeks = None + elif options["week"] is None: _, week, day = timezone.now().isocalendar() if day >= 6: year, week, _ = (timezone.now() + datetime.timedelta(weeks=1)).isocalendar() @@ -81,18 +87,20 @@ class Command(BaseCommand): else: weeks = options["week"] - if options["year"] is None and year is None: - year = timezone.now().year - elif year is None: - year = options["year"][0] + if not options["all"]: + if options["year"] is None and year is None: + year = timezone.now().year + elif year is None: + year = options["year"][0] for timetable in Timetable.objects.all(): self.stdout.write("Processing {0}".format(timetable)) try: - process_timetable(timetable, year, weeks) - except Exception as e: - self.stderr.write(self.style.ERROR("Failed to process {0}: {1}".format(timetable, e))) + process_timetable(timetable, options["force"], year, weeks) + except Exception as exc: + self.stderr.write( + self.style.ERROR("Failed to process {0}: {1}".format(timetable, exc))) errcount += 1 if errcount == 0: |