Refactor event data serialization for JSON

This commit is contained in:
Roger Gonzalez 2024-11-24 22:54:34 -03:00
parent 1cd3b37835
commit 5511bb1dd0
Signed by: rogs
GPG Key ID: C7ECE9C6C36EC2E6
2 changed files with 64 additions and 42 deletions

View File

@ -50,7 +50,14 @@ def get_calendar(principal: Principal, calendar_name: str) -> CalDAVCalendar:
def _process_exdate(exdate: Any) -> list: def _process_exdate(exdate: Any) -> list:
"""Process EXDATE field which can be either a single date or a list of dates.""" """Process EXDATE field which can be either a single date or a list of dates.
Args:
exdate: EXDATE field from an iCalendar event.
Returns:
list: List of dates in ISO format or None if no EXDATE field is present.
"""
if not exdate: if not exdate:
return None return None

View File

@ -3,6 +3,7 @@
import json import json
import os import os
import time import time
from datetime import datetime
from typing import Any, Dict, List, Tuple from typing import Any, Dict, List, Tuple
from googleapiclient.discovery import Resource from googleapiclient.discovery import Resource
@ -13,6 +14,30 @@ EventsDict = Dict[str, EventDict]
error_events = [] error_events = []
def _sanitize_event_for_json(event_data: Dict[str, Any]) -> Dict[str, Any]:
"""Sanitize event data to ensure it's JSON serializable.
Args:
event_data: Dictionary containing event details.
Returns:
Dict[str, Any]: Sanitized dictionary.
Raises:
TypeError: If the event data is not JSON serializable.
"""
sanitized = event_data.copy()
if "rrule" in sanitized and sanitized["rrule"]:
rrule = sanitized["rrule"].copy()
for key, value in rrule.items():
if isinstance(value, list):
rrule[key] = [item.isoformat() if isinstance(item, datetime) else item for item in value]
sanitized["rrule"] = rrule
return sanitized
def load_local_sync(file_path: str) -> EventsDict: def load_local_sync(file_path: str) -> EventsDict:
"""Load the locally synced events from a JSON file. """Load the locally synced events from a JSON file.
@ -35,8 +60,29 @@ def save_local_sync(file_path: str, events: EventsDict) -> None:
file_path: Path to the JSON file. file_path: Path to the JSON file.
events: Dictionary of events to save. events: Dictionary of events to save.
""" """
sanitized_events = {}
for event_id, event_data in events.items():
try:
sanitized_events[event_id] = _sanitize_event_for_json(event_data)
except Exception as e:
print(f"Warning: Could not sanitize event {event_id}: {e}")
continue
try:
with open(file_path, "w") as file: with open(file_path, "w") as file:
json.dump(events, file, indent=4) json.dump(sanitized_events, file, indent=4)
except TypeError as e:
print(f"Error saving events: {e}")
for event_id, event_data in sanitized_events.items():
try:
json.dumps(event_data)
except TypeError as e:
print(f"Problem found in event {event_id}: {e}")
for key, value in event_data.items():
try:
json.dumps({key: value})
except TypeError as e:
print(f" Problem field: {key} = {value} (type: {type(value)})")
def compare_events( def compare_events(
@ -92,6 +138,7 @@ def add_event_to_google(service: Resource, event: EventDict, calendar_id: str) -
rrule_parts = [] rrule_parts = []
for key, value in event["rrule"].items(): for key, value in event["rrule"].items():
if isinstance(value, list): if isinstance(value, list):
value = [item.isoformat() if isinstance(item, datetime) else item for item in value]
value = ",".join(str(v) for v in value) value = ",".join(str(v) for v in value)
rrule_parts.append(f"{key}={value}") rrule_parts.append(f"{key}={value}")
google_event["recurrence"] = [f"RRULE:{';'.join(rrule_parts)}"] google_event["recurrence"] = [f"RRULE:{';'.join(rrule_parts)}"]
@ -100,38 +147,6 @@ def add_event_to_google(service: Resource, event: EventDict, calendar_id: str) -
exdates = [f"EXDATE;TZID=UTC:{date}" for date in event["exdate"]] exdates = [f"EXDATE;TZID=UTC:{date}" for date in event["exdate"]]
google_event["recurrence"].extend(exdates) google_event["recurrence"].extend(exdates)
if event.get("recurrence_id"):
original_id = event["uid"].rsplit("-", 1)[0]
instance_id = event["recurrence_id"]
original_events = (
service.events()
.list(
calendarId=calendar_id,
iCalUID=original_id,
)
.execute()
.get("items", [])
)
if original_events:
original_event_id = original_events[0]["id"]
google_event["originalStartTime"] = {
"dateTime": instance_id,
"timeZone": "UTC",
}
created_event = (
service.events()
.update(
calendarId=calendar_id,
eventId=original_event_id,
body=google_event,
)
.execute()
)
else:
raise ValueError(f"Original recurring event not found for exception: {event['uid']}")
else:
created_event = ( created_event = (
service.events() service.events()
.insert( .insert(