| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  | __filename__ = "happening.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							| 
									
										
										
										
											2022-02-03 13:58:20 +00:00
										 |  |  | __version__ = "1.3.0" | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							| 
									
										
										
										
											2021-09-10 16:14:50 +00:00
										 |  |  | __email__ = "bob@libreserver.org" | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  | __status__ = "Production" | 
					
						
							| 
									
										
										
										
											2021-06-25 16:10:09 +00:00
										 |  |  | __module_group__ = "Core" | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  | from uuid import UUID | 
					
						
							| 
									
										
										
										
											2022-02-23 12:19:27 +00:00
										 |  |  | from hashlib import md5 | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  | from datetime import datetime | 
					
						
							| 
									
										
										
										
											2021-05-31 13:00:17 +00:00
										 |  |  | from datetime import timedelta | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 14:41:10 +00:00
										 |  |  | from utils import is_public_post | 
					
						
							| 
									
										
										
										
											2021-12-26 15:13:34 +00:00
										 |  |  | from utils import load_json | 
					
						
							| 
									
										
										
										
											2021-12-26 14:47:21 +00:00
										 |  |  | from utils import save_json | 
					
						
							| 
									
										
										
										
											2021-12-26 20:36:08 +00:00
										 |  |  | from utils import locate_post | 
					
						
							| 
									
										
										
										
											2021-12-26 10:57:03 +00:00
										 |  |  | from utils import has_object_dict | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  | from utils import acct_dir | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  | from utils import remove_html | 
					
						
							|  |  |  | from utils import get_display_name | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  | from utils import delete_post | 
					
						
							|  |  |  | from utils import get_status_number | 
					
						
							| 
									
										
										
										
											2022-02-24 10:18:54 +00:00
										 |  |  | from utils import get_full_domain | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  | from filters import is_filtered | 
					
						
							|  |  |  | from context import get_individual_post_context | 
					
						
							| 
									
										
										
										
											2022-02-24 10:18:54 +00:00
										 |  |  | from session import get_method | 
					
						
							|  |  |  | from auth import create_basic_auth_header | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  | def _dav_date_from_string(timestamp: str) -> str: | 
					
						
							|  |  |  |     """Returns a datetime from a caldav date
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     timestamp_year = timestamp[:4] | 
					
						
							|  |  |  |     timestamp_month = timestamp[4:][:2] | 
					
						
							|  |  |  |     timestamp_day = timestamp[6:][:2] | 
					
						
							|  |  |  |     timestamp_hour = timestamp[9:][:2] | 
					
						
							|  |  |  |     timestamp_min = timestamp[11:][:2] | 
					
						
							|  |  |  |     timestamp_sec = timestamp[13:][:2] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not timestamp_year.isdigit() or \ | 
					
						
							|  |  |  |        not timestamp_month.isdigit() or \ | 
					
						
							|  |  |  |        not timestamp_day.isdigit() or \ | 
					
						
							|  |  |  |        not timestamp_hour.isdigit() or \ | 
					
						
							|  |  |  |        not timestamp_min.isdigit() or \ | 
					
						
							|  |  |  |        not timestamp_sec.isdigit(): | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     if int(timestamp_year) < 2020 or int(timestamp_year) > 2100: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     published = \ | 
					
						
							|  |  |  |         timestamp_year + '-' + timestamp_month + '-' + timestamp_day + 'T' + \ | 
					
						
							|  |  |  |         timestamp_hour + ':' + timestamp_min + ':' + timestamp_sec + 'Z' | 
					
						
							|  |  |  |     return published | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  | def _valid_uuid(test_uuid: str, version: int): | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |     """Check if uuid_to_test is a valid UUID
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         uuid_obj = UUID(test_uuid, version=version) | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |     except ValueError: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     return str(uuid_obj) == test_uuid | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  | def _remove_event_from_timeline(event_id: str, | 
					
						
							|  |  |  |                                 tl_events_filename: str) -> None: | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |     """Removes the given event Id from the timeline
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     if event_id + '\n' not in open(tl_events_filename).read(): | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     with open(tl_events_filename, 'r') as fp_tl: | 
					
						
							|  |  |  |         events_timeline = fp_tl.read().replace(event_id + '\n', '') | 
					
						
							| 
									
										
										
										
											2021-06-21 22:53:04 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |             with open(tl_events_filename, 'w+') as fp2: | 
					
						
							|  |  |  |                 fp2.write(events_timeline) | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2021-10-29 18:48:15 +00:00
										 |  |  |             print('EX: ERROR: unable to save events timeline') | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def save_event_post(base_dir: str, handle: str, post_id: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                     event_json: {}) -> bool: | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |     """Saves an event to the calendar and/or the events timeline
 | 
					
						
							|  |  |  |     If an event has extra fields, as per Mobilizon, | 
					
						
							|  |  |  |     Then it is saved as a separate entity and added to the | 
					
						
							|  |  |  |     events timeline | 
					
						
							| 
									
										
										
										
											2020-08-20 17:08:25 +00:00
										 |  |  |     See https://framagit.org/framasoft/mobilizon/-/blob/ | 
					
						
							|  |  |  |     master/lib/federation/activity_stream/converter/event.ex | 
					
						
							| 
									
										
										
										
											2020-08-13 11:58:05 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  |     if not os.path.isdir(base_dir + '/accounts/' + handle): | 
					
						
							| 
									
										
										
										
											2021-07-18 14:15:16 +00:00
										 |  |  |         print('WARN: Account does not exist at ' + | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  |               base_dir + '/accounts/' + handle) | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     calendar_path = base_dir + '/accounts/' + handle + '/calendar' | 
					
						
							|  |  |  |     if not os.path.isdir(calendar_path): | 
					
						
							|  |  |  |         os.mkdir(calendar_path) | 
					
						
							| 
									
										
										
										
											2020-08-13 11:58:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get the year, month and day from the event | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     event_time = datetime.strptime(event_json['startTime'], | 
					
						
							|  |  |  |                                    "%Y-%m-%dT%H:%M:%S%z") | 
					
						
							|  |  |  |     event_year = int(event_time.strftime("%Y")) | 
					
						
							|  |  |  |     if event_year < 2020 or event_year >= 2100: | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     event_month_number = int(event_time.strftime("%m")) | 
					
						
							|  |  |  |     if event_month_number < 1 or event_month_number > 12: | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     event_day_of_month = int(event_time.strftime("%d")) | 
					
						
							|  |  |  |     if event_day_of_month < 1 or event_day_of_month > 31: | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     if event_json.get('name') and event_json.get('actor') and \ | 
					
						
							|  |  |  |        event_json.get('uuid') and event_json.get('content'): | 
					
						
							|  |  |  |         if not _valid_uuid(event_json['uuid'], 4): | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2020-08-20 16:51:48 +00:00
										 |  |  |         print('Mobilizon type event') | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |         # if this is a full description of an event then save it | 
					
						
							|  |  |  |         # as a separate json file | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         events_path = base_dir + '/accounts/' + handle + '/events' | 
					
						
							|  |  |  |         if not os.path.isdir(events_path): | 
					
						
							|  |  |  |             os.mkdir(events_path) | 
					
						
							|  |  |  |         events_year_path = \ | 
					
						
							|  |  |  |             base_dir + '/accounts/' + handle + '/events/' + str(event_year) | 
					
						
							|  |  |  |         if not os.path.isdir(events_year_path): | 
					
						
							|  |  |  |             os.mkdir(events_year_path) | 
					
						
							|  |  |  |         event_id = str(event_year) + '-' + event_time.strftime("%m") + '-' + \ | 
					
						
							|  |  |  |             event_time.strftime("%d") + '_' + event_json['uuid'] | 
					
						
							|  |  |  |         event_filename = events_year_path + '/' + event_id + '.json' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         save_json(event_json, event_filename) | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |         # save to the events timeline | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         tl_events_filename = base_dir + '/accounts/' + handle + '/events.txt' | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         if os.path.isfile(tl_events_filename): | 
					
						
							|  |  |  |             _remove_event_from_timeline(event_id, tl_events_filename) | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                 with open(tl_events_filename, 'r+') as tl_events_file: | 
					
						
							|  |  |  |                     content = tl_events_file.read() | 
					
						
							|  |  |  |                     if event_id + '\n' not in content: | 
					
						
							|  |  |  |                         tl_events_file.seek(0, 0) | 
					
						
							|  |  |  |                         tl_events_file.write(event_id + '\n' + content) | 
					
						
							| 
									
										
										
										
											2021-12-25 15:28:52 +00:00
										 |  |  |             except OSError as ex: | 
					
						
							| 
									
										
										
										
											2021-11-25 22:22:54 +00:00
										 |  |  |                 print('EX: Failed to write entry to events file ' + | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                       tl_events_filename + ' ' + str(ex)) | 
					
						
							| 
									
										
										
										
											2020-08-13 13:40:38 +00:00
										 |  |  |                 return False | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                 with open(tl_events_filename, 'w+') as tl_events_file: | 
					
						
							|  |  |  |                     tl_events_file.write(event_id + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                 print('EX: unable to write ' + tl_events_filename) | 
					
						
							| 
									
										
										
										
											2020-08-13 11:58:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # create a directory for the calendar year | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     if not os.path.isdir(calendar_path + '/' + str(event_year)): | 
					
						
							|  |  |  |         os.mkdir(calendar_path + '/' + str(event_year)) | 
					
						
							| 
									
										
										
										
											2020-08-13 11:58:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # calendar month file containing event post Ids | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     calendar_filename = calendar_path + '/' + str(event_year) + \ | 
					
						
							|  |  |  |         '/' + str(event_month_number) + '.txt' | 
					
						
							| 
									
										
										
										
											2020-08-13 11:58:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Does this event post already exist within the calendar month? | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     if os.path.isfile(calendar_filename): | 
					
						
							|  |  |  |         if post_id in open(calendar_filename).read(): | 
					
						
							| 
									
										
										
										
											2020-08-13 11:58:05 +00:00
										 |  |  |             # Event post already exists | 
					
						
							|  |  |  |             return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # append the post Id to the file for the calendar month | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         with open(calendar_filename, 'a+') as calendar_file: | 
					
						
							|  |  |  |             calendar_file.write(post_id + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         print('EX: unable to append ' + calendar_filename) | 
					
						
							| 
									
										
										
										
											2020-08-13 11:58:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # create a file which will trigger a notification that | 
					
						
							|  |  |  |     # a new event has been added | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     cal_notify_filename = base_dir + '/accounts/' + handle + '/.newCalendar' | 
					
						
							|  |  |  |     notify_str = \ | 
					
						
							|  |  |  |         '/calendar?year=' + str(event_year) + '?month=' + \ | 
					
						
							|  |  |  |         str(event_month_number) + '?day=' + str(event_day_of_month) | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         with open(cal_notify_filename, 'w+') as cal_file: | 
					
						
							|  |  |  |             cal_file.write(notify_str) | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         print('EX: unable to write ' + cal_notify_filename) | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2020-08-13 11:58:05 +00:00
										 |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def _is_happening_event(tag: {}) -> bool: | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  |     """Is this tag an Event or Place ActivityStreams type?
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not tag.get('type'): | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |     if tag['type'] != 'Event' and tag['type'] != 'Place': | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  |         return False | 
					
						
							|  |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def _is_happening_post(post_json_object: {}) -> bool: | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  |     """Is this a post with tags?
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not post_json_object: | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-26 10:57:03 +00:00
										 |  |  |     if not has_object_dict(post_json_object): | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not post_json_object['object'].get('tag'): | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  |         return False | 
					
						
							|  |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  | def _event_text_match(content: str, text_match: str) -> bool: | 
					
						
							|  |  |  |     """Returns true of the content matches the search text
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not text_match: | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  |     if '+' not in text_match: | 
					
						
							|  |  |  |         if text_match.strip().lower() in content.lower(): | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         match_list = text_match.split('+') | 
					
						
							|  |  |  |         for possible_match in match_list: | 
					
						
							|  |  |  |             if possible_match.strip().lower() in content.lower(): | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def get_todays_events(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |                       curr_year: int, curr_month_number: int, | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                       curr_day_of_month: int, | 
					
						
							| 
									
										
										
										
											2022-04-13 15:06:03 +00:00
										 |  |  |                       text_match: str, system_language: str) -> {}: | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |     """Retrieves calendar events for today
 | 
					
						
							|  |  |  |     Returns a dictionary of lists containing Event and Place activities | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |     now = datetime.now() | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |     if not curr_year: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |         year = now.year | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |         year = curr_year | 
					
						
							|  |  |  |     if not curr_month_number: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         month_number = now.month | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |         month_number = curr_month_number | 
					
						
							| 
									
										
										
										
											2022-02-21 16:58:37 +00:00
										 |  |  |     if not curr_day_of_month: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         day_number = now.day | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2022-02-21 16:58:37 +00:00
										 |  |  |         day_number = curr_day_of_month | 
					
						
							| 
									
										
										
										
											2020-02-23 09:45:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     calendar_filename = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  |         acct_dir(base_dir, nickname, domain) + \ | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         '/calendar/' + str(year) + '/' + str(month_number) + '.txt' | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |     events = {} | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     if not os.path.isfile(calendar_filename): | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |         return events | 
					
						
							| 
									
										
										
										
											2020-02-23 09:45:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     calendar_post_ids = [] | 
					
						
							|  |  |  |     recreate_events_file = False | 
					
						
							|  |  |  |     with open(calendar_filename, 'r') as events_file: | 
					
						
							|  |  |  |         for post_id in events_file: | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |             post_id = post_id.replace('\n', '').replace('\r', '') | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |             post_filename = locate_post(base_dir, nickname, domain, post_id) | 
					
						
							|  |  |  |             if not post_filename: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                 recreate_events_file = True | 
					
						
							| 
									
										
										
										
											2020-02-23 09:49:10 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |             post_json_object = load_json(post_filename) | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |             if not _is_happening_post(post_json_object): | 
					
						
							| 
									
										
										
										
											2020-02-23 09:49:10 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |             if post_json_object.get('object'): | 
					
						
							| 
									
										
										
										
											2022-04-13 15:06:03 +00:00
										 |  |  |                 content = None | 
					
						
							|  |  |  |                 if post_json_object['object'].get('contentMap'): | 
					
						
							|  |  |  |                     sys_lang = system_language | 
					
						
							|  |  |  |                     if post_json_object['object']['contentMap'].get(sys_lang): | 
					
						
							|  |  |  |                         content = \ | 
					
						
							|  |  |  |                             post_json_object['object']['contentMap'][sys_lang] | 
					
						
							|  |  |  |                 if not content: | 
					
						
							|  |  |  |                     if post_json_object['object'].get('content'): | 
					
						
							|  |  |  |                         content = post_json_object['object']['content'] | 
					
						
							|  |  |  |                 if content: | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                     if not _event_text_match(content, text_match): | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |             public_event = is_public_post(post_json_object) | 
					
						
							| 
									
										
										
										
											2021-03-07 14:52:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |             post_event = [] | 
					
						
							|  |  |  |             day_of_month = None | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |             for tag in post_json_object['object']['tag']: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                 if not _is_happening_event(tag): | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  |                 # this tag is an event or a place | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |                 if tag['type'] == 'Event': | 
					
						
							| 
									
										
										
										
											2020-02-23 09:49:10 +00:00
										 |  |  |                     # tag is an event | 
					
						
							|  |  |  |                     if not tag.get('startTime'): | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |                         continue | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                     event_time = \ | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |                         datetime.strptime(tag['startTime'], | 
					
						
							| 
									
										
										
										
											2020-02-23 09:49:10 +00:00
										 |  |  |                                           "%Y-%m-%dT%H:%M:%S%z") | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                     if int(event_time.strftime("%Y")) == year and \ | 
					
						
							|  |  |  |                        int(event_time.strftime("%m")) == month_number and \ | 
					
						
							|  |  |  |                        int(event_time.strftime("%d")) == day_number: | 
					
						
							|  |  |  |                         day_of_month = str(int(event_time.strftime("%d"))) | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |                         if '#statuses#' in post_id: | 
					
						
							| 
									
										
										
										
											2020-02-24 10:55:49 +00:00
										 |  |  |                             # link to the id so that the event can be | 
					
						
							|  |  |  |                             # easily deleted | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |                             tag['post_id'] = post_id.split('#statuses#')[1] | 
					
						
							| 
									
										
										
										
											2022-02-21 19:15:35 +00:00
										 |  |  |                             tag['id'] = post_id.replace('#', '/') | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |                             tag['sender'] = post_id.split('#statuses#')[0] | 
					
						
							| 
									
										
										
										
											2021-03-06 18:38:36 +00:00
										 |  |  |                             tag['sender'] = tag['sender'].replace('#', '/') | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                             tag['public'] = public_event | 
					
						
							|  |  |  |                         post_event.append(tag) | 
					
						
							| 
									
										
										
										
											2020-02-23 09:49:10 +00:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     # tag is a place | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                     post_event.append(tag) | 
					
						
							|  |  |  |             if post_event and day_of_month: | 
					
						
							|  |  |  |                 calendar_post_ids.append(post_id) | 
					
						
							|  |  |  |                 if not events.get(day_of_month): | 
					
						
							|  |  |  |                     events[day_of_month] = [] | 
					
						
							|  |  |  |                 events[day_of_month].append(post_event) | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # if some posts have been deleted then regenerate the calendar file | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     if recreate_events_file: | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |             with open(calendar_filename, 'w+') as calendar_file: | 
					
						
							|  |  |  |                 for post_id in calendar_post_ids: | 
					
						
							|  |  |  |                     calendar_file.write(post_id + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |             print('EX: unable to write ' + calendar_filename) | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return events | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 18:20:59 +00:00
										 |  |  | def _ical_date_string(date_str: str) -> str: | 
					
						
							|  |  |  |     """Returns an icalendar formatted date
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     date_str = date_str.replace('-', '') | 
					
						
							|  |  |  |     date_str = date_str.replace(':', '') | 
					
						
							|  |  |  |     return date_str.replace(' ', '') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  | def _dav_encode_token(year: int, month_number: int, | 
					
						
							|  |  |  |                       message_id: str) -> str: | 
					
						
							|  |  |  |     """Returns a token corresponding to a calendar event
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     return str(year) + '_' + str(month_number) + '_' + \ | 
					
						
							|  |  |  |         message_id.replace('/', '--').replace('#', '--') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  | def _icalendar_day(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-02-21 19:01:19 +00:00
										 |  |  |                    day_events: [], person_cache: {}, | 
					
						
							|  |  |  |                    http_prefix: str) -> str: | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |     """Returns a day's events in icalendar format
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     ical_str = '' | 
					
						
							| 
									
										
										
										
											2022-02-21 14:49:19 +00:00
										 |  |  |     print('icalendar: ' + str(day_events)) | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |     for event_post in day_events: | 
					
						
							|  |  |  |         event_description = None | 
					
						
							|  |  |  |         event_place = None | 
					
						
							|  |  |  |         post_id = None | 
					
						
							|  |  |  |         sender_name = '' | 
					
						
							|  |  |  |         sender_actor = None | 
					
						
							|  |  |  |         event_is_public = False | 
					
						
							|  |  |  |         event_start = None | 
					
						
							|  |  |  |         event_end = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for evnt in event_post: | 
					
						
							|  |  |  |             if evnt['type'] == 'Event': | 
					
						
							| 
									
										
										
										
											2022-02-21 19:13:19 +00:00
										 |  |  |                 if evnt.get('id'): | 
					
						
							|  |  |  |                     post_id = evnt['id'] | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |                 if evnt.get('startTime'): | 
					
						
							|  |  |  |                     event_start = \ | 
					
						
							|  |  |  |                         datetime.strptime(evnt['startTime'], | 
					
						
							| 
									
										
										
										
											2022-02-21 18:20:59 +00:00
										 |  |  |                                           "%Y-%m-%dT%H:%M:%S%z") | 
					
						
							| 
									
										
										
										
											2022-02-21 19:01:19 +00:00
										 |  |  |                 if evnt.get('endTime'): | 
					
						
							|  |  |  |                     event_end = \ | 
					
						
							|  |  |  |                         datetime.strptime(evnt['startTime'], | 
					
						
							|  |  |  |                                           "%Y-%m-%dT%H:%M:%S%z") | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |                 if 'public' in evnt: | 
					
						
							|  |  |  |                     if evnt['public'] is True: | 
					
						
							|  |  |  |                         event_is_public = True | 
					
						
							|  |  |  |                 if evnt.get('sender'): | 
					
						
							|  |  |  |                     # get display name from sending actor | 
					
						
							|  |  |  |                     if evnt.get('sender'): | 
					
						
							|  |  |  |                         sender_actor = evnt['sender'] | 
					
						
							|  |  |  |                         disp_name = \ | 
					
						
							|  |  |  |                             get_display_name(base_dir, sender_actor, | 
					
						
							|  |  |  |                                              person_cache) | 
					
						
							|  |  |  |                         if disp_name: | 
					
						
							|  |  |  |                             sender_name = \ | 
					
						
							|  |  |  |                                 '<a href="' + sender_actor + '">' + \ | 
					
						
							| 
									
										
										
										
											2022-02-21 19:09:43 +00:00
										 |  |  |                                 disp_name + '</a>' | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |                 if evnt.get('name'): | 
					
						
							|  |  |  |                     event_description = evnt['name'].strip() | 
					
						
							|  |  |  |             elif evnt['type'] == 'Place': | 
					
						
							|  |  |  |                 if evnt.get('name'): | 
					
						
							|  |  |  |                     event_place = evnt['name'] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 14:46:46 +00:00
										 |  |  |         print('icalendar: ' + str(post_id) + ' ' + | 
					
						
							|  |  |  |               str(event_start) + ' ' + str(event_description) + ' ' + | 
					
						
							|  |  |  |               str(sender_actor)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 19:01:19 +00:00
										 |  |  |         if not post_id or not event_start or not event_end or \ | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |            not event_description or not sender_actor: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # find the corresponding post | 
					
						
							|  |  |  |         post_filename = locate_post(base_dir, nickname, domain, post_id) | 
					
						
							|  |  |  |         if not post_filename: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         post_json_object = load_json(post_filename) | 
					
						
							|  |  |  |         if not post_json_object: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # get the published date from the post | 
					
						
							|  |  |  |         if not post_json_object.get('object'): | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if not isinstance(post_json_object['object'], dict): | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if not post_json_object['object'].get('published'): | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if not isinstance(post_json_object['object']['published'], str): | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-02-21 18:20:59 +00:00
										 |  |  |         published = \ | 
					
						
							|  |  |  |             _ical_date_string(post_json_object['object']['published']) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         event_start = \ | 
					
						
							|  |  |  |             _ical_date_string(event_start.strftime("%Y-%m-%dT%H:%M:%SZ")) | 
					
						
							| 
									
										
										
										
											2022-02-21 19:01:19 +00:00
										 |  |  |         event_end = \ | 
					
						
							|  |  |  |             _ical_date_string(event_end.strftime("%Y-%m-%dT%H:%M:%SZ")) | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 09:58:54 +00:00
										 |  |  |         token_year = int(event_start[:4]) | 
					
						
							| 
									
										
										
										
											2022-02-23 10:00:12 +00:00
										 |  |  |         token_month_number = int(event_start[4:][:2]) | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  |         uid = _dav_encode_token(token_year, token_month_number, post_id) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |         ical_str += \ | 
					
						
							|  |  |  |             'BEGIN:VEVENT\n' + \ | 
					
						
							|  |  |  |             'DTSTAMP:' + published + '\n' + \ | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  |             'UID:' + uid + '\n' + \ | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |             'DTSTART:' + event_start + '\n' + \ | 
					
						
							|  |  |  |             'DTEND:' + event_end + '\n' + \ | 
					
						
							|  |  |  |             'STATUS:CONFIRMED\n' | 
					
						
							|  |  |  |         descr = remove_html(event_description) | 
					
						
							|  |  |  |         if len(descr) < 255: | 
					
						
							|  |  |  |             ical_str += \ | 
					
						
							|  |  |  |                 'SUMMARY:' + descr + '\n' | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             ical_str += \ | 
					
						
							|  |  |  |                 'SUMMARY:' + descr[255:] + '\n' | 
					
						
							|  |  |  |             ical_str += \ | 
					
						
							|  |  |  |                 'DESCRIPTION:' + descr + '\n' | 
					
						
							|  |  |  |         if event_is_public: | 
					
						
							|  |  |  |             ical_str += \ | 
					
						
							|  |  |  |                 'CATEGORIES:APPOINTMENT,PUBLIC\n' | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             ical_str += \ | 
					
						
							|  |  |  |                 'CATEGORIES:APPOINTMENT\n' | 
					
						
							|  |  |  |         if sender_name: | 
					
						
							|  |  |  |             ical_str += \ | 
					
						
							|  |  |  |                 'ORGANIZER;CN=' + remove_html(sender_name) + ':' + \ | 
					
						
							|  |  |  |                 sender_actor + '\n' | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             ical_str += \ | 
					
						
							|  |  |  |                 'ORGANIZER:' + sender_actor + '\n' | 
					
						
							|  |  |  |         if event_place: | 
					
						
							|  |  |  |             ical_str += \ | 
					
						
							|  |  |  |                 'LOCATION:' + remove_html(event_place) + '\n' | 
					
						
							|  |  |  |         ical_str += 'END:VEVENT\n' | 
					
						
							|  |  |  |     return ical_str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_todays_events_icalendar(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                                 year: int, month_number: int, | 
					
						
							| 
									
										
										
										
											2022-02-21 19:01:19 +00:00
										 |  |  |                                 day_number: int, person_cache: {}, | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                                 http_prefix: str, | 
					
						
							| 
									
										
										
										
											2022-04-13 15:06:03 +00:00
										 |  |  |                                 text_match: str, system_language: str) -> str: | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |     """Returns today's events in icalendar format
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-02-21 17:27:37 +00:00
										 |  |  |     day_events = None | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |     events = \ | 
					
						
							|  |  |  |         get_todays_events(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                           year, month_number, day_number, | 
					
						
							| 
									
										
										
										
											2022-04-13 15:06:03 +00:00
										 |  |  |                           text_match, system_language) | 
					
						
							| 
									
										
										
										
											2022-02-21 17:27:37 +00:00
										 |  |  |     if events: | 
					
						
							|  |  |  |         if events.get(str(day_number)): | 
					
						
							|  |  |  |             day_events = events[str(day_number)] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |     ical_str = \ | 
					
						
							|  |  |  |         'BEGIN:VCALENDAR\n' + \ | 
					
						
							| 
									
										
										
										
											2022-02-21 11:45:29 +00:00
										 |  |  |         'PRODID:-//Fediverse//NONSGML Epicyon//EN\n' + \ | 
					
						
							|  |  |  |         'VERSION:2.0\n' | 
					
						
							| 
									
										
										
										
											2022-02-21 17:27:37 +00:00
										 |  |  |     if not day_events: | 
					
						
							| 
									
										
										
										
											2022-02-21 17:38:07 +00:00
										 |  |  |         print('icalendar daily: ' + nickname + '@' + domain + ' ' + | 
					
						
							|  |  |  |               str(year) + '-' + str(month_number) + | 
					
						
							| 
									
										
										
										
											2022-02-21 17:27:37 +00:00
										 |  |  |               '-' + str(day_number) + ' ' + str(day_events)) | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |         ical_str += 'END:VCALENDAR\n' | 
					
						
							|  |  |  |         return ical_str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ical_str += \ | 
					
						
							| 
									
										
										
										
											2022-02-21 19:01:19 +00:00
										 |  |  |         _icalendar_day(base_dir, nickname, domain, day_events, person_cache, | 
					
						
							|  |  |  |                        http_prefix) | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ical_str += 'END:VCALENDAR\n' | 
					
						
							|  |  |  |     return ical_str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_month_events_icalendar(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-02-21 14:46:46 +00:00
										 |  |  |                                year: int, | 
					
						
							|  |  |  |                                month_number: int, | 
					
						
							| 
									
										
										
										
											2022-02-21 19:01:19 +00:00
										 |  |  |                                person_cache: {}, | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                                http_prefix: str, | 
					
						
							|  |  |  |                                text_match: str) -> str: | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |     """Returns today's events in icalendar format
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-02-21 18:20:59 +00:00
										 |  |  |     month_events = \ | 
					
						
							| 
									
										
										
										
											2022-02-21 14:46:46 +00:00
										 |  |  |         get_calendar_events(base_dir, nickname, domain, year, | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                             month_number, text_match) | 
					
						
							| 
									
										
										
										
											2022-02-21 17:34:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |     ical_str = \ | 
					
						
							|  |  |  |         'BEGIN:VCALENDAR\n' + \ | 
					
						
							| 
									
										
										
										
											2022-02-21 11:51:43 +00:00
										 |  |  |         'PRODID:-//Fediverse//NONSGML Epicyon//EN\n' + \ | 
					
						
							|  |  |  |         'VERSION:2.0\n' | 
					
						
							| 
									
										
										
										
											2022-02-21 17:34:14 +00:00
										 |  |  |     if not month_events: | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |         ical_str += 'END:VCALENDAR\n' | 
					
						
							|  |  |  |         return ical_str | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-21 17:34:14 +00:00
										 |  |  |     print('icalendar month: ' + str(month_events)) | 
					
						
							| 
									
										
										
										
											2022-02-21 14:46:46 +00:00
										 |  |  |     for day_of_month in range(1, 32): | 
					
						
							| 
									
										
										
										
											2022-02-21 17:34:14 +00:00
										 |  |  |         if not month_events.get(str(day_of_month)): | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-02-21 17:34:14 +00:00
										 |  |  |         day_events = month_events[str(day_of_month)] | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |         ical_str += \ | 
					
						
							| 
									
										
										
										
											2022-02-21 14:46:46 +00:00
										 |  |  |             _icalendar_day(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2022-02-21 19:01:19 +00:00
										 |  |  |                            day_events, person_cache, | 
					
						
							|  |  |  |                            http_prefix) | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ical_str += 'END:VCALENDAR\n' | 
					
						
							|  |  |  |     return ical_str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def day_events_check(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |                      curr_date) -> bool: | 
					
						
							| 
									
										
										
										
											2021-05-31 11:57:36 +00:00
										 |  |  |     """Are there calendar events for the given date?
 | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-02-21 11:08:48 +00:00
										 |  |  |     year = curr_date.year | 
					
						
							|  |  |  |     month_number = curr_date.month | 
					
						
							|  |  |  |     day_number = curr_date.day | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     calendar_filename = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  |         acct_dir(base_dir, nickname, domain) + \ | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         '/calendar/' + str(year) + '/' + str(month_number) + '.txt' | 
					
						
							|  |  |  |     if not os.path.isfile(calendar_filename): | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2020-02-23 09:45:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     events_exist = False | 
					
						
							|  |  |  |     with open(calendar_filename, 'r') as events_file: | 
					
						
							|  |  |  |         for post_id in events_file: | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |             post_id = post_id.replace('\n', '').replace('\r', '') | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |             post_filename = locate_post(base_dir, nickname, domain, post_id) | 
					
						
							|  |  |  |             if not post_filename: | 
					
						
							| 
									
										
										
										
											2020-02-23 09:49:10 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |             post_json_object = load_json(post_filename) | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |             if not _is_happening_post(post_json_object): | 
					
						
							| 
									
										
										
										
											2020-02-23 09:49:10 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |             for tag in post_json_object['object']['tag']: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                 if not _is_happening_event(tag): | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  |                 # this tag is an event or a place | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |                 if tag['type'] != 'Event': | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  |                 # tag is an event | 
					
						
							|  |  |  |                 if not tag.get('startTime'): | 
					
						
							|  |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                 event_time = \ | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |                     datetime.strptime(tag['startTime'], | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  |                                       "%Y-%m-%dT%H:%M:%S%z") | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                 if int(event_time.strftime("%d")) != day_number: | 
					
						
							| 
									
										
										
										
											2021-05-31 10:24:48 +00:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                 if int(event_time.strftime("%m")) != month_number: | 
					
						
							| 
									
										
										
										
											2021-05-31 10:24:48 +00:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                 if int(event_time.strftime("%Y")) != year: | 
					
						
							| 
									
										
										
										
											2021-05-31 10:24:48 +00:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                 events_exist = True | 
					
						
							| 
									
										
										
										
											2021-05-31 10:24:48 +00:00
										 |  |  |                 break | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     return events_exist | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def get_this_weeks_events(base_dir: str, nickname: str, domain: str) -> {}: | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |     """Retrieves calendar events for this week
 | 
					
						
							| 
									
										
										
										
											2020-02-24 10:55:49 +00:00
										 |  |  |     Returns a dictionary indexed by day number of lists containing | 
					
						
							|  |  |  |     Event and Place activities | 
					
						
							| 
									
										
										
										
											2020-02-23 09:42:09 +00:00
										 |  |  |     Note: currently not used but could be with a weekly calendar screen | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |     now = datetime.now() | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     end_of_week = now + timedelta(7) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |     year = now.year | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     month_number = now.month | 
					
						
							| 
									
										
										
										
											2020-02-23 09:45:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     calendar_filename = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  |         acct_dir(base_dir, nickname, domain) + \ | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         '/calendar/' + str(year) + '/' + str(month_number) + '.txt' | 
					
						
							| 
									
										
										
										
											2020-02-23 09:45:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |     events = {} | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     if not os.path.isfile(calendar_filename): | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |         return events | 
					
						
							| 
									
										
										
										
											2020-02-23 09:45:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     calendar_post_ids = [] | 
					
						
							|  |  |  |     recreate_events_file = False | 
					
						
							|  |  |  |     with open(calendar_filename, 'r') as events_file: | 
					
						
							|  |  |  |         for post_id in events_file: | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |             post_id = post_id.replace('\n', '').replace('\r', '') | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |             post_filename = locate_post(base_dir, nickname, domain, post_id) | 
					
						
							|  |  |  |             if not post_filename: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                 recreate_events_file = True | 
					
						
							| 
									
										
										
										
											2020-02-23 09:49:10 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |             post_json_object = load_json(post_filename) | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |             if not _is_happening_post(post_json_object): | 
					
						
							| 
									
										
										
										
											2020-02-23 09:49:10 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |             post_event = [] | 
					
						
							|  |  |  |             week_day_index = None | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |             for tag in post_json_object['object']['tag']: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                 if not _is_happening_event(tag): | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  |                 # this tag is an event or a place | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |                 if tag['type'] == 'Event': | 
					
						
							| 
									
										
										
										
											2020-02-23 09:49:10 +00:00
										 |  |  |                     # tag is an event | 
					
						
							|  |  |  |                     if not tag.get('startTime'): | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  |                         continue | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                     event_time = \ | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |                         datetime.strptime(tag['startTime'], | 
					
						
							| 
									
										
										
										
											2020-02-23 09:49:10 +00:00
										 |  |  |                                           "%Y-%m-%dT%H:%M:%S%z") | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                     if event_time >= now and event_time <= end_of_week: | 
					
						
							|  |  |  |                         week_day_index = (event_time - now).days() | 
					
						
							|  |  |  |                         post_event.append(tag) | 
					
						
							| 
									
										
										
										
											2020-02-23 09:49:10 +00:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     # tag is a place | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                     post_event.append(tag) | 
					
						
							|  |  |  |             if post_event and week_day_index: | 
					
						
							|  |  |  |                 calendar_post_ids.append(post_id) | 
					
						
							|  |  |  |                 if not events.get(week_day_index): | 
					
						
							|  |  |  |                     events[week_day_index] = [] | 
					
						
							|  |  |  |                 events[week_day_index].append(post_event) | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # if some posts have been deleted then regenerate the calendar file | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     if recreate_events_file: | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |             with open(calendar_filename, 'w+') as calendar_file: | 
					
						
							|  |  |  |                 for post_id in calendar_post_ids: | 
					
						
							|  |  |  |                     calendar_file.write(post_id + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |             print('EX: unable to write ' + calendar_filename) | 
					
						
							| 
									
										
										
										
											2020-02-22 19:11:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return events | 
					
						
							| 
									
										
										
										
											2020-02-23 09:35:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def get_calendar_events(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                         year: int, month_number: int, | 
					
						
							|  |  |  |                         text_match: str) -> {}: | 
					
						
							| 
									
										
										
										
											2020-02-23 09:35:52 +00:00
										 |  |  |     """Retrieves calendar events
 | 
					
						
							| 
									
										
										
										
											2020-02-24 10:55:49 +00:00
										 |  |  |     Returns a dictionary indexed by day number of lists containing | 
					
						
							|  |  |  |     Event and Place activities | 
					
						
							| 
									
										
										
										
											2020-02-23 09:35:52 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     calendar_filename = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  |         acct_dir(base_dir, nickname, domain) + \ | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         '/calendar/' + str(year) + '/' + str(month_number) + '.txt' | 
					
						
							| 
									
										
										
										
											2020-02-23 09:45:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |     events = {} | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     if not os.path.isfile(calendar_filename): | 
					
						
							| 
									
										
										
										
											2020-02-23 09:35:52 +00:00
										 |  |  |         return events | 
					
						
							| 
									
										
										
										
											2020-02-23 09:45:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     calendar_post_ids = [] | 
					
						
							|  |  |  |     recreate_events_file = False | 
					
						
							|  |  |  |     with open(calendar_filename, 'r') as events_file: | 
					
						
							|  |  |  |         for post_id in events_file: | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |             post_id = post_id.replace('\n', '').replace('\r', '') | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |             post_filename = locate_post(base_dir, nickname, domain, post_id) | 
					
						
							|  |  |  |             if not post_filename: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                 recreate_events_file = True | 
					
						
							| 
									
										
										
										
											2020-02-23 09:42:09 +00:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |             post_json_object = load_json(post_filename) | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |             if not post_json_object: | 
					
						
							|  |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |             if not _is_happening_post(post_json_object): | 
					
						
							| 
									
										
										
										
											2020-02-23 09:42:09 +00:00
										 |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |             if post_json_object.get('object'): | 
					
						
							|  |  |  |                 if post_json_object['object'].get('content'): | 
					
						
							|  |  |  |                     content = post_json_object['object']['content'] | 
					
						
							|  |  |  |                     if not _event_text_match(content, text_match): | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |             post_event = [] | 
					
						
							|  |  |  |             day_of_month = None | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |             for tag in post_json_object['object']['tag']: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                 if not _is_happening_event(tag): | 
					
						
							| 
									
										
										
										
											2020-02-23 09:42:09 +00:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2020-02-24 11:10:48 +00:00
										 |  |  |                 # this tag is an event or a place | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |                 if tag['type'] == 'Event': | 
					
						
							| 
									
										
										
										
											2020-02-23 09:42:09 +00:00
										 |  |  |                     # tag is an event | 
					
						
							|  |  |  |                     if not tag.get('startTime'): | 
					
						
							|  |  |  |                         continue | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                     event_time = \ | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |                         datetime.strptime(tag['startTime'], | 
					
						
							| 
									
										
										
										
											2020-02-23 09:42:09 +00:00
										 |  |  |                                           "%Y-%m-%dT%H:%M:%S%z") | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                     if int(event_time.strftime("%Y")) == year and \ | 
					
						
							|  |  |  |                        int(event_time.strftime("%m")) == month_number: | 
					
						
							|  |  |  |                         day_of_month = str(int(event_time.strftime("%d"))) | 
					
						
							| 
									
										
										
										
											2022-02-21 19:32:40 +00:00
										 |  |  |                         if '#statuses#' in post_id: | 
					
						
							|  |  |  |                             tag['post_id'] = post_id.split('#statuses#')[1] | 
					
						
							|  |  |  |                             tag['id'] = post_id.replace('#', '/') | 
					
						
							|  |  |  |                             tag['sender'] = post_id.split('#statuses#')[0] | 
					
						
							|  |  |  |                             tag['sender'] = tag['sender'].replace('#', '/') | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                         post_event.append(tag) | 
					
						
							| 
									
										
										
										
											2020-02-23 09:42:09 +00:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     # tag is a place | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                     post_event.append(tag) | 
					
						
							| 
									
										
										
										
											2020-02-23 09:42:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |             if post_event and day_of_month: | 
					
						
							|  |  |  |                 calendar_post_ids.append(post_id) | 
					
						
							|  |  |  |                 if not events.get(day_of_month): | 
					
						
							|  |  |  |                     events[day_of_month] = [] | 
					
						
							|  |  |  |                 events[day_of_month].append(post_event) | 
					
						
							| 
									
										
										
										
											2020-02-23 09:35:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # if some posts have been deleted then regenerate the calendar file | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     if recreate_events_file: | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |             with open(calendar_filename, 'w+') as calendar_file: | 
					
						
							|  |  |  |                 for post_id in calendar_post_ids: | 
					
						
							|  |  |  |                     calendar_file.write(post_id + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |             print('EX: unable to write ' + calendar_filename) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-23 09:35:52 +00:00
										 |  |  |     return events | 
					
						
							| 
									
										
										
										
											2020-02-23 13:28:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def remove_calendar_event(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                           year: int, month_number: int, | 
					
						
							|  |  |  |                           message_id: str) -> None: | 
					
						
							| 
									
										
										
										
											2020-02-23 13:28:27 +00:00
										 |  |  |     """Removes a calendar event
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     calendar_filename = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  |         acct_dir(base_dir, nickname, domain) + \ | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         '/calendar/' + str(year) + '/' + str(month_number) + '.txt' | 
					
						
							|  |  |  |     if not os.path.isfile(calendar_filename): | 
					
						
							| 
									
										
										
										
											2020-02-23 13:28:27 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     if '/' in message_id: | 
					
						
							|  |  |  |         message_id = message_id.replace('/', '#') | 
					
						
							|  |  |  |     if message_id not in open(calendar_filename).read(): | 
					
						
							| 
									
										
										
										
											2020-02-23 13:28:27 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2020-04-03 11:53:31 +00:00
										 |  |  |     lines = None | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |     with open(calendar_filename, 'r') as fp_cal: | 
					
						
							|  |  |  |         lines = fp_cal.readlines() | 
					
						
							| 
									
										
										
										
											2020-02-23 13:28:27 +00:00
										 |  |  |     if not lines: | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         with open(calendar_filename, 'w+') as fp_cal: | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |             for line in lines: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |                 if message_id not in line: | 
					
						
							|  |  |  |                     fp_cal.write(line) | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 15:16:47 +00:00
										 |  |  |         print('EX: unable to write ' + calendar_filename) | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _dav_decode_token(token: str) -> (int, int, str): | 
					
						
							|  |  |  |     """Decodes a token corresponding to a calendar event
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if '_' not in token or '--' not in token: | 
					
						
							|  |  |  |         return None, None, None | 
					
						
							|  |  |  |     token_sections = token.split('_') | 
					
						
							|  |  |  |     if len(token_sections) != 3: | 
					
						
							|  |  |  |         return None, None, None | 
					
						
							|  |  |  |     if not token_sections[0].isdigit(): | 
					
						
							|  |  |  |         return None, None, None | 
					
						
							|  |  |  |     if not token_sections[1].isdigit(): | 
					
						
							|  |  |  |         return None, None, None | 
					
						
							|  |  |  |     token_year = int(token_sections[0]) | 
					
						
							|  |  |  |     token_month_number = int(token_sections[1]) | 
					
						
							|  |  |  |     token_post_id = token_sections[2].replace('--', '/') | 
					
						
							|  |  |  |     return token_year, token_month_number, token_post_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def dav_propfind_response(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                           depth: int, xml_str: str) -> str: | 
					
						
							|  |  |  |     """Returns the response to caldav PROPFIND
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if '<d:propfind' not in xml_str or \ | 
					
						
							|  |  |  |        '</d:propfind>' not in xml_str: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     response_str = \ | 
					
						
							|  |  |  |         '<d:multistatus xmlns:d="DAV:" ' + \ | 
					
						
							|  |  |  |         'xmlns:cs="http://calendarserver.org/ns/">\n' + \ | 
					
						
							|  |  |  |         '    <d:response>\n' + \ | 
					
						
							|  |  |  |         '        <d:href>/calendars/' + nickname + '/</d:href>\n' + \ | 
					
						
							|  |  |  |         '        <d:propstat>\n' + \ | 
					
						
							|  |  |  |         '            <d:prop>\n' + \ | 
					
						
							|  |  |  |         '                <d:displayname />\n' + \ | 
					
						
							|  |  |  |         '                <cs:getctag />\n' + \ | 
					
						
							|  |  |  |         '            </d:prop>\n' + \ | 
					
						
							|  |  |  |         '            <d:status>HTTP/1.1 200 OK</d:status>\n' + \ | 
					
						
							|  |  |  |         '        </d:propstat>\n' + \ | 
					
						
							|  |  |  |         '    </d:response>\n' + \ | 
					
						
							|  |  |  |         '</d:multistatus>' | 
					
						
							|  |  |  |     return response_str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _dav_store_event(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                      event_list: [], http_prefix: str, | 
					
						
							|  |  |  |                      system_language: str) -> bool: | 
					
						
							|  |  |  |     """Stores a calendar event obtained via caldav PUT
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     event_str = str(event_list) | 
					
						
							|  |  |  |     if 'DTSTAMP:' not in event_str or \ | 
					
						
							|  |  |  |        'DTSTART:' not in event_str or \ | 
					
						
							|  |  |  |        'DTEND:' not in event_str: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     if 'STATUS:' not in event_str and 'DESCRIPTION:' not in event_str: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     timestamp = None | 
					
						
							|  |  |  |     start_time = None | 
					
						
							|  |  |  |     end_time = None | 
					
						
							|  |  |  |     description = None | 
					
						
							|  |  |  |     for line in event_list: | 
					
						
							|  |  |  |         if line.startswith('DTSTAMP:'): | 
					
						
							|  |  |  |             timestamp = line.split(':', 1)[1] | 
					
						
							|  |  |  |         elif line.startswith('DTSTART:'): | 
					
						
							|  |  |  |             start_time = line.split(':', 1)[1] | 
					
						
							|  |  |  |         elif line.startswith('DTEND:'): | 
					
						
							|  |  |  |             end_time = line.split(':', 1)[1] | 
					
						
							|  |  |  |         elif line.startswith('SUMMARY:') or line.startswith('DESCRIPTION:'): | 
					
						
							|  |  |  |             description = line.split(':', 1)[1] | 
					
						
							|  |  |  |         elif line.startswith('LOCATION:'): | 
					
						
							|  |  |  |             location = line.split(':', 1)[1] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not timestamp or \ | 
					
						
							|  |  |  |        not start_time or \ | 
					
						
							|  |  |  |        not end_time or \ | 
					
						
							|  |  |  |        not description: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     if len(timestamp) < 15: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     if len(start_time) < 15: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     if len(end_time) < 15: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # check that the description is valid | 
					
						
							|  |  |  |     if is_filtered(base_dir, nickname, domain, description): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # convert to the expected time format | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |     published = _dav_date_from_string(timestamp) | 
					
						
							|  |  |  |     if not published: | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |     start_time = _dav_date_from_string(start_time) | 
					
						
							|  |  |  |     if not start_time: | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |     end_time = _dav_date_from_string(end_time) | 
					
						
							|  |  |  |     if not end_time: | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     post_id = '' | 
					
						
							|  |  |  |     post_context = get_individual_post_context() | 
					
						
							|  |  |  |     # create the status number from DTSTAMP | 
					
						
							|  |  |  |     status_number, published = get_status_number(published) | 
					
						
							|  |  |  |     # get the post id | 
					
						
							|  |  |  |     actor = http_prefix + "://" + domain + "/users/" + nickname | 
					
						
							|  |  |  |     actor2 = http_prefix + "://" + domain + "/@" + nickname | 
					
						
							|  |  |  |     post_id = actor + "/statuses/" + status_number | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     next_str = post_id + "/replies?only_other_accounts=true&page=true" | 
					
						
							|  |  |  |     content = \ | 
					
						
							|  |  |  |         '<p><span class=\"h-card\"><a href=\"' + actor2 + \ | 
					
						
							| 
									
										
										
										
											2022-05-25 13:20:49 +00:00
										 |  |  |         '\" class=\"u-url mention\" tabindex="10">@<span>' + nickname + \ | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  |         '</span></a></span>' + remove_html(description) + '</p>' | 
					
						
							|  |  |  |     event_json = { | 
					
						
							|  |  |  |         "@context": post_context, | 
					
						
							|  |  |  |         "id": post_id + "/activity", | 
					
						
							|  |  |  |         "type": "Create", | 
					
						
							|  |  |  |         "actor": actor, | 
					
						
							|  |  |  |         "published": published, | 
					
						
							|  |  |  |         "to": [actor], | 
					
						
							|  |  |  |         "cc": [], | 
					
						
							|  |  |  |         "object": { | 
					
						
							|  |  |  |             "id": post_id, | 
					
						
							|  |  |  |             "conversation": post_id, | 
					
						
							|  |  |  |             "type": "Note", | 
					
						
							|  |  |  |             "summary": None, | 
					
						
							|  |  |  |             "inReplyTo": None, | 
					
						
							|  |  |  |             "published": published, | 
					
						
							|  |  |  |             "url": actor + "/" + status_number, | 
					
						
							|  |  |  |             "attributedTo": actor, | 
					
						
							|  |  |  |             "to": [actor], | 
					
						
							|  |  |  |             "cc": [], | 
					
						
							|  |  |  |             "sensitive": False, | 
					
						
							|  |  |  |             "atomUri": post_id, | 
					
						
							|  |  |  |             "inReplyToAtomUri": None, | 
					
						
							|  |  |  |             "commentsEnabled": False, | 
					
						
							|  |  |  |             "rejectReplies": True, | 
					
						
							|  |  |  |             "mediaType": "text/html", | 
					
						
							|  |  |  |             "content": content, | 
					
						
							|  |  |  |             "contentMap": { | 
					
						
							|  |  |  |                 system_language: content | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "attachment": [], | 
					
						
							|  |  |  |             "tag": [ | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "href": actor2, | 
					
						
							|  |  |  |                     "name": "@" + nickname + "@" + domain, | 
					
						
							|  |  |  |                     "type": "Mention" | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							|  |  |  |                     "type": "Event", | 
					
						
							|  |  |  |                     "name": content, | 
					
						
							|  |  |  |                     "startTime": start_time, | 
					
						
							|  |  |  |                     "endTime": end_time | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             "replies": { | 
					
						
							|  |  |  |                 "id": post_id + "/replies", | 
					
						
							|  |  |  |                 "type": "Collection", | 
					
						
							|  |  |  |                 "first": { | 
					
						
							|  |  |  |                     "type": "CollectionPage", | 
					
						
							|  |  |  |                     "next": next_str, | 
					
						
							|  |  |  |                     "partOf": post_id + "/replies", | 
					
						
							|  |  |  |                     "items": [] | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if location: | 
					
						
							|  |  |  |         event_json['object']['tag'].append({ | 
					
						
							|  |  |  |             "@context": "https://www.w3.org/ns/activitystreams", | 
					
						
							|  |  |  |             "type": "Place", | 
					
						
							|  |  |  |             "name": location | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |     handle = nickname + '@' + domain | 
					
						
							|  |  |  |     outbox_dir = base_dir + '/accounts/' + handle + '/outbox' | 
					
						
							|  |  |  |     if not os.path.isdir(outbox_dir): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     filename = outbox_dir + '/' + post_id.replace('/', '#') + '.json' | 
					
						
							|  |  |  |     save_json(event_json, filename) | 
					
						
							|  |  |  |     save_event_post(base_dir, handle, post_id, event_json) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  | def _dav_update_recent_etags(etag: str, nickname: str, | 
					
						
							|  |  |  |                              recent_dav_etags: {}) -> None: | 
					
						
							|  |  |  |     """Updates the recent etags for each account
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     # update the recent caldav etags for each account | 
					
						
							|  |  |  |     if not recent_dav_etags.get(nickname): | 
					
						
							|  |  |  |         recent_dav_etags[nickname] = [etag] | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         # only keep a limited number of recent etags | 
					
						
							|  |  |  |         while len(recent_dav_etags[nickname]) > 32: | 
					
						
							|  |  |  |             recent_dav_etags[nickname].pop(0) | 
					
						
							|  |  |  |         # append the etag to the recent list | 
					
						
							|  |  |  |         if etag not in recent_dav_etags[nickname]: | 
					
						
							|  |  |  |             recent_dav_etags[nickname].append(etag) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  | def dav_put_response(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                      depth: int, xml_str: str, http_prefix: str, | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |                      system_language: str, | 
					
						
							|  |  |  |                      recent_dav_etags: {}) -> str: | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  |     """Returns the response to caldav PUT
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if '\n' not in xml_str: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     if 'BEGIN:VCALENDAR' not in xml_str or \ | 
					
						
							|  |  |  |        'END:VCALENDAR' not in xml_str: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     if 'BEGIN:VEVENT' not in xml_str or \ | 
					
						
							|  |  |  |        'END:VEVENT' not in xml_str: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-24 16:55:37 +00:00
										 |  |  |     etag = md5(xml_str.encode('utf-8')).hexdigest() | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |     if recent_dav_etags.get(nickname): | 
					
						
							|  |  |  |         if etag in recent_dav_etags[nickname]: | 
					
						
							|  |  |  |             return 'Not modified' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  |     stored_count = 0 | 
					
						
							|  |  |  |     reading_event = False | 
					
						
							|  |  |  |     lines_list = xml_str.split('\n') | 
					
						
							|  |  |  |     event_list = [] | 
					
						
							|  |  |  |     for line in lines_list: | 
					
						
							|  |  |  |         line = line.strip() | 
					
						
							|  |  |  |         if not reading_event: | 
					
						
							|  |  |  |             if line == 'BEGIN:VEVENT': | 
					
						
							|  |  |  |                 reading_event = True | 
					
						
							|  |  |  |                 event_list = [] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             if line == 'END:VEVENT': | 
					
						
							|  |  |  |                 if event_list: | 
					
						
							|  |  |  |                     _dav_store_event(base_dir, nickname, domain, | 
					
						
							|  |  |  |                                      event_list, http_prefix, | 
					
						
							|  |  |  |                                      system_language) | 
					
						
							|  |  |  |                     stored_count += 1 | 
					
						
							|  |  |  |                 reading_event = False | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 event_list.append(line) | 
					
						
							|  |  |  |     if stored_count == 0: | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |     _dav_update_recent_etags(etag, nickname, recent_dav_etags) | 
					
						
							|  |  |  |     return 'ETag:' + etag | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def dav_report_response(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-02-23 12:19:27 +00:00
										 |  |  |                         depth: int, xml_str: str, | 
					
						
							|  |  |  |                         person_cache: {}, http_prefix: str, | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |                         curr_etag: str, recent_dav_etags: {}, | 
					
						
							| 
									
										
										
										
											2022-04-13 15:06:03 +00:00
										 |  |  |                         domain_full: str, system_language: str) -> str: | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  |     """Returns the response to caldav REPORT
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if '<c:calendar-query' not in xml_str or \ | 
					
						
							|  |  |  |        '</c:calendar-query>' not in xml_str: | 
					
						
							|  |  |  |         if '<c:calendar-multiget' not in xml_str or \ | 
					
						
							|  |  |  |            '</c:calendar-multiget>' not in xml_str: | 
					
						
							|  |  |  |             return None | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if curr_etag: | 
					
						
							|  |  |  |         if recent_dav_etags.get(nickname): | 
					
						
							|  |  |  |             if curr_etag in recent_dav_etags[nickname]: | 
					
						
							|  |  |  |                 return "Not modified" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     xml_str_lower = xml_str.lower() | 
					
						
							|  |  |  |     query_start_time = None | 
					
						
							|  |  |  |     query_end_time = None | 
					
						
							|  |  |  |     if ':time-range' in xml_str_lower: | 
					
						
							|  |  |  |         time_range_str = xml_str_lower.split(':time-range')[1] | 
					
						
							|  |  |  |         if 'start=' in time_range_str and 'end=' in time_range_str: | 
					
						
							|  |  |  |             start_time_str = time_range_str.split('start=')[1] | 
					
						
							|  |  |  |             if start_time_str.startswith("'"): | 
					
						
							|  |  |  |                 query_start_time_str = start_time_str.split("'")[1] | 
					
						
							|  |  |  |                 query_start_time = _dav_date_from_string(query_start_time_str) | 
					
						
							|  |  |  |             elif start_time_str.startswith('"'): | 
					
						
							|  |  |  |                 query_start_time_str = start_time_str.split('"')[1] | 
					
						
							|  |  |  |                 query_start_time = _dav_date_from_string(query_start_time_str) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             end_time_str = time_range_str.split('end=')[1] | 
					
						
							|  |  |  |             if end_time_str.startswith("'"): | 
					
						
							|  |  |  |                 query_end_time_str = end_time_str.split("'")[1] | 
					
						
							|  |  |  |                 query_end_time = _dav_date_from_string(query_end_time_str) | 
					
						
							|  |  |  |             elif end_time_str.startswith('"'): | 
					
						
							|  |  |  |                 query_end_time_str = end_time_str.split('"')[1] | 
					
						
							|  |  |  |                 query_end_time = _dav_date_from_string(query_end_time_str) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |     text_match = '' | 
					
						
							|  |  |  |     if ':text-match' in xml_str_lower: | 
					
						
							|  |  |  |         match_str = xml_str_lower.split(':text-match')[1] | 
					
						
							|  |  |  |         if '>' in match_str and '<' in match_str: | 
					
						
							|  |  |  |             text_match = match_str.split('>')[1] | 
					
						
							|  |  |  |             if '<' in text_match: | 
					
						
							|  |  |  |                 text_match = text_match.split('<')[0] | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 text_match = '' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |     ical_events = None | 
					
						
							|  |  |  |     etag = None | 
					
						
							|  |  |  |     events_href = '' | 
					
						
							|  |  |  |     responses = '' | 
					
						
							|  |  |  |     search_date = datetime.now() | 
					
						
							|  |  |  |     if query_start_time and query_end_time: | 
					
						
							|  |  |  |         query_start_year = int(query_start_time.split('-')[0]) | 
					
						
							|  |  |  |         query_start_month = int(query_start_time.split('-')[1]) | 
					
						
							|  |  |  |         query_start_day = query_start_time.split('-')[2] | 
					
						
							|  |  |  |         query_start_day = int(query_start_day.split('T')[0]) | 
					
						
							|  |  |  |         query_end_year = int(query_end_time.split('-')[0]) | 
					
						
							|  |  |  |         query_end_month = int(query_end_time.split('-')[1]) | 
					
						
							|  |  |  |         query_end_day = query_end_time.split('-')[2] | 
					
						
							|  |  |  |         query_end_day = int(query_end_day.split('T')[0]) | 
					
						
							|  |  |  |         if query_start_year == query_end_year and \ | 
					
						
							|  |  |  |            query_start_month == query_end_month: | 
					
						
							|  |  |  |             if query_start_day == query_end_day: | 
					
						
							|  |  |  |                 # calendar for one day | 
					
						
							|  |  |  |                 search_date = \ | 
					
						
							| 
									
										
										
										
											2022-02-24 17:23:41 +00:00
										 |  |  |                     datetime(year=query_start_year, | 
					
						
							|  |  |  |                              month=query_start_month, | 
					
						
							|  |  |  |                              day=query_start_day) | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |                 ical_events = \ | 
					
						
							|  |  |  |                     get_todays_events_icalendar(base_dir, nickname, domain, | 
					
						
							|  |  |  |                                                 search_date.year, | 
					
						
							|  |  |  |                                                 search_date.month, | 
					
						
							|  |  |  |                                                 search_date.day, person_cache, | 
					
						
							| 
									
										
										
										
											2022-04-13 15:06:03 +00:00
										 |  |  |                                                 http_prefix, text_match, | 
					
						
							|  |  |  |                                                 system_language) | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |                 events_href = \ | 
					
						
							|  |  |  |                     http_prefix + '://' + domain_full + '/users/' + \ | 
					
						
							|  |  |  |                     nickname + '/calendar?year=' + \ | 
					
						
							|  |  |  |                     str(search_date.year) + '?month=' + \ | 
					
						
							|  |  |  |                     str(search_date.month) + '?day=' + str(search_date.day) | 
					
						
							|  |  |  |                 if ical_events: | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                     if 'VEVENT' in ical_events: | 
					
						
							| 
									
										
										
										
											2022-02-24 16:55:37 +00:00
										 |  |  |                         ical_events_encoded = ical_events.encode('utf-8') | 
					
						
							|  |  |  |                         etag = md5(ical_events_encoded).hexdigest() | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                         responses = \ | 
					
						
							|  |  |  |                             '    <d:response>\n' + \ | 
					
						
							|  |  |  |                             '        <d:href>' + events_href + \ | 
					
						
							|  |  |  |                             '</d:href>\n' + \ | 
					
						
							|  |  |  |                             '        <d:propstat>\n' + \ | 
					
						
							|  |  |  |                             '            <d:prop>\n' + \ | 
					
						
							|  |  |  |                             '                <d:getetag>"' + \ | 
					
						
							|  |  |  |                             etag + '"</d:getetag>\n' + \ | 
					
						
							|  |  |  |                             '                <c:calendar-data>' + \ | 
					
						
							|  |  |  |                             ical_events + \ | 
					
						
							|  |  |  |                             '                </c:calendar-data>\n' + \ | 
					
						
							|  |  |  |                             '            </d:prop>\n' + \ | 
					
						
							|  |  |  |                             '            <d:status>HTTP/1.1 200 OK' + \ | 
					
						
							|  |  |  |                             '</d:status>\n' + \ | 
					
						
							|  |  |  |                             '        </d:propstat>\n' + \ | 
					
						
							|  |  |  |                             '    </d:response>\n' | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |             elif query_start_day == 1 and query_start_day >= 28: | 
					
						
							|  |  |  |                 # calendar for a month | 
					
						
							|  |  |  |                 ical_events = \ | 
					
						
							|  |  |  |                     get_month_events_icalendar(base_dir, nickname, domain, | 
					
						
							|  |  |  |                                                query_start_year, | 
					
						
							|  |  |  |                                                query_start_month, | 
					
						
							|  |  |  |                                                person_cache, | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                                                http_prefix, | 
					
						
							|  |  |  |                                                text_match) | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |                 events_href = \ | 
					
						
							|  |  |  |                     http_prefix + '://' + domain_full + '/users/' + \ | 
					
						
							|  |  |  |                     nickname + '/calendar?year=' + \ | 
					
						
							|  |  |  |                     str(query_start_year) + '?month=' + \ | 
					
						
							|  |  |  |                     str(query_start_month) | 
					
						
							|  |  |  |                 if ical_events: | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                     if 'VEVENT' in ical_events: | 
					
						
							| 
									
										
										
										
											2022-02-24 16:55:37 +00:00
										 |  |  |                         ical_events_encoded = ical_events.encode('utf-8') | 
					
						
							|  |  |  |                         etag = md5(ical_events_encoded).hexdigest() | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                         responses = \ | 
					
						
							|  |  |  |                             '    <d:response>\n' + \ | 
					
						
							|  |  |  |                             '        <d:href>' + events_href + \ | 
					
						
							|  |  |  |                             '</d:href>\n' + \ | 
					
						
							|  |  |  |                             '        <d:propstat>\n' + \ | 
					
						
							|  |  |  |                             '            <d:prop>\n' + \ | 
					
						
							|  |  |  |                             '                <d:getetag>"' + \ | 
					
						
							|  |  |  |                             etag + '"</d:getetag>\n' + \ | 
					
						
							|  |  |  |                             '                <c:calendar-data>' + \ | 
					
						
							|  |  |  |                             ical_events + \ | 
					
						
							|  |  |  |                             '                </c:calendar-data>\n' + \ | 
					
						
							|  |  |  |                             '            </d:prop>\n' + \ | 
					
						
							|  |  |  |                             '            <d:status>HTTP/1.1 200 OK' + \ | 
					
						
							|  |  |  |                             '</d:status>\n' + \ | 
					
						
							|  |  |  |                             '        </d:propstat>\n' + \ | 
					
						
							|  |  |  |                             '    </d:response>\n' | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |         if not responses: | 
					
						
							|  |  |  |             all_events = '' | 
					
						
							|  |  |  |             for year in range(query_start_year, query_end_year+1): | 
					
						
							|  |  |  |                 if query_start_year == query_end_year: | 
					
						
							|  |  |  |                     start_month_number = query_start_month | 
					
						
							|  |  |  |                     end_month_number = query_end_month | 
					
						
							|  |  |  |                 elif year == query_end_year: | 
					
						
							|  |  |  |                     start_month_number = 1 | 
					
						
							|  |  |  |                     end_month_number = query_end_month | 
					
						
							|  |  |  |                 elif year == query_start_year: | 
					
						
							|  |  |  |                     start_month_number = query_start_month | 
					
						
							|  |  |  |                     end_month_number = 12 | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     start_month_number = 1 | 
					
						
							|  |  |  |                     end_month_number = 12 | 
					
						
							|  |  |  |                 for month in range(start_month_number, end_month_number+1): | 
					
						
							|  |  |  |                     ical_events = \ | 
					
						
							|  |  |  |                         get_month_events_icalendar(base_dir, | 
					
						
							|  |  |  |                                                    nickname, domain, | 
					
						
							|  |  |  |                                                    year, month, | 
					
						
							|  |  |  |                                                    person_cache, | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                                                    http_prefix, | 
					
						
							|  |  |  |                                                    text_match) | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |                     events_href = \ | 
					
						
							|  |  |  |                         http_prefix + '://' + domain_full + '/users/' + \ | 
					
						
							|  |  |  |                         nickname + '/calendar?year=' + \ | 
					
						
							|  |  |  |                         str(year) + '?month=' + \ | 
					
						
							|  |  |  |                         str(month) | 
					
						
							|  |  |  |                     if ical_events: | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                         if 'VEVENT' in ical_events: | 
					
						
							|  |  |  |                             all_events += ical_events | 
					
						
							| 
									
										
										
										
											2022-02-24 16:55:37 +00:00
										 |  |  |                             ical_events_encoded = ical_events.encode('utf-8') | 
					
						
							|  |  |  |                             local_etag = md5(ical_events_encoded).hexdigest() | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                             responses += \ | 
					
						
							|  |  |  |                                 '    <d:response>\n' + \ | 
					
						
							|  |  |  |                                 '        <d:href>' + events_href + \ | 
					
						
							|  |  |  |                                 '</d:href>\n' + \ | 
					
						
							|  |  |  |                                 '        <d:propstat>\n' + \ | 
					
						
							|  |  |  |                                 '            <d:prop>\n' + \ | 
					
						
							|  |  |  |                                 '                <d:getetag>"' + \ | 
					
						
							| 
									
										
										
										
											2022-02-24 16:55:37 +00:00
										 |  |  |                                 local_etag + '"</d:getetag>\n' + \ | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                                 '                <c:calendar-data>' + \ | 
					
						
							|  |  |  |                                 ical_events + \ | 
					
						
							|  |  |  |                                 '                </c:calendar-data>\n' + \ | 
					
						
							|  |  |  |                                 '            </d:prop>\n' + \ | 
					
						
							|  |  |  |                                 '            <d:status>HTTP/1.1 200 OK' + \ | 
					
						
							|  |  |  |                                 '</d:status>\n' + \ | 
					
						
							|  |  |  |                                 '        </d:propstat>\n' + \ | 
					
						
							|  |  |  |                                 '    </d:response>\n' | 
					
						
							| 
									
										
										
										
											2022-02-24 16:55:37 +00:00
										 |  |  |             ical_events_encoded = all_events.encode('utf-8') | 
					
						
							|  |  |  |             etag = md5(ical_events_encoded).hexdigest() | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 12:19:27 +00:00
										 |  |  |     # today's calendar events | 
					
						
							|  |  |  |     if not ical_events: | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |         ical_events = \ | 
					
						
							|  |  |  |             get_todays_events_icalendar(base_dir, nickname, domain, | 
					
						
							|  |  |  |                                         search_date.year, search_date.month, | 
					
						
							|  |  |  |                                         search_date.day, person_cache, | 
					
						
							| 
									
										
										
										
											2022-04-13 15:06:03 +00:00
										 |  |  |                                         http_prefix, text_match, | 
					
						
							|  |  |  |                                         system_language) | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |         events_href = \ | 
					
						
							|  |  |  |             http_prefix + '://' + domain_full + '/users/' + \ | 
					
						
							|  |  |  |             nickname + '/calendar?year=' + \ | 
					
						
							|  |  |  |             str(search_date.year) + '?month=' + \ | 
					
						
							|  |  |  |             str(search_date.month) + '?day=' + str(search_date.day) | 
					
						
							|  |  |  |         if ical_events: | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |             if 'VEVENT' in ical_events: | 
					
						
							| 
									
										
										
										
											2022-02-24 16:55:37 +00:00
										 |  |  |                 ical_events_encoded = ical_events.encode('utf-8') | 
					
						
							|  |  |  |                 etag = md5(ical_events_encoded).hexdigest() | 
					
						
							| 
									
										
										
										
											2022-02-23 18:46:20 +00:00
										 |  |  |                 responses = \ | 
					
						
							|  |  |  |                     '    <d:response>\n' + \ | 
					
						
							|  |  |  |                     '        <d:href>' + events_href + '</d:href>\n' + \ | 
					
						
							|  |  |  |                     '        <d:propstat>\n' + \ | 
					
						
							|  |  |  |                     '            <d:prop>\n' + \ | 
					
						
							|  |  |  |                     '                <d:getetag>"' + etag + \ | 
					
						
							|  |  |  |                     '"</d:getetag>\n' + \ | 
					
						
							|  |  |  |                     '                <c:calendar-data>' + ical_events + \ | 
					
						
							|  |  |  |                     '                </c:calendar-data>\n' + \ | 
					
						
							|  |  |  |                     '            </d:prop>\n' + \ | 
					
						
							|  |  |  |                     '            <d:status>HTTP/1.1 200 OK</d:status>\n' + \ | 
					
						
							|  |  |  |                     '        </d:propstat>\n' + \ | 
					
						
							|  |  |  |                     '    </d:response>\n' | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not ical_events or not etag: | 
					
						
							| 
									
										
										
										
											2022-02-23 12:19:27 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  |     if 'VEVENT' not in ical_events: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if etag == curr_etag: | 
					
						
							|  |  |  |         return "Not modified" | 
					
						
							|  |  |  |     response_str = \ | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |         '<?xml version="1.0" encoding="utf-8" ?>\n' + \ | 
					
						
							| 
									
										
										
										
											2022-02-23 12:19:27 +00:00
										 |  |  |         '<d:multistatus xmlns:d="DAV:" ' + \ | 
					
						
							|  |  |  |         'xmlns:cs="http://calendarserver.org/ns/">\n' + \ | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |         responses + '</d:multistatus>' | 
					
						
							| 
									
										
										
										
											2022-02-23 12:19:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 18:04:34 +00:00
										 |  |  |     _dav_update_recent_etags(etag, nickname, recent_dav_etags) | 
					
						
							| 
									
										
										
										
											2022-02-23 12:19:27 +00:00
										 |  |  |     return response_str | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def dav_delete_response(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                         depth: int, path: str, | 
					
						
							|  |  |  |                         http_prefix: str, debug: bool, | 
					
						
							|  |  |  |                         recent_posts_cache: {}) -> str: | 
					
						
							|  |  |  |     """Returns the response to caldav DELETE
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     token = path.split('/calendars/' + nickname + '/')[1] | 
					
						
							|  |  |  |     token_year, token_month_number, token_post_id = \ | 
					
						
							|  |  |  |         _dav_decode_token(token) | 
					
						
							|  |  |  |     if not token_year: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     post_filename = locate_post(base_dir, nickname, domain, token_post_id) | 
					
						
							|  |  |  |     if not post_filename: | 
					
						
							|  |  |  |         print('Calendar post not found ' + token_post_id) | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     post_json_object = load_json(post_filename) | 
					
						
							|  |  |  |     if not _is_happening_post(post_json_object): | 
					
						
							|  |  |  |         print(token_post_id + ' is not a calendar post') | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     remove_calendar_event(base_dir, nickname, domain, | 
					
						
							|  |  |  |                           token_year, token_month_number, | 
					
						
							|  |  |  |                           token_post_id) | 
					
						
							|  |  |  |     delete_post(base_dir, http_prefix, | 
					
						
							|  |  |  |                 nickname, domain, post_filename, | 
					
						
							| 
									
										
										
										
											2022-05-01 17:14:29 +00:00
										 |  |  |                 debug, recent_posts_cache, True) | 
					
						
							| 
									
										
										
										
											2022-02-23 09:51:00 +00:00
										 |  |  |     return 'Ok' | 
					
						
							| 
									
										
										
										
											2022-02-24 10:18:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def dav_month_via_server(session, http_prefix: str, | 
					
						
							|  |  |  |                          nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |                          debug: bool, | 
					
						
							|  |  |  |                          year: int, month: int, | 
					
						
							|  |  |  |                          password: str) -> str: | 
					
						
							|  |  |  |     """Gets the icalendar for a month via caldav
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     auth_header = create_basic_auth_header(nickname, password) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							|  |  |  |         'host': domain, | 
					
						
							|  |  |  |         'Content-type': 'application/xml', | 
					
						
							|  |  |  |         'Authorization': auth_header | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     domain_full = get_full_domain(domain, port) | 
					
						
							|  |  |  |     params = {} | 
					
						
							|  |  |  |     url = http_prefix + '://' + domain_full + '/calendars/' + nickname | 
					
						
							|  |  |  |     month_str = str(month) | 
					
						
							|  |  |  |     if month < 10: | 
					
						
							|  |  |  |         month_str = '0' + month_str | 
					
						
							|  |  |  |     xml_str = \ | 
					
						
							|  |  |  |         '<?xml version="1.0" encoding="utf-8" ?>\n' + \ | 
					
						
							|  |  |  |         '<c:calendar-query xmlns:d="DAV:"\n' + \ | 
					
						
							|  |  |  |         '                  xmlns:c="urn:ietf:params:xml:ns:caldav">\n' + \ | 
					
						
							|  |  |  |         '  <d:prop>\n' + \ | 
					
						
							|  |  |  |         '    <d:getetag/>\n' + \ | 
					
						
							|  |  |  |         '  </d:prop>\n' + \ | 
					
						
							|  |  |  |         '  <c:filter>\n' + \ | 
					
						
							|  |  |  |         '    <c:comp-filter name="VCALENDAR">\n' + \ | 
					
						
							|  |  |  |         '      <c:comp-filter name="VEVENT">\n' + \ | 
					
						
							|  |  |  |         '      <c:time-range start="' + str(year) + month_str + \ | 
					
						
							|  |  |  |         '01T000000Z"\n' + \ | 
					
						
							|  |  |  |         '                    end="' + str(year) + month_str + \ | 
					
						
							| 
									
										
										
										
											2022-02-24 17:23:41 +00:00
										 |  |  |         '31T235959Z"/>\n' + \ | 
					
						
							|  |  |  |         '      </c:comp-filter>\n' + \ | 
					
						
							|  |  |  |         '    </c:comp-filter>\n' + \ | 
					
						
							|  |  |  |         '  </c:filter>\n' + \ | 
					
						
							|  |  |  |         '</c:calendar-query>' | 
					
						
							|  |  |  |     result = \ | 
					
						
							| 
									
										
										
										
											2022-05-26 21:58:22 +00:00
										 |  |  |         get_method("REPORT", xml_str, session, url, params, headers, debug, | 
					
						
							|  |  |  |                    __version__, http_prefix, domain) | 
					
						
							| 
									
										
										
										
											2022-02-24 17:23:41 +00:00
										 |  |  |     return result | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def dav_day_via_server(session, http_prefix: str, | 
					
						
							|  |  |  |                        nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |                        debug: bool, | 
					
						
							|  |  |  |                        year: int, month: int, day: int, | 
					
						
							|  |  |  |                        password: str) -> str: | 
					
						
							|  |  |  |     """Gets the icalendar for a day via caldav
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     auth_header = create_basic_auth_header(nickname, password) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							|  |  |  |         'host': domain, | 
					
						
							|  |  |  |         'Content-type': 'application/xml', | 
					
						
							|  |  |  |         'Authorization': auth_header | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     domain_full = get_full_domain(domain, port) | 
					
						
							|  |  |  |     params = {} | 
					
						
							|  |  |  |     url = http_prefix + '://' + domain_full + '/calendars/' + nickname | 
					
						
							|  |  |  |     month_str = str(month) | 
					
						
							|  |  |  |     if month < 10: | 
					
						
							|  |  |  |         month_str = '0' + month_str | 
					
						
							|  |  |  |     day_str = str(day) | 
					
						
							|  |  |  |     if day < 10: | 
					
						
							|  |  |  |         day_str = '0' + day_str | 
					
						
							|  |  |  |     xml_str = \ | 
					
						
							|  |  |  |         '<?xml version="1.0" encoding="utf-8" ?>\n' + \ | 
					
						
							|  |  |  |         '<c:calendar-query xmlns:d="DAV:"\n' + \ | 
					
						
							|  |  |  |         '                  xmlns:c="urn:ietf:params:xml:ns:caldav">\n' + \ | 
					
						
							|  |  |  |         '  <d:prop>\n' + \ | 
					
						
							|  |  |  |         '    <d:getetag/>\n' + \ | 
					
						
							|  |  |  |         '  </d:prop>\n' + \ | 
					
						
							|  |  |  |         '  <c:filter>\n' + \ | 
					
						
							|  |  |  |         '    <c:comp-filter name="VCALENDAR">\n' + \ | 
					
						
							|  |  |  |         '      <c:comp-filter name="VEVENT">\n' + \ | 
					
						
							|  |  |  |         '      <c:time-range start="' + str(year) + month_str + \ | 
					
						
							|  |  |  |         day_str + 'T000000Z"\n' + \ | 
					
						
							|  |  |  |         '                    end="' + str(year) + month_str + \ | 
					
						
							|  |  |  |         day_str + 'T235959Z"/>\n' + \ | 
					
						
							| 
									
										
										
										
											2022-02-24 10:18:54 +00:00
										 |  |  |         '      </c:comp-filter>\n' + \ | 
					
						
							|  |  |  |         '    </c:comp-filter>\n' + \ | 
					
						
							|  |  |  |         '  </c:filter>\n' + \ | 
					
						
							|  |  |  |         '</c:calendar-query>' | 
					
						
							| 
									
										
										
										
											2022-02-24 11:10:14 +00:00
										 |  |  |     result = \ | 
					
						
							| 
									
										
										
										
											2022-05-26 21:58:22 +00:00
										 |  |  |         get_method("REPORT", xml_str, session, url, params, headers, debug, | 
					
						
							|  |  |  |                    __version__, http_prefix, domain) | 
					
						
							| 
									
										
										
										
											2022-02-24 10:18:54 +00:00
										 |  |  |     return result |