hook/email: remove/solve some type:ignore

This commit is contained in:
Peter Bieringer
2026-04-10 07:48:10 +02:00
parent 717985763c
commit 785b19812e

View File

@@ -296,7 +296,7 @@ class VComponent:
return [None]
if not isinstance(sub_vobjects, (list, tuple)):
sub_vobjects = [sub_vobjects]
return ([_class(vobject_item=so) for so in sub_vobjects if # type: ignore
return ([_class(vobject_item=so) for so in sub_vobjects if # type: ignore # TODO: Missing positional argument "component_type" in call to "VComponent"
isinstance(so, vobject.base.Component)]
or [None])
@@ -444,12 +444,12 @@ class Timezone(VComponent):
@property
def standard(self) -> Optional[StandardTimezone]:
"""Return the STANDARD subcomponent if it exists."""
return self._get_sub_vobjects("standard", StandardTimezone)[0] # type: ignore
return self._get_sub_vobjects("standard", StandardTimezone)[0] # type: ignore # TODO: got "VComponent | None", expected "StandardTimezone | None"
@property
def daylight(self) -> Optional[DaylightTimezone]:
"""Return the DAYLIGHT subcomponent if it exists."""
return self._get_sub_vobjects("daylight", DaylightTimezone)[0] # type: ignore
return self._get_sub_vobjects("daylight", DaylightTimezone)[0] # type: ignore # TODO: got "VComponent | None", expected "DaylightTimezone | None"
class Event(VComponent):
@@ -513,7 +513,7 @@ class Event(VComponent):
@property
def alarms(self) -> List[Alarm]:
"""Return a list of VALARM items in the event."""
return self._get_sub_vobjects("valarm", Alarm) # type: ignore # Can be multiple
return self._get_sub_vobjects("valarm", Alarm) # type: ignore # Can be multiple # TODO: got "list[VComponent | None]", expected "list[Alarm]"
@property
def attendees(self) -> List[Attendee]:
@@ -541,14 +541,14 @@ class Calendar(VComponent):
@property
def event(self) -> Optional[Event]:
"""Return the VEVENT item in the calendar."""
return self._get_sub_vobjects("vevent", Event)[0] # type: ignore
return self._get_sub_vobjects("vevent", Event)[0] # type: ignore # TODO: got "VComponent | None", expected "Event | None"
# TODO: Add VTODO and VJOURNAL support if needed
@property
def timezone(self) -> Optional[Timezone]:
"""Return the VTIMEZONE item in the calendar."""
return self._get_sub_vobjects("vtimezone", Timezone)[0] # type: ignore
return self._get_sub_vobjects("vtimezone", Timezone)[0] # type: ignore # TODO: got "VComponent | None", expected "Timezone | None"
class EmailEvent:
@@ -637,19 +637,20 @@ class MessageTemplate:
:param attendee: The specific attendee to include in the message, if not a mass email.
:return: The formatted message body.
"""
attendee_name: Union[str, None]
if mass_email:
# If this is a mass email, we do not use individual attendee names
attendee_name = "everyone"
else:
assert attendee is not None, "Attendee must be provided for non-mass emails"
attendee_name = attendee.name if attendee else "Unknown Name" # type: ignore
attendee_name = attendee.name if attendee else "Unknown Name"
context = {
"attendee_name": attendee_name,
"from_email": from_email,
"organizer_name": event.event.organizer or "Unknown Organizer",
"event_title": event.event.summary or "No Title",
"event_start_time": event.event.datetime_start.time_string(), # type: ignore
"event_start_time": event.event.datetime_start.time_string() if event.event.datetime_start else "No Start Time",
"event_end_time": event.event.datetime_end.time_string() if event.event.datetime_end else "No End Time",
"event_location": event.event.location or "No Location Specified",
}
@@ -666,19 +667,20 @@ class MessageTemplate:
:param attendee: The specific attendee to include in the message, if not a mass email.
:return: The formatted message subject.
"""
attendee_name: Union[str, None]
if mass_email:
# If this is a mass email, we do not use individual attendee names
attendee_name = "everyone"
else:
assert attendee is not None, "Attendee must be provided for non-mass emails"
attendee_name = attendee.name if attendee else "Unknown Name" # type: ignore
attendee_name = attendee.name if attendee else "Unknown Name"
context = {
"attendee_name": attendee_name,
"from_email": from_email,
"organizer_name": event.event.organizer or "Unknown Organizer",
"event_title": event.event.summary or "No Title",
"event_start_time": event.event.datetime_start.time_string(), # type: ignore
"event_start_time": event.event.datetime_start.time_string() if event.event.datetime_start else "No Start Time",
"event_end_time": event.event.datetime_end.time_string() if event.event.datetime_end else "No End Time",
"event_location": event.event.location or "No Location Specified",
}
@@ -890,10 +892,10 @@ def _read_event(vobject_data: str) -> EmailEvent:
"""
v_cal: vobject.base.Component = vobject.readOne(vobject_data)
cal: Calendar = Calendar(vobject_item=v_cal)
event: Event = cal.event # type: ignore
event: Union[Event, None] = cal.event
return EmailEvent(
event=event,
event=event, # type: ignore # TODO: Argument "event" to "EmailEvent" has incompatible type "Event | None"; expected "Event"
ics_content=vobject_data,
ics_file_name="event.ics"
)
@@ -955,6 +957,10 @@ class Hook(BaseHook):
:type notification_item: HookNotificationItem
:return: None
"""
email_success: bool
email_event: EmailEvent
new_event: Union[Event, None]
if self.email_config.dryrun:
logger.warning("Hook 'email': DRY-RUN received notification_item: %r", vars(notification_item))
else:
@@ -972,7 +978,7 @@ class Hook(BaseHook):
elif notification_type == HookNotificationItemTypes.UPSERT:
# Handle upsert notifications
new_item_str: str = notification_item.new_content # type: ignore # A serialized vobject.base.Component
new_item_str: str = notification_item.new_content # A serialized vobject.base.Component
previous_item_str: Optional[str] = notification_item.old_content
if not ics_contents_contains_event(contents=new_item_str):
@@ -980,15 +986,15 @@ class Hook(BaseHook):
logger.debug("No event found in the ICS file, skipping notification.")
return
email_event: EmailEvent = _read_event(vobject_data=new_item_str) # type: ignore
email_event = _read_event(vobject_data=new_item_str)
if not email_event:
logger.error("Failed to read event from new content: %s", new_item_str)
return
email_event_event = email_event.event # type: ignore
email_event_event = email_event.event
if not email_event_event:
logger.error("Event could not be parsed from the new content: %s", new_item_str)
return
email_event_end_time = email_event_event.datetime_end # type: ignore
email_event_end_time = email_event_event.datetime_end
# Skip notification if the event end time is more than 1 minute in the past.
if email_event_end_time and email_event_end_time.time:
event_end = email_event_end_time.time
@@ -1038,7 +1044,7 @@ class Hook(BaseHook):
# Notify added attendees as "event created"
if added_attendees:
email_success: bool = self.email_config.send_added_email( # type: ignore
email_success = self.email_config.send_added_email(
attendees=added_attendees,
event=email_event
)
@@ -1048,7 +1054,7 @@ class Hook(BaseHook):
# Notify removed attendees as "event deleted"
if removed_attendees:
email_success: bool = self.email_config.send_deleted_email( # type: ignore
email_success = self.email_config.send_deleted_email(
attendees=removed_attendees,
event=email_event
)
@@ -1059,7 +1065,7 @@ class Hook(BaseHook):
# Notify unaltered attendees as "event updated" if details other than attendees have changed
if unaltered_attendees and event_details_other_than_attendees_changed(original_event=previous_event,
new_event=new_event):
email_success: bool = self.email_config.send_updated_email( # type: ignore
email_success = self.email_config.send_updated_email(
attendees=unaltered_attendees,
event=email_event
)
@@ -1075,16 +1081,16 @@ class Hook(BaseHook):
elif notification_type == HookNotificationItemTypes.DELETE:
# Handle delete notifications
deleted_item_str: str = notification_item.old_content # type: ignore # A serialized vobject.base.Component
deleted_item_str: str = notification_item.old_content # A serialized vobject.base.Component
if not ics_contents_contains_event(contents=deleted_item_str):
# If the ICS file does not contain an event, we do not send any notifications.
logger.debug("No event found in the ICS file, skipping notification.")
return
email_event: EmailEvent = _read_event(vobject_data=deleted_item_str) # type: ignore
email_event = _read_event(vobject_data=deleted_item_str)
email_success: bool = self.email_config.send_deleted_email( # type: ignore
email_success = self.email_config.send_deleted_email(
attendees=email_event.event.attendees,
event=email_event
)