187 files
This commit is contained in:
@@ -16,7 +16,7 @@ from homeassistant.helpers.event import async_track_time_change
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import photos
|
||||
from . import notify_strings, photos
|
||||
from .const import DOMAIN
|
||||
from .coord_assignments import AssignmentsMixin
|
||||
from .coord_auctions import AuctionsMixin
|
||||
@@ -136,6 +136,7 @@ class TaskMateCoordinator(
|
||||
self.external_state_version: int = 0
|
||||
self._unsub_surprise: Callable[[], None] | None = None
|
||||
self._unsub_weekly: Callable[[], None] | None = None
|
||||
self._unsub_language: Callable[[], None] | None = None
|
||||
self._unsub_mandatory: list[Callable[[], None]] = []
|
||||
# Per-build memo for the availability matrix (PERF-1). Non-None only
|
||||
# inside `availability_build_scope()`; see coord_chores/coord_assignments.
|
||||
@@ -392,6 +393,10 @@ class TaskMateCoordinator(
|
||||
"""Initialize the coordinator."""
|
||||
await self.storage.async_load()
|
||||
self.notifications.coordinator = self
|
||||
# Notification wording follows HA's language (#1037): load it now, and
|
||||
# again whenever the language is changed.
|
||||
await notify_strings.async_load(self.hass)
|
||||
self._unsub_language = notify_strings.async_watch_language(self.hass)
|
||||
# Wire existing parent recipients to default-on parent-audience types
|
||||
# that have no routes yet (e.g. a parent added after the one-time seed),
|
||||
# so pending-approval notifications actually reach a parent.
|
||||
@@ -470,6 +475,7 @@ class TaskMateCoordinator(
|
||||
|
||||
async def _async_send_weekly_digest(self) -> None:
|
||||
"""Build and send the weekly digest to parents (opt-in)."""
|
||||
await notify_strings.async_load(self.hass)
|
||||
summary = self._build_weekly_digest()
|
||||
if not summary:
|
||||
return
|
||||
@@ -492,7 +498,14 @@ class TaskMateCoordinator(
|
||||
done[comp.child_id] = done.get(comp.child_id, 0) + 1
|
||||
earned[comp.child_id] = earned.get(comp.child_id, 0) + (comp.points_awarded or 0)
|
||||
pts = self.storage.get_points_name()
|
||||
lines = [f"• {c.name}: {done.get(c.id, 0)} chores, {earned.get(c.id, 0)} {pts} earned" for c in children]
|
||||
lines = [
|
||||
notify_strings.render(
|
||||
self.hass,
|
||||
"weekly_digest_line",
|
||||
{"child_name": c.name, "chores": done.get(c.id, 0), "points": earned.get(c.id, 0), "points_name": pts},
|
||||
)
|
||||
for c in children
|
||||
]
|
||||
return "\n".join(lines)
|
||||
|
||||
async def _async_send_monthly_report(self) -> None:
|
||||
@@ -500,6 +513,7 @@ class TaskMateCoordinator(
|
||||
today = dt_util.now().date()
|
||||
month_end = today.replace(day=1) - timedelta(days=1)
|
||||
month_start = month_end.replace(day=1)
|
||||
await notify_strings.async_load(self.hass)
|
||||
summary = self._build_monthly_report(month_start, month_end)
|
||||
if not summary:
|
||||
return
|
||||
@@ -507,7 +521,7 @@ class TaskMateCoordinator(
|
||||
"monthly_report",
|
||||
{
|
||||
"summary": summary,
|
||||
"month": month_start.strftime("%B %Y"),
|
||||
"month": notify_strings.month_year(self.hass, month_start),
|
||||
},
|
||||
)
|
||||
|
||||
@@ -528,8 +542,18 @@ class TaskMateCoordinator(
|
||||
earned[comp.child_id] = earned.get(comp.child_id, 0) + (comp.points_awarded or 0)
|
||||
pts = self.storage.get_points_name()
|
||||
lines = [
|
||||
f"• {c.name}: {done.get(c.id, 0)} chores, {earned.get(c.id, 0)} {pts}, "
|
||||
f"level {getattr(c, 'level', 1)}, best streak {getattr(c, 'best_streak', 0)}"
|
||||
notify_strings.render(
|
||||
self.hass,
|
||||
"monthly_report_line",
|
||||
{
|
||||
"child_name": c.name,
|
||||
"chores": done.get(c.id, 0),
|
||||
"points": earned.get(c.id, 0),
|
||||
"points_name": pts,
|
||||
"level": getattr(c, "level", 1),
|
||||
"streak": getattr(c, "best_streak", 0),
|
||||
},
|
||||
)
|
||||
for c in children
|
||||
]
|
||||
return "\n".join(lines)
|
||||
@@ -688,7 +712,7 @@ class TaskMateCoordinator(
|
||||
{
|
||||
"child_name": top["name"],
|
||||
"points": top["points"],
|
||||
"month": prev_end.strftime("%B %Y"),
|
||||
"month": notify_strings.month_year(self.hass, prev_end),
|
||||
"points_name": self.storage.get_points_name(),
|
||||
},
|
||||
)
|
||||
@@ -809,6 +833,7 @@ class TaskMateCoordinator(
|
||||
"_unsub_tag_scanned",
|
||||
"_unsub_surprise",
|
||||
"_unsub_weekly",
|
||||
"_unsub_language",
|
||||
"_unsub_auction_timer",
|
||||
):
|
||||
if unsub := getattr(self, attr, None):
|
||||
@@ -1011,6 +1036,7 @@ class TaskMateCoordinator(
|
||||
self.storage.remove_daily_progress_for_child(child_id)
|
||||
self.storage.remove_quest_progress_for_child(child_id)
|
||||
self.storage.remove_challenge_progress_for_child(child_id)
|
||||
self.storage.remove_weekly_target_bonuses(child_id=child_id)
|
||||
# Drop pending swap requests either side of this child (#785) — a
|
||||
# handover to or from a deleted child can never complete, and the
|
||||
# approval queue would render them as "?".
|
||||
|
||||
Reference in New Issue
Block a user