Assignments

  1from icalevents.icalevents import events
  2from datetime import datetime, timedelta, date
  3from pytz import utc, timezone
  4import html
  5
  6
  7class Assignments:
  8    """
  9    Assignments are retrieved from the myPARISH calendar webcal feed. The assumption is made that the calendar is
 10    first limited to only assignments, without other kinds of events. A list is created containing `Assignment` objects.
 11    """
 12    def __init__(self, start, end, url):
 13        """
 14        Constructor for `Assignments` class.
 15        :param start: datetime object -> start date for assignments list
 16        :param end: datetime object -> end date for assignments list
 17        :param url: str -> webcal url to myPARISH calendar
 18        """
 19        self.URL = url
 20        self.start_date = self.normalize_date(start)
 21        self.end_date = self.normalize_date(end)
 22        self.assignments = self.get_assignments()
 23
 24    def __str__(self):
 25        """
 26        String representation for `Assignments` objects
 27        :return: str
 28        """
 29        output = ''
 30
 31        for assignment in self.assignments:
 32            output += str(assignment) + '\n'
 33
 34        return output
 35
 36    def get_assignments(self):
 37        """
 38        Extract assignments from webcal feed and populate a list.
 39        :return: list -> list of `Assignment` objects [`Assignment`, `Assignment`, ...]
 40        """
 41        es = events(self.URL, start=self.start_date, end=self.end_date, fix_apple=True)
 42        es.sort()
 43        ret_list = []
 44        for event in es:
 45            start_time = self.normalize_date(event.start)
 46            ret_list.append(Assignment(start_time,
 47                                       html.unescape(self.get_course(event.summary)),
 48                                       html.unescape(self.get_name(event.summary))
 49                                       ))
 50        return ret_list
 51
 52    @staticmethod
 53    def normalize_date(dt):
 54        """
 55        Convert `date` or `datetime` to `datetime` with timezone.
 56        :param dt: date to normalize
 57        :return: date as `datetime` with timezone
 58        """
 59        if type(dt) is date:
 60            dt = datetime(dt.year, dt.month, dt.day, 0, 0)
 61        elif type(dt) is datetime:
 62            dt = dt
 63        else:
 64            raise ValueError("unknown type %s" % type(dt))
 65
 66        if not dt.tzinfo:
 67            dt = utc.localize(dt)
 68
 69        return dt
 70
 71    @staticmethod
 72    def get_course(summary):
 73        """
 74        Extract course name from `event.summary` property
 75        :param summary: `event.summary`
 76        :return: str -> name of course or `None`
 77        """
 78        if ':' in summary:
 79            course = summary[:summary.find(':')]
 80            return course.strip()
 81        return None
 82
 83    @staticmethod
 84    def get_name(summary):
 85        """
 86        Extract assignment name from `event.summary` property
 87        :param summary: `event.summary`
 88        :return: str -> name of assignment or `None`
 89        """
 90        if ':' in summary:
 91            name = summary[summary.find(':') + 1:]
 92            return name.strip()
 93        return None
 94
 95
 96class Assignment:
 97    """
 98    Class for each individual assignment.
 99    """
