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()
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.
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
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
, ...]
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
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
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
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.
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
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.