Remove some offset complexity from calendar event (#68724)

Simplify the calendar offset calculations to no longer update the event dictionary
using extra fields. calculate_offset is renamed to extract_offset and the integration
is responsible for overwriting the summary text.

This is in prepration for:
- Improved calendar event typing, removing unnecessary offset_reached field
- Calendar triggers which will remove offsets anyway
This commit is contained in:
Allen Porter 2022-03-27 10:02:19 -07:00 committed by GitHub
parent 945028d43d
commit f61c911174
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 23 deletions

View File

@ -13,7 +13,7 @@ from homeassistant.components.calendar import (
ENTITY_ID_FORMAT, ENTITY_ID_FORMAT,
PLATFORM_SCHEMA, PLATFORM_SCHEMA,
CalendarEventDevice, CalendarEventDevice,
calculate_offset, extract_offset,
get_date, get_date,
is_offset_reached, is_offset_reached,
) )
@ -147,9 +147,12 @@ class WebDavCalendarEventDevice(CalendarEventDevice):
if event is None: if event is None:
self._event = event self._event = event
return return
event = calculate_offset(event, OFFSET) (summary, offset) = extract_offset(event["summary"], OFFSET)
event["summary"] = summary
self._event = event self._event = event
self._attr_extra_state_attributes = {"offset_reached": is_offset_reached(event)} self._attr_extra_state_attributes = {
"offset_reached": is_offset_reached(get_date(event["start"]), offset)
}
class WebDavCalendarData: class WebDavCalendarData:

View File

@ -101,15 +101,14 @@ def normalize_event(event: dict[str, Any]) -> dict[str, Any]:
return normalized_event return normalized_event
def calculate_offset(event: dict[str, Any], offset: str) -> dict[str, Any]: def extract_offset(summary: str, offset_prefix: str) -> tuple[str, datetime.timedelta]:
"""Calculate event offset. """Extract the offset from the event summary.
Return the updated event with the offset_time included. Return a tuple with the updated event summary and offset time.
""" """
summary = event.get("summary", "")
# check if we have an offset tag in the message # check if we have an offset tag in the message
# time is HH:MM or MM # time is HH:MM or MM
reg = f"{offset}([+-]?[0-9]{{0,2}}(:[0-9]{{0,2}})?)" reg = f"{offset_prefix}([+-]?[0-9]{{0,2}}(:[0-9]{{0,2}})?)"
search = re.search(reg, summary) search = re.search(reg, summary)
if search and search.group(1): if search and search.group(1):
time = search.group(1) time = search.group(1)
@ -121,21 +120,16 @@ def calculate_offset(event: dict[str, Any], offset: str) -> dict[str, Any]:
offset_time = time_period_str(time) offset_time = time_period_str(time)
summary = (summary[: search.start()] + summary[search.end() :]).strip() summary = (summary[: search.start()] + summary[search.end() :]).strip()
event["summary"] = summary return (summary, offset_time)
else: return (summary, datetime.timedelta())
offset_time = datetime.timedelta() # default it
event["offset_time"] = offset_time
return event
def is_offset_reached(event: dict[str, Any]) -> bool: def is_offset_reached(
start: datetime.datetime, offset_time: datetime.timedelta
) -> bool:
"""Have we reached the offset time specified in the event title.""" """Have we reached the offset time specified in the event title."""
start = get_date(event["start"]) if offset_time == datetime.timedelta():
offset_time: datetime.timedelta = event["offset_time"]
if start is None or offset_time == datetime.timedelta():
return False return False
return start + offset_time <= dt.now(start.tzinfo) return start + offset_time <= dt.now(start.tzinfo)

View File

@ -11,7 +11,8 @@ from httplib2 import ServerNotFoundError
from homeassistant.components.calendar import ( from homeassistant.components.calendar import (
ENTITY_ID_FORMAT, ENTITY_ID_FORMAT,
CalendarEventDevice, CalendarEventDevice,
calculate_offset, extract_offset,
get_date,
is_offset_reached, is_offset_reached,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
@ -178,9 +179,12 @@ class GoogleCalendarEventDevice(CalendarEventDevice):
_LOGGER.error("Unable to connect to Google: %s", err) _LOGGER.error("Unable to connect to Google: %s", err)
return return
# Pick the first visible event. Make a copy since calculate_offset mutates the event # Pick the first visible event and apply offset calculations.
valid_items = filter(self._event_filter, items) valid_items = filter(self._event_filter, items)
self._event = copy.deepcopy(next(valid_items, None)) self._event = copy.deepcopy(next(valid_items, None))
if self._event: if self._event:
calculate_offset(self._event, self._offset) (summary, offset) = extract_offset(self._event["summary"], self._offset)
self._offset_reached = is_offset_reached(self._event) self._event["summary"] = summary
self._offset_reached = is_offset_reached(
get_date(self._event["start"]), offset
)