100    def __init__(self, d, c, n):
101        """
102        Constructor for `Assignment` class
103        :param d: datetime -> due date of assignment
104        :param c: str -> course name
105        :param n: str -> assignment name
106        """
107        self.date = d
108        self.course = c
109        self.name = n
110
111    def __str__(self):
112        """
113        String representation for `Assignment` objects
114        :return: str
115        """
116        return f'{datetime.date(self.date)} | {self.course} | {self.name}'
117
118
119def main():
120    """
121    This function executes only if this file is run directly. It is only present to show example usage.
122    Code that utilizes `Assignments` should be located in other files, not this one.
123    :return:
124    """
125    # Get URL from user. Possibly store in text file.
126    url = 'webcal://parish.myschoolapp.com/podium/feed/iCal.aspx?z=PBfWPW%2b7Bf8znQAnWIawKSUMruwMfYfE8DOy5Pq3KcqL5EEpKZ3SaFZKWyirslzw8uqEHM2%2bpImt5ve%2b8ykwEg%3d%3d'
127
128    # Also get these from user
129    start_yr = 2023
130    start_mth = 3
131    start_day = 6
132
133    end_yr = 2023
134    end_mth = 3
135    end_day = 15
136
137    # create Assignments object
138    my_assignments = Assignments(datetime(start_yr, start_mth, start_day), datetime(end_yr, end_mth, end_day), url)
139
140    # print assignments in a loop
141    # selection can be done on assignment properties
142    print('\nAssignments for Coding for OOP...')
143    for assignment in my_assignments.assignments:
144        if 'Coding for OOP' in assignment.course:
145            print(f'Date: {datetime.date(assignment.date)} | Course: {assignment.course} | Name: {assignment.name}')
146
147    # print all assignments
148    print('\nAll assignments...')
149    print(my_assignments)
150
151    print('Both printouts are limited to the date range given.')
152
153
154if __name__ == '__main__':
155    main()
class Assignments:
 8class Assignments:
 9    """
10    Assignments are retrieved from the myPARISH calendar webcal feed. The assumption is made that the calendar is
11    first limited to only assignments, without other kinds of events. A list is created containing `Assignment` objects.
12    """
13    def __init__(self, start, end, url):
14        """
15        Constructor for `Assignments` class.
16        :param start: datetime object -> start date for assignments list
17        :param end: datetime object -> end date for assignments list
18        :param url: str -> webcal url to myPARISH calendar
19        """
20        self.URL = url
21        self.start_date = self.normalize_date(start)
22        self.end_date = self.normalize_date(end)
23        self.assignments = self.get_assignments()
24
25    def __str__(self):
26        """
27        String representation for `Assignments` objects
28        :return: str
29        """
30        output = ''
31
32        for assignment in self.assignments:
33            output += str(assignment) + '\n'
34
35        return output
36
37    def get_assignments(self):
38        """
39        Extract assignments from webcal feed and populate a list.
40        :return: list -> list of `Assignment` objects [`Assignment`, `Assignment`, ...]
41        """
42        es = events(self.URL, start=self.start_date, end=self.end_date, fix_apple=True)
43        es.sort()
44        ret_list = []
45        for event in es:
46            start_time = self.normalize_date(event.start)
47            ret_list.append(Assignment(start_time,
48                                       html.unescape(self.get_course(event.summary)),
49                                       html.unescape(self.get_name(event.summary))
50                                       ))
51        return ret_list
52
53    @staticmethod
54    def normalize_date(dt):
55        """
56        Convert `date` or `datetime` to `datetime` with timezone.
57        :param dt: date to normalize
58        :return: date as `datetime` with timezone
59        """
60        if type(dt) is date:
61            dt = datetime(dt.year, dt.month, dt.day, 0, 0)
62        elif type(dt) is datetime:
63            dt = dt
64        else:
65            raise ValueError("unknown type %s" % type(dt))
66
67        if not dt.tzinfo:
68            dt = utc.localize(dt)
69
70        return dt
71
72    @staticmethod
73    def get_course(summary):
74        """
75        Extract course name from `event.summary` property
76        :param summary: `event.summary`
77        :return: str -> name of course or `None`
78        """
79        if ':' in summary:
80            course = summary[:summary.find(':')]
81            return course.strip()
82        return None
83
84    @staticmethod
85    def get_name(summary):
86        """
87        Extract assignment name from `event.summary` property
88        :param summary: `event.summary`
89        :return: str -> name of assignment or `None`
90        """
91        if ':' in summary:
92            name = summary[summary.find(':') + 1:]
93            return name.strip()
94        return None

Assignments are retrieved from the myPARISH calendar webcal feed. The assumption is made that the calendar is first limited to only assignments, without other kinds of events. A list is created containing Assignment objects.

Assignments(start, end, url)
13    def __init__(self, start, end, url):
14        """
15        Constructor for `Assignments` class.
16        :param start: datetime object -> start date for assignments list
17        :param end: datetime object -> end date for assignments list
18        :param url: str -> webcal url to myPARISH calendar
19        """
20        self.URL = url
21        self.start_date = self.normalize_date(start)
22        self.end_date = self.normalize_date(end)
23        self.assignments = self.get_assignments()

Constructor for Assignments class.

Parameters
  • start: datetime object -> start date for assignments list
  • end: datetime object -> end date for assignments list
  • url: str -> webcal url to myPARISH calendar
def get_assignments(self):
37    def get_assignments(self):
38        """
39        Extract assignments from webcal feed and populate a list.
40        :return: list -> list of `Assignment` objects [`Assignment`, `Assignment`, ...]
41        """
42        es = events(self.URL, start=self.start_date, end=self.end_date, fix_apple=True)
43        es.sort()
44        ret_list = []
45        for event in es:
46            start_time = self.normalize_date(event.start)
47            ret_list.append(Assignment(start_time,
48                                       html.unescape(self.get_course(event.summary)),
49                                       html.unescape(self.get_name(event.summary))
50                                       ))
51        return ret_list

