Source code for mergecal.calendar_merger

from typing import Optional

from icalendar import Calendar, Event
from x_wr_timezone import to_standard


def generate_default_prodid() -> str:
    """Generate a default PRODID."""
    return "-//mergecal.org//MergeCal//EN"


[docs] class CalendarMerger: """Merge multiple calendars into one.""" def __init__( self, calendars: list[Calendar], prodid: Optional[str] = None, version: str = "2.0", method: Optional[str] = None, ): self.merged_calendar = Calendar() # Set required properties self.merged_calendar.add("prodid", prodid or generate_default_prodid()) self.merged_calendar.add("version", version) # Set optional properties if provided if method: self.merged_calendar.add("method", method) self.calendars: list[Calendar] = [] for calendar in calendars: self.add_calendar(calendar)
[docs] def add_calendar(self, calendar: Calendar) -> None: """Add a calendar to be merged.""" self.calendars.append(to_standard(calendar, add_timezone_component=True))
[docs] def merge(self) -> Calendar: """Merge the calendars.""" existing_uids: set[tuple[Optional[str], int, Optional[str]]] = set() no_uid_events: list[Event] = [] tzids: set[str] = set() for cal in self.calendars: for timezone in cal.timezones: if timezone.tz_name not in tzids: self.merged_calendar.add_component(timezone) tzids.add(timezone.tz_name) for event in cal.events: uid = event.get("uid", None) sequence = event.get("sequence", 0) recurrence_id = event.get("recurrence-id", None) # Create a unique identifier for the component component_id = (uid, sequence, recurrence_id) if uid is None: if event in no_uid_events: continue no_uid_events.append(event) elif component_id in existing_uids: continue existing_uids.add(component_id) self.merged_calendar.add_component(event) return self.merged_calendar
[docs] def merge_calendars(calendars: list[Calendar], **kwargs: object) -> Calendar: """Convenience function to merge calendars.""" merger = CalendarMerger(calendars, **kwargs) # type: ignore return merger.merge()
__all__ = ["CalendarMerger", "merge_calendars"]