From eb8d6a59c8154acb792fbcb9e783485d945b0aee Mon Sep 17 00:00:00 2001 From: Hoseong Son Date: Thu, 8 Feb 2018 22:45:16 +0900 Subject: [PATCH] Init. --- .gitignore | 6 +++++ app.py | 12 +++++++++ convert.py | 63 ++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + test/test_convert.py | 22 ++++++++++++++++ 5 files changed, 104 insertions(+) create mode 100644 .gitignore create mode 100644 app.py create mode 100644 convert.py create mode 100644 requirements.txt create mode 100644 test/test_convert.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..46c2893 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.xml +.idea +.venv +__pycache__ +*.ics + diff --git a/app.py b/app.py new file mode 100644 index 0000000..7b8e935 --- /dev/null +++ b/app.py @@ -0,0 +1,12 @@ +import argparse + +from convert import Convert + +parser = argparse.ArgumentParser() +parser.add_argument("--xml", type=str, help="Location of timetable xml file", required=True) +parser.add_argument("--begin", type=str, help="Semester beginning date", required=True) +parser.add_argument("--end", type=str, help="Semester ending date", required=True) +args = parser.parse_args() + +c = Convert(args.xml) +c.get_calendar(c.get_subjects(), args.begin, args.end) diff --git a/convert.py b/convert.py new file mode 100644 index 0000000..4e0e01d --- /dev/null +++ b/convert.py @@ -0,0 +1,63 @@ +import datetime +import os +import tempfile +import xml.etree.ElementTree as ElementTree +from dateutil import parser +from icalendar import Calendar, Event + + +class Convert(): + def __init__(self, filename): + self.filename = filename + + def get_subjects(self): + result = [] + + tree = ElementTree.parse(self.filename) + root = tree.getroot() + for subject in root.findall('subject'): + name = subject.find("name").get("value") + single_subject = {} + + single_subject["name"] = name + single_subject["professor"] = subject.find("professor").get("value") + single_subject["info"] = list(map( + lambda x: { + "day": x.get("day"), + "place" : x.get("place"), + "startAt": '{:02d}:{:02d}'.format(*divmod(int(x.get("starttime")) * 5, 60)), + "endAt": '{:02d}:{:02d}'.format(*divmod(int(x.get("endtime")) * 5, 60)) + }, subject.find("time").findall("data") + ) + ) + result.append(single_subject) + + return result + + def get_calendar(self, timetable, start_date, end_date): + cal = Calendar() + + for item in timetable: + for time in item["info"]: + event = Event() + event.add('summary', item["name"]) + event.add('dtstart', parser.parse("%s %s" % (self.get_nearest_date(start_date, time["day"]), time["startAt"]))) + event.add('dtend', parser.parse("%s %s" % (self.get_nearest_date(start_date, time["day"]), time["endAt"]))) + event.add('rrule', {'freq': 'WEEKLY', 'until': parser.parse(end_date)}) + cal.add_component(event) + + f = open(os.path.join('', 'example.ics'), 'wb') + f.write(cal.to_ical()) + f.close() + + def get_nearest_date(self, start_date, weekday): + start_date = parser.parse(start_date) + weekday = int(weekday) + + if start_date.weekday() >= weekday: + if start_date.weekday() > weekday: start_date += datetime.timedelta(days=7) + start_date -= datetime.timedelta(start_date.weekday() - weekday) + else: + start_date += datetime.timedelta(weekday - start_date.weekday()) + + return start_date \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..44466d5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +icalendar \ No newline at end of file diff --git a/test/test_convert.py b/test/test_convert.py new file mode 100644 index 0000000..0c24b12 --- /dev/null +++ b/test/test_convert.py @@ -0,0 +1,22 @@ +import unittest + +from dateutil import parser + +from convert import Convert + + +class TestConvert(unittest.TestCase): + def test_get_subjects(self): + c = Convert("table.xml") + self.assertGreater(len(c.get_subjects()), 0) + + def test_get_calendar(self): + c = Convert("table.xml") + c.get_calendar(c.get_subjects(), "20180301", "20181231") + + def test_get_nearest_date(self): + c = Convert("table.xml") + self.assertEqual(c.get_nearest_date(start_date="20180301", weekday=4), parser.parse("20180302")) + +if __name__ == '__main__': + unittest.main()