Extract assignments from webcal feed and populate a list.

Returns

list -> list of Assignment objects [Assignment, Assignment, ...]

@staticmethod
def normalize_date(dt):
53    @staticmethod
54    def normalize_date(dt):
55        """
56        Convert `date` or `datetime` to `datetime` with timezone.
57        :param dt: date to normalize
58        :return: date as `datetime` with timezone
59        """
60        if type(dt) is date:
61            dt = datetime(dt.year, dt.month, dt.day, 0, 0)
62        elif type(dt) is datetime:
63            dt = dt
64        else:
65            raise ValueError("unknown type %s" % type(dt))
66
67        if not dt.tzinfo:
68            dt = utc.localize(dt)
69
70        return dt

Convert date or datetime to datetime with timezone.

Parameters
  • dt: date to normalize
Returns

date as datetime with timezone

@staticmethod
def get_course(summary):
72    @staticmethod
73    def get_course(summary):
74        """
75        Extract course name from `event.summary` property
76        :param summary: `event.summary`
77        :return: str -> name of course or `None`
78        """
79        if ':' in summary:
80            course = summary[:summary.find(':')]
81            return course.strip()
82        return None

Extract course name from event.summary property

Parameters
  • summary: event.summary
Returns

str -> name of course or None

@staticmethod
def get_name(summary):
84    @staticmethod
85    def get_name(summary):
86        """
87        Extract assignment name from `event.summary` property
88        :param summary: `event.summary`
89        :return: str -> name of assignment or `None`
90        """
91        if ':' in summary:
92            name = summary[summary.find(':') + 1:]
93            return name.strip()
94        return None

Extract assignment name from event.summary property

Parameters
  • summary: event.summary
Returns

str -> name of assignment or None

class Assignment:
 97class Assignment:
 98    """
 99    Class for each individual assignment.
100    """
101    def __init__(self, d, c, n):
102        """
103        Constructor for `Assignment` class
104        :param d: datetime -> due date of assignment
105        :param c: str -> course name
106        :param n: str -> assignment name
107        """
108        self.date = d
109        self.course = c
110        self.name = n
111
112    def __str__(self):
113        """
114        String representation for `Assignment` objects
115        :return: str
116        """
117        return f'{datetime.date(self.date)} | {self.course} | {self.name}'

Class for each individual assignment.

Assignment(d, c, n)
101    def __init__(self, d, c, n):
102        """
103        Constructor for `Assignment` class
104        :param d: datetime -> due date of assignment
105        :param c: str -> course name
106        :param n: str -> assignment name
107        """
108        self.date = d
109        self.course = c
110        self.name = n

Constructor for Assignment class

Parameters
  • d: datetime -> due date of assignment
  • c: str -> course name
  • n: str -> assignment name
def main():
120def main():
121    """
122    This function executes only if this file is run directly. It is only present to show example usage.
123    Code that utilizes `Assignments` should be located in other files, not this one.
124    :return:
125    """
126    # Get URL from user. Possibly store in text file.
127    url = 'webcal://parish.myschoolapp.com/podium/feed/iCal.aspx?z=PBfWPW%2b7Bf8znQAnWIawKSUMruwMfYfE8DOy5Pq3KcqL5EEpKZ3SaFZKWyirslzw8uqEHM2%2bpImt5ve%2b8ykwEg%3d%3d'
128
129    # Also get these from user
130    start_yr = 2023
131    start_mth = 3
132    start_day = 6
133
134    end_yr = 2023
135    end_mth = 3
136    end_day = 15
137
138    # create Assignments object
139    my_assignments = Assignments(datetime(start_yr, start_mth, start_day), datetime(end_yr, end_mth, end_day), url)
140
141    # print assignments in a loop
142    # selection can be done on assignment properties
143    print('\nAssignments for Coding for OOP...')
144    for assignment in my_assignments.assignments:
145        if 'Coding for OOP' in assignment.course:
146            print(f'Date: {datetime.date(assignment.date)} | Course: {assignment.course} | Name: {assignment.name}')
147
148    # print all assignments
149    print('\nAll assignments...')
150    print(my_assignments)
151
152    print('Both printouts are limited to the date range given.')

This function executes only if this file is run directly. It is only present to show example usage. Code that utilizes Assignments should be located in other files, not this one.

Returns