mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 04:37:06 +00:00
Refactor calendars in Habitica (#131020)
* Refactor calendars * changes
This commit is contained in:
parent
5c8fb5ec2c
commit
8e12fbff88
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from abc import abstractmethod
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import date, datetime, timedelta
|
||||||
from enum import StrEnum
|
from enum import StrEnum
|
||||||
|
|
||||||
@ -60,6 +61,43 @@ class HabiticaCalendarEntity(HabiticaBase, CalendarEntity):
|
|||||||
"""Initialize calendar entity."""
|
"""Initialize calendar entity."""
|
||||||
super().__init__(coordinator, self.entity_description)
|
super().__init__(coordinator, self.entity_description)
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_events(
|
||||||
|
self, start_date: datetime, end_date: datetime | None = None
|
||||||
|
) -> list[CalendarEvent]:
|
||||||
|
"""Return events."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def event(self) -> CalendarEvent | None:
|
||||||
|
"""Return the current or next upcoming event."""
|
||||||
|
|
||||||
|
return next(iter(self.get_events(dt_util.now())), None)
|
||||||
|
|
||||||
|
async def async_get_events(
|
||||||
|
self, hass: HomeAssistant, start_date: datetime, end_date: datetime
|
||||||
|
) -> list[CalendarEvent]:
|
||||||
|
"""Return calendar events within a datetime range."""
|
||||||
|
|
||||||
|
return self.get_events(start_date, end_date)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def start_of_today(self) -> datetime:
|
||||||
|
"""Habitica daystart."""
|
||||||
|
return dt_util.start_of_local_day(
|
||||||
|
datetime.fromisoformat(self.coordinator.data.user["lastCron"])
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_recurrence_dates(
|
||||||
|
self, recurrences: rrule, start_date: datetime, end_date: datetime | None = None
|
||||||
|
) -> list[datetime]:
|
||||||
|
"""Calculate recurrence dates based on start_date and end_date."""
|
||||||
|
if end_date:
|
||||||
|
return recurrences.between(
|
||||||
|
start_date, end_date - timedelta(days=1), inc=True
|
||||||
|
)
|
||||||
|
# if no end_date is given, return only the next recurrence
|
||||||
|
return [recurrences.after(start_date, inc=True)]
|
||||||
|
|
||||||
|
|
||||||
class HabiticaTodosCalendarEntity(HabiticaCalendarEntity):
|
class HabiticaTodosCalendarEntity(HabiticaCalendarEntity):
|
||||||
"""Habitica todos calendar entity."""
|
"""Habitica todos calendar entity."""
|
||||||
@ -69,7 +107,7 @@ class HabiticaTodosCalendarEntity(HabiticaCalendarEntity):
|
|||||||
translation_key=HabiticaCalendar.TODOS,
|
translation_key=HabiticaCalendar.TODOS,
|
||||||
)
|
)
|
||||||
|
|
||||||
def dated_todos(
|
def get_events(
|
||||||
self, start_date: datetime, end_date: datetime | None = None
|
self, start_date: datetime, end_date: datetime | None = None
|
||||||
) -> list[CalendarEvent]:
|
) -> list[CalendarEvent]:
|
||||||
"""Get all dated todos."""
|
"""Get all dated todos."""
|
||||||
@ -112,18 +150,6 @@ class HabiticaTodosCalendarEntity(HabiticaCalendarEntity):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def event(self) -> CalendarEvent | None:
|
|
||||||
"""Return the current or next upcoming event."""
|
|
||||||
|
|
||||||
return next(iter(self.dated_todos(dt_util.now())), None)
|
|
||||||
|
|
||||||
async def async_get_events(
|
|
||||||
self, hass: HomeAssistant, start_date: datetime, end_date: datetime
|
|
||||||
) -> list[CalendarEvent]:
|
|
||||||
"""Return calendar events within a datetime range."""
|
|
||||||
return self.dated_todos(start_date, end_date)
|
|
||||||
|
|
||||||
|
|
||||||
class HabiticaDailiesCalendarEntity(HabiticaCalendarEntity):
|
class HabiticaDailiesCalendarEntity(HabiticaCalendarEntity):
|
||||||
"""Habitica dailies calendar entity."""
|
"""Habitica dailies calendar entity."""
|
||||||
@ -133,13 +159,6 @@ class HabiticaDailiesCalendarEntity(HabiticaCalendarEntity):
|
|||||||
translation_key=HabiticaCalendar.DAILIES,
|
translation_key=HabiticaCalendar.DAILIES,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def today(self) -> datetime:
|
|
||||||
"""Habitica daystart."""
|
|
||||||
return dt_util.start_of_local_day(
|
|
||||||
datetime.fromisoformat(self.coordinator.data.user["lastCron"])
|
|
||||||
)
|
|
||||||
|
|
||||||
def end_date(self, recurrence: datetime, end: datetime | None = None) -> date:
|
def end_date(self, recurrence: datetime, end: datetime | None = None) -> date:
|
||||||
"""Calculate the end date for a yesterdaily.
|
"""Calculate the end date for a yesterdaily.
|
||||||
|
|
||||||
@ -152,29 +171,20 @@ class HabiticaDailiesCalendarEntity(HabiticaCalendarEntity):
|
|||||||
if end:
|
if end:
|
||||||
return recurrence.date() + timedelta(days=1)
|
return recurrence.date() + timedelta(days=1)
|
||||||
return (
|
return (
|
||||||
dt_util.start_of_local_day() if recurrence == self.today else recurrence
|
dt_util.start_of_local_day()
|
||||||
|
if recurrence == self.start_of_today
|
||||||
|
else recurrence
|
||||||
).date() + timedelta(days=1)
|
).date() + timedelta(days=1)
|
||||||
|
|
||||||
def get_recurrence_dates(
|
def get_events(
|
||||||
self, recurrences: rrule, start_date: datetime, end_date: datetime | None = None
|
|
||||||
) -> list[datetime]:
|
|
||||||
"""Calculate recurrence dates based on start_date and end_date."""
|
|
||||||
if end_date:
|
|
||||||
return recurrences.between(
|
|
||||||
start_date, end_date - timedelta(days=1), inc=True
|
|
||||||
)
|
|
||||||
# if no end_date is given, return only the next recurrence
|
|
||||||
return [recurrences.after(self.today, inc=True)]
|
|
||||||
|
|
||||||
def due_dailies(
|
|
||||||
self, start_date: datetime, end_date: datetime | None = None
|
self, start_date: datetime, end_date: datetime | None = None
|
||||||
) -> list[CalendarEvent]:
|
) -> list[CalendarEvent]:
|
||||||
"""Get dailies and recurrences for a given period or the next upcoming."""
|
"""Get dailies and recurrences for a given period or the next upcoming."""
|
||||||
|
|
||||||
# we only have dailies for today and future recurrences
|
# we only have dailies for today and future recurrences
|
||||||
if end_date and end_date < self.today:
|
if end_date and end_date < self.start_of_today:
|
||||||
return []
|
return []
|
||||||
start_date = max(start_date, self.today)
|
start_date = max(start_date, self.start_of_today)
|
||||||
|
|
||||||
events = []
|
events = []
|
||||||
for task in self.coordinator.data.tasks:
|
for task in self.coordinator.data.tasks:
|
||||||
@ -187,10 +197,12 @@ class HabiticaDailiesCalendarEntity(HabiticaCalendarEntity):
|
|||||||
recurrences, start_date, end_date
|
recurrences, start_date, end_date
|
||||||
)
|
)
|
||||||
for recurrence in recurrence_dates:
|
for recurrence in recurrence_dates:
|
||||||
is_future_event = recurrence > self.today
|
is_future_event = recurrence > self.start_of_today
|
||||||
is_current_event = recurrence <= self.today and not task["completed"]
|
is_current_event = (
|
||||||
|
recurrence <= self.start_of_today and not task["completed"]
|
||||||
|
)
|
||||||
|
|
||||||
if not (is_future_event or is_current_event):
|
if not is_future_event and not is_current_event:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
events.append(
|
events.append(
|
||||||
@ -214,20 +226,15 @@ class HabiticaDailiesCalendarEntity(HabiticaCalendarEntity):
|
|||||||
@property
|
@property
|
||||||
def event(self) -> CalendarEvent | None:
|
def event(self) -> CalendarEvent | None:
|
||||||
"""Return the next upcoming event."""
|
"""Return the next upcoming event."""
|
||||||
return next(iter(self.due_dailies(self.today)), None)
|
return next(iter(self.get_events(self.start_of_today)), None)
|
||||||
|
|
||||||
async def async_get_events(
|
|
||||||
self, hass: HomeAssistant, start_date: datetime, end_date: datetime
|
|
||||||
) -> list[CalendarEvent]:
|
|
||||||
"""Return calendar events within a datetime range."""
|
|
||||||
|
|
||||||
return self.due_dailies(start_date, end_date)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self) -> dict[str, bool | None] | None:
|
def extra_state_attributes(self) -> dict[str, bool | None] | None:
|
||||||
"""Return entity specific state attributes."""
|
"""Return entity specific state attributes."""
|
||||||
return {
|
return {
|
||||||
"yesterdaily": self.event.start < self.today.date() if self.event else None
|
"yesterdaily": self.event.start < self.start_of_today.date()
|
||||||
|
if self.event
|
||||||
|
else None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -239,7 +246,7 @@ class HabiticaTodoRemindersCalendarEntity(HabiticaCalendarEntity):
|
|||||||
translation_key=HabiticaCalendar.TODO_REMINDERS,
|
translation_key=HabiticaCalendar.TODO_REMINDERS,
|
||||||
)
|
)
|
||||||
|
|
||||||
def reminders(
|
def get_events(
|
||||||
self, start_date: datetime, end_date: datetime | None = None
|
self, start_date: datetime, end_date: datetime | None = None
|
||||||
) -> list[CalendarEvent]:
|
) -> list[CalendarEvent]:
|
||||||
"""Reminders for todos."""
|
"""Reminders for todos."""
|
||||||
@ -282,18 +289,6 @@ class HabiticaTodoRemindersCalendarEntity(HabiticaCalendarEntity):
|
|||||||
key=lambda event: event.start,
|
key=lambda event: event.start,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def event(self) -> CalendarEvent | None:
|
|
||||||
"""Return the next upcoming event."""
|
|
||||||
return next(iter(self.reminders(dt_util.now())), None)
|
|
||||||
|
|
||||||
async def async_get_events(
|
|
||||||
self, hass: HomeAssistant, start_date: datetime, end_date: datetime
|
|
||||||
) -> list[CalendarEvent]:
|
|
||||||
"""Return calendar events within a datetime range."""
|
|
||||||
|
|
||||||
return self.reminders(start_date, end_date)
|
|
||||||
|
|
||||||
|
|
||||||
class HabiticaDailyRemindersCalendarEntity(HabiticaCalendarEntity):
|
class HabiticaDailyRemindersCalendarEntity(HabiticaCalendarEntity):
|
||||||
"""Habitica daily reminders calendar entity."""
|
"""Habitica daily reminders calendar entity."""
|
||||||
@ -321,47 +316,31 @@ class HabiticaDailyRemindersCalendarEntity(HabiticaCalendarEntity):
|
|||||||
tzinfo=dt_util.DEFAULT_TIME_ZONE,
|
tzinfo=dt_util.DEFAULT_TIME_ZONE,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
def get_events(
|
||||||
def today(self) -> datetime:
|
|
||||||
"""Habitica daystart."""
|
|
||||||
return dt_util.start_of_local_day(
|
|
||||||
datetime.fromisoformat(self.coordinator.data.user["lastCron"])
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_recurrence_dates(
|
|
||||||
self, recurrences: rrule, start_date: datetime, end_date: datetime | None = None
|
|
||||||
) -> list[datetime]:
|
|
||||||
"""Calculate recurrence dates based on start_date and end_date."""
|
|
||||||
if end_date:
|
|
||||||
return recurrences.between(
|
|
||||||
start_date, end_date - timedelta(days=1), inc=True
|
|
||||||
)
|
|
||||||
# if no end_date is given, return only the next recurrence
|
|
||||||
return [recurrences.after(self.today, inc=True)]
|
|
||||||
|
|
||||||
def reminders(
|
|
||||||
self, start_date: datetime, end_date: datetime | None = None
|
self, start_date: datetime, end_date: datetime | None = None
|
||||||
) -> list[CalendarEvent]:
|
) -> list[CalendarEvent]:
|
||||||
"""Reminders for dailies."""
|
"""Reminders for dailies."""
|
||||||
|
|
||||||
events = []
|
events = []
|
||||||
if end_date and end_date < self.today:
|
if end_date and end_date < self.start_of_today:
|
||||||
return []
|
return []
|
||||||
start_date = max(start_date, self.today)
|
start_date = max(start_date, self.start_of_today)
|
||||||
|
|
||||||
for task in self.coordinator.data.tasks:
|
for task in self.coordinator.data.tasks:
|
||||||
if not (task["type"] == HabiticaTaskType.DAILY and task["everyX"]):
|
if not (task["type"] == HabiticaTaskType.DAILY and task["everyX"]):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
recurrences = build_rrule(task)
|
recurrences = build_rrule(task)
|
||||||
recurrences_start = self.today
|
recurrences_start = self.start_of_today
|
||||||
|
|
||||||
recurrence_dates = self.get_recurrence_dates(
|
recurrence_dates = self.get_recurrence_dates(
|
||||||
recurrences, recurrences_start, end_date
|
recurrences, recurrences_start, end_date
|
||||||
)
|
)
|
||||||
for recurrence in recurrence_dates:
|
for recurrence in recurrence_dates:
|
||||||
is_future_event = recurrence > self.today
|
is_future_event = recurrence > self.start_of_today
|
||||||
is_current_event = recurrence <= self.today and not task["completed"]
|
is_current_event = (
|
||||||
|
recurrence <= self.start_of_today and not task["completed"]
|
||||||
|
)
|
||||||
|
|
||||||
if not is_future_event and not is_current_event:
|
if not is_future_event and not is_current_event:
|
||||||
continue
|
continue
|
||||||
@ -388,15 +367,3 @@ class HabiticaDailyRemindersCalendarEntity(HabiticaCalendarEntity):
|
|||||||
events,
|
events,
|
||||||
key=lambda event: event.start,
|
key=lambda event: event.start,
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def event(self) -> CalendarEvent | None:
|
|
||||||
"""Return the next upcoming event."""
|
|
||||||
return next(iter(self.reminders(dt_util.now())), None)
|
|
||||||
|
|
||||||
async def async_get_events(
|
|
||||||
self, hass: HomeAssistant, start_date: datetime, end_date: datetime
|
|
||||||
) -> list[CalendarEvent]:
|
|
||||||
"""Return calendar events within a datetime range."""
|
|
||||||
|
|
||||||
return self.reminders(start_date, end_date)
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user