""" Android Provider CalendarContract 扩展组件 方法签名完全对齐 Android SDK """ from __future__ import annotations import os import json import time import datetime import threading from typing import Any, Dict, List, Optional, Set, Tuple, Union from .._core import Stub, AndroidOnlyError from ..java.lang import RuntimeException # ═══════════════════════════════════════════════════════════════ # CalendarContract 常量 # ═══════════════════════════════════════════════════════════════ # Calendars CALENDAR_DISPLAY_NAME = "calendar_displayName" CALENDAR_ACCOUNT_NAME = "account_name" CALENDAR_ACCOUNT_TYPE = "account_type" CALENDAR_OWNER_ACCOUNT = "calendar_ownerAccount" CALENDAR_COLOR = "calendar_color" CALENDAR_COLOR_KEY = "calendar_color_key" CALENDAR_ACCESS_LEVEL = "calendar_access_level" CALENDAR_VISIBLE = "calendar_visible" CALENDAR_SYNC_EVENTS = "calendar_sync_events" CALENDAR_TIMEZONE = "calendar_timezone" CALENDAR_ALLOWED_REMINDERS = "calendar_allowedReminders" CALENDAR_ALLOWED_AVAILABILITY = "calendar_allowedAvailability" CALENDAR_ALLOWED_ATTENDEE_TYPES = "calendar_allowedAttendeeTypes" CALENDAR_IS_PRIMARY = "calendar_isPrimary" CALENDAR_MAX_REMINDERS = "calendar_maxReminders" CALENDAR_DTSTART = "calendar_dtstart" CALENDAR_CAN_ORGANIZER_RESPOND = "calendar_canOrganizerRespond" CALENDAR_CAN_MODIFY_TIME_ZONE = "calendar_canModifyTimeZone" CALENDAR_ALLOWED_REMINDERS = CALENDAR_ALLOWED_REMINDERS CALENDAR_AVAILABLE_COLORS = "calendar_availableColors" CALENDAR_COLORS_RAW = "calendar_colorsRaw" # Events EVENT_ID = "_id" EVENT_TITLE = "title" EVENT_DESCRIPTION = "description" EVENT_LOCATION = "eventLocation" EVENT_DTSTART = "dtstart" EVENT_DTEND = "dtend" EVENT_DURATION = "duration" EVENT_TIMEZONE = "eventTimezone" EVENT_ALL_DAY = "allDay" EVENT_CALENDAR_ID = "calendar_id" EVENT_ORGANIZER = "organizer" EVENT_STATUS = "eventStatus" EVENT_AVAILABILITY = "availability" EVENT_ACCESS_LEVEL = "accessLevel" EVENT_RRULE = "rrule" EVENT_RDATE = "rdate" EVENT_EXRULE = "exrule" EVENT_EXDATE = "exdate" EVENT_ORIGINAL_ID = "original_id" EVENT_ORIGINAL_SYNC_ID = "original_sync_id" EVENT_ORIGINAL_INSTANCE_TIME = "originalInstanceTime" EVENT_ORIGINAL_ALL_DAY = "originalAllDay" EVENT_LAST_DATE = "lastDate" EVENT_HAS_ALARM = "hasAlarm" EVENT_HAS_EXTENDED_PROPERTIES = "hasExtendedProperties" EVENT_EVENT_COLOR = "eventColor" EVENT_EVENT_COLOR_KEY = "eventColor_key" EVENT_CUSTOM_APP_PACKAGE = "customAppPackage" EVENT_CUSTOM_APP_URI = "customAppUri" EVENT_ORGANIZER_CAN_RESPOND = "organizerCanRespond" EVENT_SELF_ATTENDEE_STATUS = "selfAttendeeStatus" EVENT_UID_2445 = "uid2445" EVENT_IS_ORGANIZER = "isOrganizer" EVENT_CAN_INVITE_OTHERS = "canInviteOthers" EVENT_ALLOWED_REMINDERS = "allowedReminders" # Attendees ATTENDEE_ID = "_id" ATTENDEE_EVENT_ID = "event_id" ATTENDEE_NAME = "attendeeName" ATTENDEE_EMAIL = "attendeeEmail" ATTENDEE_RELATIONSHIP = "attendeeRelationship" ATTENDEE_TYPE = "attendeeType" ATTENDEE_STATUS = "attendeeStatus" ATTENDEE_IDENTITY = "attendeeIdentity" ATTENDEE_ID_NAMESPACE = "attendeeIdNamespace" # Reminders REMINDER_ID = "_id" REMINDER_EVENT_ID = "event_id" REMINDER_MINUTES = "minutes" REMINDER_METHOD = "method" # Instances INSTANCE_ID = "_id" INSTANCE_EVENT_ID = "event_id" INSTANCE_BEGIN = "begin" INSTANCE_END = "end" INSTANCE_TITLE = "title" INSTANCE_DESCRIPTION = "description" INSTANCE_EVENT_LOCATION = "eventLocation" INSTANCE_ALL_DAY = "allDay" INSTANCE_CALENDAR_ID = "calendar_id" INSTANCE_RRULE = "rrule" INSTANCE_ORIGINAL_ID = "original_id" INSTANCE_ORIGINAL_INSTANCE_TIME = "originalInstanceTime" INSTANCE_ORIGINAL_SYNC_ID = "original_sync_id" INSTANCE_EVENT_TIMEZONE = "eventTimezone" INSTANCE_DTSTART = "dtstart" INSTANCE_DTEND = "dtend" INSTANCE_DURATION = "duration" INSTANCE_STATUS = "eventStatus" INSTANCE_AVAILABILITY = "availability" INSTANCE_ACCESS_LEVEL = "accessLevel" INSTANCE_HAS_ALARM = "hasAlarm" INSTANCE_HAS_EXTENDED_PROPERTIES = "hasExtendedProperties" INSTANCE_EVENT_COLOR = "eventColor" INSTANCE_SELF_ATTENDEE_STATUS = "selfAttendeeStatus" INSTANCE_START_DAY = "startDay" INSTANCE_END_DAY = "endDay" INSTANCE_START_MINUTE = "startMinute" INSTANCE_END_MINUTE = "endMinute" # Colors COLOR_ID = "_id" COLOR_KEY = "color_key" COLOR = "color" COLOR_TYPE = "color_type" # Calendar Alerts CALENDAR_ALERT_ID = "_id" CALENDAR_ALERT_EVENT_ID = "event_id" CALENDAR_ALERT_BEGIN = "begin" CALENDAR_ALERT_END = "end" CALENDAR_ALERT_ALARM_TIME = "alarmTime" CALENDAR_ALERT_CREATION_TIME = "creationTime" CALENDAR_ALERT_RECEIVED_TIME = "receivedTime" CALENDAR_ALERT_NOTIFY_TIME = "notifyTime" CALENDAR_ALERT_STATE = "state" CALENDAR_ALERT_MINUTES = "minutes" CALENDAR_ALERT_ACKNOWLEDGED = "acknowledged" CALENDAR_ALERT_DISMISSED = "dismissed" CALENDAR_ALERT_TYPE = "type" CALENDAR_ALERT_ORIGIN = "origin" # Calendar Cache CALENDAR_CACHE_KEY = "key" CALENDAR_CACHE_VALUE = "value" # Event status EVENT_STATUS_TENTATIVE = 0 EVENT_STATUS_CONFIRMED = 1 EVENT_STATUS_CANCELED = 2 # Availability AVAILABILITY_BUSY = 0 AVAILABILITY_FREE = 1 AVAILABILITY_TENTATIVE = 2 # Access level ACCESS_DEFAULT = 0 ACCESS_CONFIDENTIAL = 1 ACCESS_PRIVATE = 2 ACCESS_PUBLIC = 3 ACCESS_RESTRICTED = 4 # Attendee relationship ATTENDEE_RELATIONSHIP_NONE = 0 ATTENDEE_RELATIONSHIP_ORGANIZER = 1 ATTENDEE_RELATIONSHIP_ATTENDEE = 2 ATTENDEE_RELATIONSHIP_PERFORMER = 3 ATTENDEE_RELATIONSHIP_SPEAKER = 4 # Attendee type ATTENDEE_TYPE_NONE = 0 ATTENDEE_TYPE_REQUIRED = 1 ATTENDEE_TYPE_OPTIONAL = 2 # Attendee status ATTENDEE_STATUS_NONE = 0 ATTENDEE_STATUS_ACCEPTED = 1 ATTENDEE_STATUS_DECLINED = 2 ATTENDEE_STATUS_INVITED = 3 ATTENDEE_STATUS_TENTATIVE = 4 # Reminder method REMINDER_METHOD_DEFAULT = 0 REMINDER_METHOD_ALERT = 1 REMINDER_METHOD_EMAIL = 2 REMINDER_METHOD_SMS = 3 REMINDER_METHOD_ALARM = 4 # Color type COLOR_TYPE_CALENDAR = 0 COLOR_TYPE_EVENT = 1 # Calendar alert state CALENDAR_ALERT_STATE_SCHEDULED = 0 CALENDAR_ALERT_STATE_FIRED = 1 CALENDAR_ALERT_STATE_DISMISSED = 2 # Calendar alert type CALENDAR_ALERT_TYPE_ALARM = 0 CALENDAR_ALERT_TYPE_REMINDER = 1 # Calendar alert origin CALENDAR_ALERT_ORIGIN_SELF = 0 CALENDAR_ALERT_ORIGIN_SYNC = 1 # Calendar visibility CALENDAR_VISIBLE_TRUE = 1 CALENDAR_VISIBLE_FALSE = 0 # Calendar sync CALENDAR_SYNC_EVENTS_TRUE = 1 CALENDAR_SYNC_EVENTS_FALSE = 0 # Calendar primary CALENDAR_IS_PRIMARY_TRUE = 1 CALENDAR_IS_PRIMARY_FALSE = 0 # Calendar can modify time zone CALENDAR_CAN_MODIFY_TIME_ZONE_TRUE = 1 CALENDAR_CAN_MODIFY_TIME_ZONE_FALSE = 0 # Calendar can organizer respond CALENDAR_CAN_ORGANIZER_RESPOND_TRUE = 1 CALENDAR_CAN_ORGANIZER_RESPOND_FALSE = 0 # Sync columns CALENDAR_SYNC_ACCOUNT_NAME = "account_name" CALENDAR_SYNC_ACCOUNT_TYPE = "account_type" CALENDAR_SYNC_SOURCE_ID = "sync_id" CALENDAR_SYNC_VERSION = "sync_version" CALENDAR_SYNC_DIRTY = "sync_dirty" CALENDAR_SYNC_MARK = "sync_mark" CALENDAR_SYNC1 = "sync1" CALENDAR_SYNC2 = "sync2" CALENDAR_SYNC3 = "sync3" CALENDAR_SYNC4 = "sync4" CALENDAR_SYNC5 = "sync5" CALENDAR_SYNC6 = "sync6" CALENDAR_SYNC7 = "sync7" CALENDAR_SYNC8 = "sync8" CALENDAR_SYNC9 = "sync9" CALENDAR_SYNC10 = "sync10" # Calendar keys for CalendarCache CALENDAR_CACHE_KEY_TIMEZONE_TYPE = "timezoneType" CALENDAR_CACHE_KEY_TIMEZONE_INSTANCES = "timezoneInstances" CALENDAR_CACHE_KEY_TIMEZONE_INSTANCES_PREVIOUS = "timezoneInstancesPrevious" CALENDAR_CACHE_KEY_TIMEZONE_INSTANCES_NEXT = "timezoneInstancesNext" # Calendar notification CALENDAR_NOTIFICATION_ID = "_id" CALENDAR_NOTIFICATION_EVENT_ID = "event_id" CALENDAR_NOTIFICATION_ALARM_TIME = "alarmTime" CALENDAR_NOTIFICATION_BEGIN = "begin" CALENDAR_NOTIFICATION_END = "end" CALENDAR_NOTIFICATION_TITLE = "title" CALENDAR_NOTIFICATION_DESCRIPTION = "description" CALENDAR_NOTIFICATION_LOCATION = "location" CALENDAR_NOTIFICATION_STATE = "state" CALENDAR_NOTIFICATION_MINUTES = "minutes" CALENDAR_NOTIFICATION_VISIBILITY = "visibility" CALENDAR_NOTIFICATION_PRIORITY = "priority" CALENDAR_NOTIFICATION_GROUP_KEY = "groupKey" CALENDAR_NOTIFICATION_SORT_KEY = "sortKey" # URI constants CALENDAR_URI_CALENDARS = "content://com.android.calendar/calendars" CALENDAR_URI_EVENTS = "content://com.android.calendar/events" CALENDAR_URI_ATTENDEES = "content://com.android.calendar/attendees" CALENDAR_URI_REMINDERS = "content://com.android.calendar/reminders" CALENDAR_URI_INSTANCES = "content://com.android.calendar/instances/when" CALENDAR_URI_INSTANCES_GROUP_BY_DAY = "content://com.android.calendar/instances/groupbyday" CALENDAR_URI_COLORS = "content://com.android.calendar/colors" CALENDAR_URI_CALENDAR_ALERTS = "content://com.android.calendar/calendar_alerts" CALENDAR_URI_CALENDAR_CACHE = "content://com.android.calendar/calendar_cache" CALENDAR_URI_SYNC_STATE = "content://com.android.calendar/syncstate" CALENDAR_URI_CALENDAR_ENTITY = "content://com.android.calendar/calendar_entity" CALENDAR_URI_EVENT_ENTITY = "content://com.android.calendar/event_entity" # ═══════════════════════════════════════════════════════════════ # CalendarContract 命名空间容器 # ═══════════════════════════════════════════════════════════════ class CalendarContractBase(Stub): """CalendarContract — 日历合约基类""" pass class SyncColumns(Stub): """CalendarContract.SyncColumns — 同步列""" ACCOUNT_NAME = CALENDAR_SYNC_ACCOUNT_NAME ACCOUNT_TYPE = CALENDAR_SYNC_ACCOUNT_TYPE SOURCE_ID = CALENDAR_SYNC_SOURCE_ID VERSION = CALENDAR_SYNC_VERSION DIRTY = CALENDAR_SYNC_DIRTY SYNC1 = CALENDAR_SYNC1 SYNC2 = CALENDAR_SYNC2 SYNC3 = CALENDAR_SYNC3 SYNC4 = CALENDAR_SYNC4 SYNC5 = CALENDAR_SYNC5 SYNC6 = CALENDAR_SYNC6 SYNC7 = CALENDAR_SYNC7 SYNC8 = CALENDAR_SYNC8 SYNC9 = CALENDAR_SYNC9 SYNC10 = CALENDAR_SYNC10 class SyncState(Stub): """CalendarContract.SyncState — 同步状态表""" CONTENT_URI = CALENDAR_URI_SYNC_STATE _ID = "_id" ACCOUNT_NAME = "account_name" ACCOUNT_TYPE = "account_type" DATA = "data" class Calendars(Stub): """CalendarContract.Calendars — 日历表""" CONTENT_URI = CALENDAR_URI_CALENDARS _ID = "_id" CALENDAR_DISPLAY_NAME = "calendar_displayName" CALENDAR_ACCOUNT_NAME = "account_name" CALENDAR_ACCOUNT_TYPE = "account_type" CALENDAR_OWNER_ACCOUNT = "calendar_ownerAccount" CALENDAR_COLOR = "calendar_color" CALENDAR_COLOR_KEY = "calendar_color_key" CALENDAR_ACCESS_LEVEL = "calendar_access_level" CALENDAR_VISIBLE = "calendar_visible" CALENDAR_SYNC_EVENTS = "calendar_sync_events" CALENDAR_TIMEZONE = "calendar_timezone" CALENDAR_ALLOWED_REMINDERS = "calendar_allowedReminders" CALENDAR_ALLOWED_AVAILABILITY = "calendar_allowedAvailability" CALENDAR_ALLOWED_ATTENDEE_TYPES = "calendar_allowedAttendeeTypes" CALENDAR_IS_PRIMARY = "calendar_isPrimary" CALENDAR_MAX_REMINDERS = "calendar_maxReminders" CALENDAR_DTSTART = "calendar_dtstart" CALENDAR_CAN_ORGANIZER_RESPOND = "calendar_canOrganizerRespond" CALENDAR_CAN_MODIFY_TIME_ZONE = "calendar_canModifyTimeZone" CALENDAR_AVAILABLE_COLORS = "calendar_availableColors" CALENDAR_COLORS_RAW = "calendar_colorsRaw" CALENDAR_ALLOWED_REMINDERS = "calendar_allowedReminders" NAME = "calendar_displayName" SYNC_EVENTS = "calendar_sync_events" VISIBLE = 1 SYNC_EVENTS_YES = 1 SYNC_EVENTS_NO = 0 NO_UNDO_UPDATE_DELETION = 1 @staticmethod def query(context: Any, projection: List[str], selection: str = None, selection_args: List[str] = None, sort_order: str = None) -> List[Dict[str, Any]]: """Query the calendars table.""" return [] @staticmethod def queryWithFactory(context: Any, projection: List[str], selection: str = None, selection_args: List[str] = None, sort_order: str = None) -> Any: """Query calendars with factory.""" return None @staticmethod def getCalendarColor(context: Any, calendar_id: int) -> int: """Get calendar color.""" return 0xFF1976D2 class Events(Stub): """CalendarContract.Events — 事件表""" CONTENT_URI = CALENDAR_URI_EVENTS _ID = "_id" TITLE = "title" DESCRIPTION = "description" EVENT_LOCATION = "eventLocation" DTSTART = "dtstart" DTEND = "dtend" DURATION = "duration" EVENT_TIMEZONE = "eventTimezone" ALL_DAY = "allDay" CALENDAR_ID = "calendar_id" ORGANIZER = "organizer" STATUS = "eventStatus" AVAILABILITY = "availability" ACCESS_LEVEL = "accessLevel" RRULE = "rrule" RDATE = "rdate" EXRULE = "exrule" EXDATE = "exdate" ORIGINAL_ID = "original_id" ORIGINAL_SYNC_ID = "original_sync_id" ORIGINAL_INSTANCE_TIME = "originalInstanceTime" ORIGINAL_ALL_DAY = "originalAllDay" LAST_DATE = "lastDate" HAS_ALARM = "hasAlarm" HAS_EXTENDED_PROPERTIES = "hasExtendedProperties" EVENT_COLOR = "eventColor" EVENT_COLOR_KEY = "eventColor_key" CUSTOM_APP_PACKAGE = "customAppPackage" CUSTOM_APP_URI = "customAppUri" ORGANIZER_CAN_RESPOND = "organizerCanRespond" SELF_ATTENDEE_STATUS = "selfAttendeeStatus" UID_2445 = "uid2445" IS_ORGANIZER = "isOrganizer" CAN_INVITE_OTHERS = "canInviteOthers" ALLOWED_REMINDERS = "allowedReminders" STATUS_TENTATIVE = 0 STATUS_CONFIRMED = 1 STATUS_CANCELED = 2 @staticmethod def query(context: Any, projection: List[str], selection: str = None, selection_args: List[str] = None, sort_order: str = None) -> List[Dict[str, Any]]: """Query the events table.""" return [] @staticmethod def insert(context: Any, values: Dict[str, Any]) -> int: """Insert a new event. Returns the event ID.""" return -1 @staticmethod def update(context: Any, values: Dict[str, Any], selection: str = None, selection_args: List[str] = None) -> int: """Update events. Returns number of rows affected.""" return 0 @staticmethod def delete(context: Any, selection: str = None, selection_args: List[str] = None) -> int: """Delete events. Returns number of rows deleted.""" return 0 @staticmethod def queryEntity(context: Any, projection: List[str], selection: str = None, selection_args: List[str] = None, sort_order: str = None) -> List[Any]: """Query event entities.""" return [] class Attendees(Stub): """CalendarContract.Attendees — 参与者表""" CONTENT_URI = CALENDAR_URI_ATTENDEES _ID = "_id" EVENT_ID = "event_id" ATTENDEE_NAME = "attendeeName" ATTENDEE_EMAIL = "attendeeEmail" ATTENDEE_RELATIONSHIP = "attendeeRelationship" ATTENDEE_TYPE = "attendeeType" ATTENDEE_STATUS = "attendeeStatus" ATTENDEE_IDENTITY = "attendeeIdentity" ATTENDEE_ID_NAMESPACE = "attendeeIdNamespace" RELATIONSHIP_NONE = 0 RELATIONSHIP_ORGANIZER = 1 RELATIONSHIP_ATTENDEE = 2 RELATIONSHIP_PERFORMER = 3 RELATIONSHIP_SPEAKER = 4 TYPE_NONE = 0 TYPE_REQUIRED = 1 TYPE_OPTIONAL = 2 STATUS_NONE = 0 STATUS_ACCEPTED = 1 STATUS_DECLINED = 2 STATUS_INVITED = 3 STATUS_TENTATIVE = 4 @staticmethod def query(context: Any, event_id: int, projection: List[str] = None) -> List[Dict[str, Any]]: """Query attendees for a specific event.""" return [] class Reminders(Stub): """CalendarContract.Reminders — 提醒表""" CONTENT_URI = CALENDAR_URI_REMINDERS _ID = "_id" EVENT_ID = "event_id" MINUTES = "minutes" METHOD = "method" METHOD_DEFAULT = 0 METHOD_ALERT = 1 METHOD_EMAIL = 2 METHOD_SMS = 3 METHOD_ALARM = 4 @staticmethod def query(context: Any, event_id: int, projection: List[str] = None) -> List[Dict[str, Any]]: """Query reminders for a specific event.""" return [] class Instances(Stub): """CalendarContract.Instances — 实例表""" CONTENT_URI = CALENDAR_URI_INSTANCES CONTENT_BY_DAY_URI = CALENDAR_URI_INSTANCES_GROUP_BY_DAY _ID = "_id" EVENT_ID = "event_id" BEGIN = "begin" END = "end" TITLE = "title" DESCRIPTION = "description" EVENT_LOCATION = "eventLocation" ALL_DAY = "allDay" CALENDAR_ID = "calendar_id" RRULE = "rrule" ORIGINAL_ID = "original_id" ORIGINAL_INSTANCE_TIME = "originalInstanceTime" ORIGINAL_SYNC_ID = "original_sync_id" EVENT_TIMEZONE = "eventTimezone" DTSTART = "dtstart" DTEND = "dtend" DURATION = "duration" STATUS = "eventStatus" AVAILABILITY = "availability" ACCESS_LEVEL = "accessLevel" HAS_ALARM = "hasAlarm" HAS_EXTENDED_PROPERTIES = "hasExtendedProperties" EVENT_COLOR = "eventColor" SELF_ATTENDEE_STATUS = "selfAttendeeStatus" START_DAY = "startDay" END_DAY = "endDay" START_MINUTE = "startMinute" END_MINUTE = "endMinute" @staticmethod def query(context: Any, projection: List[str], begin_time: int, end_time: int, selection: str = None, selection_args: List[str] = None, sort_order: str = None) -> List[Dict[str, Any]]: """Query instances in a time range.""" return [] class Colors(Stub): """CalendarContract.Colors — 颜色表""" CONTENT_URI = CALENDAR_URI_COLORS _ID = "_id" COLOR_KEY = "color_key" COLOR = "color" COLOR_TYPE = "color_type" TYPE_CALENDAR = 0 TYPE_EVENT = 1 @staticmethod def query(context: Any, projection: List[str] = None) -> List[Dict[str, Any]]: """Query available colors.""" return [] class CalendarEntity(Stub): """CalendarContract.CalendarEntity — 日历实体""" CONTENT_URI = CALENDAR_URI_CALENDAR_ENTITY _ID = "_id" CALENDAR_DISPLAY_NAME = "calendar_displayName" CALENDAR_ACCOUNT_NAME = "account_name" CALENDAR_ACCOUNT_TYPE = "account_type" CALENDAR_OWNER_ACCOUNT = "calendar_ownerAccount" CALENDAR_COLOR = "calendar_color" CALENDAR_ACCESS_LEVEL = "calendar_access_level" CALENDAR_VISIBLE = "calendar_visible" CALENDAR_SYNC_EVENTS = "calendar_sync_events" CALENDAR_TIMEZONE = "calendar_timezone" CALENDAR_IS_PRIMARY = "calendar_isPrimary" CALENDAR_DTSTART = "calendar_dtstart" CALENDAR_CAN_ORGANIZER_RESPOND = "calendar_canOrganizerRespond" CALENDAR_CAN_MODIFY_TIME_ZONE = "calendar_canModifyTimeZone" CALENDAR_MAX_REMINDERS = "calendar_maxReminders" CALENDAR_ALLOWED_REMINDERS = "calendar_allowedReminders" @staticmethod def queryEntity(context: Any, projection: List[str], selection: str = None, selection_args: List[str] = None, sort_order: str = None) -> List[Any]: """Query calendar entities.""" return [] class EventEntity(Stub): """CalendarContract.EventEntity — 事件实体""" CONTENT_URI = CALENDAR_URI_EVENT_ENTITY _ID = "_id" TITLE = "title" DESCRIPTION = "description" EVENT_LOCATION = "eventLocation" DTSTART = "dtstart" DTEND = "dtend" DURATION = "duration" EVENT_TIMEZONE = "eventTimezone" ALL_DAY = "allDay" CALENDAR_ID = "calendar_id" ORGANIZER = "organizer" STATUS = "eventStatus" AVAILABILITY = "availability" ACCESS_LEVEL = "accessLevel" RRULE = "rrule" RDATE = "rdate" EXRULE = "exrule" EXDATE = "exdate" ORIGINAL_ID = "original_id" ORIGINAL_SYNC_ID = "original_sync_id" ORIGINAL_INSTANCE_TIME = "originalInstanceTime" ORIGINAL_ALL_DAY = "originalAllDay" LAST_DATE = "lastDate" HAS_ALARM = "hasAlarm" HAS_EXTENDED_PROPERTIES = "hasExtendedProperties" EVENT_COLOR = "eventColor" CUSTOM_APP_PACKAGE = "customAppPackage" CUSTOM_APP_URI = "customAppUri" ORGANIZER_CAN_RESPOND = "organizerCanRespond" SELF_ATTENDEE_STATUS = "selfAttendeeStatus" UID_2445 = "uid2445" IS_ORGANIZER = "isOrganizer" CAN_INVITE_OTHERS = "canInviteOthers" ALLOWED_REMINDERS = "allowedReminders" @staticmethod def queryEntity(context: Any, projection: List[str], selection: str = None, selection_args: List[str] = None, sort_order: str = None) -> List[Any]: """Query event entities.""" return [] class CalendarCache(Stub): """CalendarContract.CalendarCache — 日历缓存表""" CONTENT_URI = CALENDAR_URI_CALENDAR_CACHE KEY = "key" VALUE = "value" TIMEZONE_TYPE = "timezoneType" TIMEZONE_INSTANCES = "timezoneInstances" TIMEZONE_INSTANCES_PREVIOUS = "timezoneInstancesPrevious" TIMEZONE_INSTANCES_NEXT = "timezoneInstancesNext" TIMEZONE_TYPE_AUTO = "auto" TIMEZONE_TYPE_USER = "user" @staticmethod def getCacheKey(timezone_id: str, type_key: str) -> str: """Build a cache key for timezone data.""" return f"{timezone_id}_{type_key}" class CalendarAlerts(Stub): """CalendarContract.CalendarAlerts — 日历提醒表""" CONTENT_URI = CALENDAR_URI_CALENDAR_ALERTS _ID = "_id" EVENT_ID = "event_id" BEGIN = "begin" END = "end" ALARM_TIME = "alarmTime" CREATION_TIME = "creationTime" RECEIVED_TIME = "receivedTime" NOTIFY_TIME = "notifyTime" STATE = "state" MINUTES = "minutes" ACKNOWLEDGED = "acknowledged" DISMISSED = "dismissed" TYPE = "type" ORIGIN = "origin" STATE_SCHEDULED = 0 STATE_FIRED = 1 STATE_DISMISSED = 2 TYPE_ALARM = 0 TYPE_REMINDER = 1 ORIGIN_SELF = 0 ORIGIN_SYNC = 1 @staticmethod def query(context: Any, projection: List[str] = None) -> List[Dict[str, Any]]: """Query calendar alerts.""" return [] @staticmethod def insert(context: Any, values: Dict[str, Any]) -> int: """Insert a calendar alert. Returns the alert ID.""" return -1 @staticmethod def updateState(context: Any, alert_id: int, state: int): """Update the state of a calendar alert.""" pass class CalendarNotification(Stub): """CalendarContract.CalendarNotification — 日历通知表""" CONTENT_URI = None # Virtual table, no direct content URI _ID = "_id" EVENT_ID = "event_id" ALARM_TIME = "alarmTime" BEGIN = "begin" END = "end" TITLE = "title" DESCRIPTION = "description" LOCATION = "location" STATE = "state" MINUTES = "minutes" VISIBILITY = "visibility" PRIORITY = "priority" GROUP_KEY = "groupKey" SORT_KEY = "sortKey" STATE_SHOWN = 0 STATE_DISMISSED = 1 VISIBILITY_PRIVATE = 0 VISIBILITY_PUBLIC = 1 PRIORITY_DEFAULT = 0 PRIORITY_HIGH = 1 PRIORITY_LOW = 2 @staticmethod def notify(context: Any, event_id: int, alarm_time: int, begin: int, end: int): """Trigger notification for a calendar event.""" pass @staticmethod def cancelNotification(context: Any, event_id: int): """Cancel notification for a calendar event.""" pass class CalendarSyncColumns(SyncColumns): """CalendarContract.CalendarSyncColumns — 日历同步列""" CAL_SYNC1 = "cal_sync1" CAL_SYNC2 = "cal_sync2" CAL_SYNC3 = "cal_sync3" CAL_SYNC4 = "cal_sync4" CAL_SYNC5 = "cal_sync5" CAL_SYNC6 = "cal_sync6" CAL_SYNC7 = "cal_sync7" CAL_SYNC8 = "cal_sync8" CAL_SYNC9 = "cal_sync9" CAL_SYNC10 = "cal_sync10" # ═══════════════════════════════════════════════════════════════ # CalendarContract 根类 # ═══════════════════════════════════════════════════════════════ class CalendarContract(CalendarContractBase): """CalendarContract — 日历合约(扩展版)""" Calendars = Calendars Events = Events Attendees = Attendees Reminders = Reminders Instances = Instances Colors = Colors CalendarEntity = CalendarEntity EventEntity = EventEntity CalendarCache = CalendarCache CalendarAlerts = CalendarAlerts CalendarNotification = CalendarNotification CalendarSyncColumns = CalendarSyncColumns SyncState = SyncState # URI aliases CONTENT_URI_CALENDARS = CALENDAR_URI_CALENDARS CONTENT_URI_EVENTS = CALENDAR_URI_EVENTS CONTENT_URI_ATTENDEES = CALENDAR_URI_ATTENDEES CONTENT_URI_REMINDERS = CALENDAR_URI_REMINDERS CONTENT_URI_INSTANCES = CALENDAR_URI_INSTANCES CONTENT_URI_INSTANCES_GROUP_BY_DAY = CALENDAR_URI_INSTANCES_GROUP_BY_DAY CONTENT_URI_COLORS = CALENDAR_URI_COLORS CONTENT_URI_CALENDAR_ALERTS = CALENDAR_URI_CALENDAR_ALERTS CONTENT_URI_CALENDAR_CACHE = CALENDAR_URI_CALENDAR_CACHE CONTENT_URI_SYNC_STATE = CALENDAR_URI_SYNC_STATE CONTENT_URI_CALENDAR_ENTITY = CALENDAR_URI_CALENDAR_ENTITY CONTENT_URI_EVENT_ENTITY = CALENDAR_URI_EVENT_ENTITY @staticmethod def isValidEventType(context: Any, type_value: str) -> bool: """Check if a mime type is a valid event type.""" return type_value in ("vnd.android.cursor.item/event", "vnd.android.cursor.dir/event") # ═══════════════════════════════════════════════════════════════ # CalendarContract 便捷类(扩展别名) # ═══════════════════════════════════════════════════════════════ class CalendarContractCalendars(Calendars): """CalendarContract.Calendars 别名""" pass class CalendarContractEvents(Events): """CalendarContract.Events 别名""" pass class CalendarContractAttendees(Attendees): """CalendarContract.Attendees 别名""" pass class CalendarContractReminders(Reminders): """CalendarContract.Reminders 别名""" pass class CalendarContractInstances(Instances): """CalendarContract.Instances 别名""" pass class CalendarContractColors(Colors): """CalendarContract.Colors 别名""" pass class CalendarContractCalendarEntity(CalendarEntity): """CalendarContract.CalendarEntity 别名""" pass class CalendarContractEventEntity(EventEntity): """CalendarContract.EventEntity 别名""" pass class CalendarContractCalendarCache(CalendarCache): """CalendarContract.CalendarCache 别名""" pass class CalendarContractCalendarAlerts(CalendarAlerts): """CalendarContract.CalendarAlerts 别名""" pass class CalendarContractCalendarNotification(CalendarNotification): """CalendarContract.CalendarNotification 别名""" pass class CalendarContractCalendarSyncColumns(CalendarSyncColumns): """CalendarContract.CalendarSyncColumns 别名""" pass class CalendarContractSyncState(SyncState): """CalendarContract.SyncState 别名""" pass # ═══════════════════════════════════════════════════════════════ # CalendarEvent 辅助类 # ═══════════════════════════════════════════════════════════════ class CalendarEvent(Stub): """CalendarEvent — 事件对象封装""" def __init__(self, event_id: int = -1, title: str = "", description: str = "", location: str = "", dtstart: int = 0, dtend: int = 0, timezone: str = "UTC", all_day: bool = False, calendar_id: int = -1, organizer: str = "", status: int = EVENT_STATUS_CONFIRMED, availability: int = AVAILABILITY_BUSY, access_level: int = ACCESS_DEFAULT, rrule: str = "", duration: str = ""): super().__init__() self._id = event_id self._title = title self._description = description self._location = location self._dtstart = dtstart self._dtend = dtend self._timezone = timezone self._all_day = all_day self._calendar_id = calendar_id self._organizer = organizer self._status = status self._availability = availability self._access_level = access_level self._rrule = rrule self._duration = duration self._attendees: List[Dict[str, Any]] = [] self._reminders: List[Dict[str, Any]] = [] self._extended_properties: Dict[str, str] = {} def getId(self) -> int: return self._id def getTitle(self) -> str: return self._title def setTitle(self, title: str): self._title = title def getDescription(self) -> str: return self._description def setDescription(self, description: str): self._description = description def getLocation(self) -> str: return self._location def setLocation(self, location: str): self._location = location def getDtStart(self) -> int: return self._dtstart def setDtStart(self, dtstart: int): self._dtstart = dtstart def getDtEnd(self) -> int: return self._dtend def setDtEnd(self, dtend: int): self._dtend = dtend def getTimezone(self) -> str: return self._timezone def setTimezone(self, timezone: str): self._timezone = timezone def isAllDay(self) -> bool: return self._all_day def setAllDay(self, all_day: bool): self._all_day = all_day def getCalendarId(self) -> int: return self._calendar_id def setCalendarId(self, calendar_id: int): self._calendar_id = calendar_id def getOrganizer(self) -> str: return self._organizer def setOrganizer(self, organizer: str): self._organizer = organizer def getStatus(self) -> int: return self._status def setStatus(self, status: int): self._status = status def getAvailability(self) -> int: return self._availability def setAvailability(self, availability: int): self._availability = availability def getAccessLevel(self) -> int: return self._access_level def setAccessLevel(self, access_level: int): self._access_level = access_level def getRrule(self) -> str: return self._rrule def setRrule(self, rrule: str): self._rrule = rrule def getDuration(self) -> str: return self._duration def setDuration(self, duration: str): self._duration = duration def addAttendee(self, name: str, email: str, relationship: int = ATTENDEE_RELATIONSHIP_ATTENDEE, attendee_type: int = ATTENDEE_TYPE_REQUIRED, status: int = ATTENDEE_STATUS_NONE): """Add an attendee to this event.""" self._attendees.append({ "attendeeName": name, "attendeeEmail": email, "attendeeRelationship": relationship, "attendeeType": attendee_type, "attendeeStatus": status, }) def getAttendees(self) -> List[Dict[str, Any]]: return list(self._attendees) def addReminder(self, minutes: int, method: int = REMINDER_METHOD_DEFAULT): """Add a reminder to this event.""" self._reminders.append({ "minutes": minutes, "method": method, }) def getReminders(self) -> List[Dict[str, Any]]: return list(self._reminders) def putExtendedProperty(self, key: str, value: str): """Set an extended property.""" self._extended_properties[key] = value def getExtendedProperty(self, key: str) -> Optional[str]: return self._extended_properties.get(key) def getExtendedProperties(self) -> Dict[str, str]: return dict(self._extended_properties) def toContentValues(self) -> Dict[str, Any]: """Convert event to content values dictionary.""" values: Dict[str, Any] = {} if self._title: values["title"] = self._title if self._description: values["description"] = self._description if self._location: values["eventLocation"] = self._location if self._dtstart: values["dtstart"] = self._dtstart if self._dtend: values["dtend"] = self._dtend if self._timezone: values["eventTimezone"] = self._timezone values["allDay"] = 1 if self._all_day else 0 if self._calendar_id >= 0: values["calendar_id"] = self._calendar_id if self._organizer: values["organizer"] = self._organizer values["eventStatus"] = self._status values["availability"] = self._availability values["accessLevel"] = self._access_level if self._rrule: values["rrule"] = self._rrule if self._duration: values["duration"] = self._duration return values @staticmethod def fromContentValues(values: Dict[str, Any]) -> "CalendarEvent": """Create an event from content values.""" event = CalendarEvent() event._id = values.get("_id", -1) event._title = values.get("title", "") event._description = values.get("description", "") event._location = values.get("eventLocation", "") event._dtstart = values.get("dtstart", 0) event._dtend = values.get("dtend", 0) event._timezone = values.get("eventTimezone", "UTC") event._all_day = bool(values.get("allDay", 0)) event._calendar_id = values.get("calendar_id", -1) event._organizer = values.get("organizer", "") event._status = values.get("eventStatus", EVENT_STATUS_CONFIRMED) event._availability = values.get("availability", AVAILABILITY_BUSY) event._access_level = values.get("accessLevel", ACCESS_DEFAULT) event._rrule = values.get("rrule", "") event._duration = values.get("duration", "") return event def toString(self) -> str: return f"CalendarEvent(id={self._id}, title='{self._title}')" # ═══════════════════════════════════════════════════════════════ # CalendarHelper 工具类 # ═══════════════════════════════════════════════════════════════ class CalendarHelper(Stub): """CalendarHelper — 日历操作辅助工具""" @staticmethod def createEvent(context: Any, calendar_id: int, title: str, dtstart: int, dtend: int, timezone: str = "UTC", description: str = "", location: str = "", all_day: bool = False) -> Optional[int]: """Create a calendar event. Returns event ID or None.""" return None @staticmethod def updateEvent(context: Any, event_id: int, values: Dict[str, Any]) -> bool: """Update a calendar event.""" return False @staticmethod def deleteEvent(context: Any, event_id: int) -> bool: """Delete a calendar event.""" return False @staticmethod def getEvent(context: Any, event_id: int) -> Optional[CalendarEvent]: """Get a calendar event by ID.""" return None @staticmethod def queryEvents(context: Any, calendar_id: Optional[int] = None, start_time: Optional[int] = None, end_time: Optional[int] = None) -> List[CalendarEvent]: """Query calendar events with optional filters.""" return [] @staticmethod def addReminder(context: Any, event_id: int, minutes: int, method: int = REMINDER_METHOD_DEFAULT) -> bool: """Add a reminder to an event.""" return False @staticmethod def addAttendee(context: Any, event_id: int, email: str, name: str = "") -> bool: """Add an attendee to an event.""" return False @staticmethod def getDefaultCalendarId(context: Any) -> int: """Get the default calendar ID.""" return -1 @staticmethod def queryCalendars(context: Any) -> List[Dict[str, Any]]: """Query all available calendars.""" return [] @staticmethod def getCalendars(context: Any) -> List[Dict[str, Any]]: """Get all calendars with sync enabled.""" return [] @staticmethod def createCalendar(context: Any, display_name: str, account_name: str, account_type: str, owner_account: str = "", timezone: str = "UTC") -> Optional[int]: """Create a new calendar.""" return None @staticmethod def deleteCalendar(context: Any, calendar_id: int) -> bool: """Delete a calendar.""" return False # ═══════════════════════════════════════════════════════════════ # CalendarTimezoneHelper 工具类 # ═══════════════════════════════════════════════════════════════ class CalendarTimezoneHelper(Stub): """CalendarTimezoneHelper — 时区辅助工具""" TIMEZONE_IDS = [ "UTC", "GMT", "America/New_York", "America/Chicago", "America/Denver", "America/Los_Angeles", "America/Anchorage", "Pacific/Honolulu", "Europe/London", "Europe/Paris", "Europe/Berlin", "Europe/Moscow", "Europe/Istanbul", "Asia/Dubai", "Asia/Kolkata", "Asia/Bangkok", "Asia/Shanghai", "Asia/Tokyo", "Asia/Seoul", "Australia/Sydney", "Pacific/Auckland", ] @staticmethod def getAvailableTimezoneIds() -> List[str]: """Get list of available timezone IDs.""" return list(CalendarTimezoneHelper.TIMEZONE_IDS) @staticmethod def toDisplayName(timezone_id: str, locale: Any = None) -> str: """Convert timezone ID to display name.""" try: import zoneinfo tz = zoneinfo.ZoneInfo(timezone_id) now = datetime.datetime.now(tz) return f"{timezone_id} (UTC{now.strftime('%z')})" except Exception: return timezone_id @staticmethod def toMilliseconds(days: int = 0, hours: int = 0, minutes: int = 0, seconds: int = 0) -> int: """Convert time duration to milliseconds.""" total_seconds = (days * 86400) + (hours * 3600) + (minutes * 60) + seconds return total_seconds * 1000 @staticmethod def fromMilliseconds(ms: int) -> Dict[str, int]: """Convert milliseconds to duration components.""" total_seconds = ms // 1000 days = total_seconds // 86400 hours = (total_seconds % 86400) // 3600 minutes = (total_seconds % 3600) // 60 seconds = total_seconds % 60 return {"days": days, "hours": hours, "minutes": minutes, "seconds": seconds} # ═══════════════════════════════════════════════════════════════ # CalendarRecurrenceRule 工具类 # ═══════════════════════════════════════════════════════════════ class CalendarRecurrenceRule(Stub): """CalendarRecurrenceRule — 重复规则解析工具""" FREQ_DAILY = "DAILY" FREQ_WEEKLY = "WEEKLY" FREQ_MONTHLY = "MONTHLY" FREQ_YEARLY = "YEARLY" BY_DAY_SUNDAY = "SU" BY_DAY_MONDAY = "MO" BY_DAY_TUESDAY = "TU" BY_DAY_WEDNESDAY = "WE" BY_DAY_THURSDAY = "TH" BY_DAY_FRIDAY = "FR" BY_DAY_SATURDAY = "SA" def __init__(self, rrule: str = ""): super().__init__() self._freq: str = "" self._interval: int = 1 self._count: Optional[int] = None self._until: Optional[int] = None self._by_day: List[str] = [] self._by_month_day: List[int] = [] self._by_month: List[int] = [] self._by_year_day: List[int] = [] self._week_start: str = "MO" self._raw = rrule if rrule: self._parse(rrule) def _parse(self, rrule: str): """Parse an RRULE string.""" parts = rrule.split(";") for part in parts: if "=" not in part: continue key, value = part.split("=", 1) key = key.strip().upper() value = value.strip() if key == "FREQ": self._freq = value elif key == "INTERVAL": self._interval = int(value) elif key == "COUNT": self._count = int(value) elif key == "UNTIL": try: self._until = int(value) except ValueError: self._until = 0 elif key == "BYDAY": self._by_day = value.split(",") elif key == "BYMONTHDAY": self._by_month_day = [int(x) for x in value.split(",")] elif key == "BYMONTH": self._by_month = [int(x) for x in value.split(",")] elif key == "BYYEARDAY": self._by_year_day = [int(x) for x in value.split(",")] elif key == "WKST": self._week_start = value def getFrequency(self) -> str: return self._freq def getInterval(self) -> int: return self._interval def getCount(self) -> Optional[int]: return self._count def getUntil(self) -> Optional[int]: return self._until def getByDay(self) -> List[str]: return list(self._by_day) def getByMonthDay(self) -> List[int]: return list(self._by_month_day) def getByMonth(self) -> List[int]: return list(self._by_month) def toString(self) -> str: return self._raw @staticmethod def createDaily(interval: int = 1, count: Optional[int] = None, until: Optional[int] = None) -> "CalendarRecurrenceRule": """Create a daily recurrence rule.""" parts = [f"FREQ={CalendarRecurrenceRule.FREQ_DAILY}"] if interval > 1: parts.append(f"INTERVAL={interval}") if count is not None: parts.append(f"COUNT={count}") if until is not None: parts.append(f"UNTIL={until}") return CalendarRecurrenceRule(";".join(parts)) @staticmethod def createWeekly(interval: int = 1, by_day: Optional[List[str]] = None, count: Optional[int] = None) -> "CalendarRecurrenceRule": """Create a weekly recurrence rule.""" parts = [f"FREQ={CalendarRecurrenceRule.FREQ_WEEKLY}"] if interval > 1: parts.append(f"INTERVAL={interval}") if by_day: parts.append(f"BYDAY={','.join(by_day)}") if count is not None: parts.append(f"COUNT={count}") return CalendarRecurrenceRule(";".join(parts)) @staticmethod def createMonthly(interval: int = 1, by_month_day: Optional[List[int]] = None, count: Optional[int] = None) -> "CalendarRecurrenceRule": """Create a monthly recurrence rule.""" parts = [f"FREQ={CalendarRecurrenceRule.FREQ_MONTHLY}"] if interval > 1: parts.append(f"INTERVAL={interval}") if by_month_day: parts.append(f"BYMONTHDAY={','.join(str(d) for d in by_month_day)}") if count is not None: parts.append(f"COUNT={count}") return CalendarRecurrenceRule(";".join(parts)) # ═══════════════════════════════════════════════════════════════ # __all__ # ═══════════════════════════════════════════════════════════════ __all__ = [ # Constants "CALENDAR_DISPLAY_NAME", "CALENDAR_ACCOUNT_NAME", "CALENDAR_ACCOUNT_TYPE", "CALENDAR_OWNER_ACCOUNT", "CALENDAR_COLOR", "CALENDAR_COLOR_KEY", "CALENDAR_ACCESS_LEVEL", "CALENDAR_VISIBLE", "CALENDAR_SYNC_EVENTS", "CALENDAR_TIMEZONE", "CALENDAR_ALLOWED_REMINDERS", "CALENDAR_IS_PRIMARY", "CALENDAR_MAX_REMINDERS", "CALENDAR_DTSTART", "EVENT_ID", "EVENT_TITLE", "EVENT_DESCRIPTION", "EVENT_LOCATION", "EVENT_DTSTART", "EVENT_DTEND", "EVENT_DURATION", "EVENT_TIMEZONE", "EVENT_ALL_DAY", "EVENT_CALENDAR_ID", "EVENT_ORGANIZER", "EVENT_STATUS", "EVENT_AVAILABILITY", "EVENT_ACCESS_LEVEL", "EVENT_RRULE", "EVENT_RDATE", "EVENT_EXRULE", "EVENT_EXDATE", "ATTENDEE_ID", "ATTENDEE_EVENT_ID", "ATTENDEE_NAME", "ATTENDEE_EMAIL", "ATTENDEE_RELATIONSHIP", "ATTENDEE_TYPE", "ATTENDEE_STATUS", "REMINDER_ID", "REMINDER_EVENT_ID", "REMINDER_MINUTES", "REMINDER_METHOD", "INSTANCE_ID", "INSTANCE_BEGIN", "INSTANCE_END", "AVAILABILITY_BUSY", "AVAILABILITY_FREE", "AVAILABILITY_TENTATIVE", "ACCESS_DEFAULT", "ACCESS_CONFIDENTIAL", "ACCESS_PRIVATE", "ACCESS_PUBLIC", "ACCESS_RESTRICTED", "EVENT_STATUS_TENTATIVE", "EVENT_STATUS_CONFIRMED", "EVENT_STATUS_CANCELED", "ATTENDEE_RELATIONSHIP_NONE", "ATTENDEE_RELATIONSHIP_ORGANIZER", "ATTENDEE_RELATIONSHIP_ATTENDEE", "ATTENDEE_RELATIONSHIP_PERFORMER", "ATTENDEE_RELATIONSHIP_SPEAKER", "ATTENDEE_TYPE_NONE", "ATTENDEE_TYPE_REQUIRED", "ATTENDEE_TYPE_OPTIONAL", "ATTENDEE_STATUS_NONE", "ATTENDEE_STATUS_ACCEPTED", "ATTENDEE_STATUS_DECLINED", "ATTENDEE_STATUS_INVITED", "ATTENDEE_STATUS_TENTATIVE", "REMINDER_METHOD_DEFAULT", "REMINDER_METHOD_ALERT", "REMINDER_METHOD_EMAIL", "REMINDER_METHOD_SMS", "REMINDER_METHOD_ALARM", # Classes "CalendarContract", "Calendars", "Events", "Attendees", "Reminders", "Instances", "Colors", "CalendarEntity", "EventEntity", "CalendarCache", "CalendarAlerts", "CalendarNotification", "CalendarSyncColumns", "SyncState", "CalendarContractBase", "SyncColumns", "CalendarContractCalendars", "CalendarContractEvents", "CalendarContractAttendees", "CalendarContractReminders", "CalendarContractInstances", "CalendarContractColors", "CalendarContractCalendarEntity", "CalendarContractEventEntity", "CalendarContractCalendarCache", "CalendarContractCalendarAlerts", "CalendarContractCalendarNotification", "CalendarContractCalendarSyncColumns", "CalendarContractSyncState", # Helpers "CalendarEvent", "CalendarHelper", "CalendarTimezoneHelper", "CalendarRecurrenceRule", ]