diff options
| -rw-r--r-- | management/commands/_private.py | 69 | ||||
| -rw-r--r-- | management/commands/timetables.py | 38 | 
2 files changed, 107 insertions, 0 deletions
| diff --git a/management/commands/_private.py b/management/commands/_private.py new file mode 100644 index 0000000..4000f6b --- /dev/null +++ b/management/commands/_private.py @@ -0,0 +1,69 @@ +from bs4 import BeautifulSoup +from django.utils import timezone +from edt.models import Group, Room + +import datetime +import requests + + +class Week: +    def __init__(self, number, start): +        self.number = number +        self.start = timezone.make_aware(datetime.datetime.strptime(start, "%d/%m/%Y")) + +    def get_day(self, id): +        return self.start + datetime.timedelta(id) + +def add_time(date, time): +    delta = datetime.timedelta(hours=time.hour, minutes=time.minute) +    return date + delta + +def get_from_db_or_create(cls, name): +    obj = cls.objects.all().filter(name=name).first() +    if obj == None: +        obj = cls(name=name) +        obj.save() + +    return obj + +def get_events(soup, weeks, week): +    for event in soup.find_all("event"): +        title = None +        type_ = None +        groups = None +        rooms = None + +        if weeks[event.rawweeks.text].number != week: +            continue + +        if event.resources.module is not None: +            title = event.resources.module.text + +        if event.category is not None and title is not None: +            type_ = event.category.text + +        if event.resources.group is not None and type_ is not None: +            groups = [get_from_db_or_create(Group, item.text) for item in event.resources.group.find_all("item")] + +        if event.resources.room is not None and groups is not None: +            rooms = [get_from_db_or_create(Room, item.text) for item in event.resources.room.find_all("item")] + +            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")) + +            yield (title, type_, groups, rooms, begin, end,) + +def get_weeks(soup): +    weeks = {} +    for span in soup.find_all("span"): +        weeks[span.alleventweeks.text] = Week(int(span.title.text), span["date"]) + +    return weeks + +def get_xml(url): +    r = requests.get(url) +    r.encoding = "utf8" + +    soup = BeautifulSoup(r.text, "html.parser") +    return soup diff --git a/management/commands/timetables.py b/management/commands/timetables.py new file mode 100644 index 0000000..58897a1 --- /dev/null +++ b/management/commands/timetables.py @@ -0,0 +1,38 @@ +from django.core.management.base import BaseCommand, CommandError +from django.utils import timezone +from edt.models import Group, Room, Course + +from bs4 import BeautifulSoup + +from ._private import get_events, get_weeks, get_xml, Week + +import datetime +import requests + +class Command(BaseCommand): +    help = "Fetches the specified celcat timetable" + +    def add_arguments(self, parser): +        parser.add_argument("url", type=str) + +    def handle(self, *args, **options): +        url = options["url"] + +        _, week, day = timezone.now().isocalendar() +        if day >= 6: +            _, week, _ = (timezone.now() + datetime.timedelta(weeks=1)).isocalendar() + +        soup = get_xml(url) +        weeks = get_weeks(soup) + +        for name, type_, groups, rooms, begin, end in get_events(soup, weeks, week): +             +            course = Course.objects.create(begin=begin, end=end) + +            course.name = name +            course.type = type_ +            course.groups.add(*groups) +            course.rooms.add(*rooms) +            course.save() + +        self.stdout.write(self.style.SUCCESS("Done.")) | 
