mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 09:47:52 +00:00
Update local_calendar/todo to avoid blocking in the event loop (#127048)
This commit is contained in:
parent
f99b7d8b78
commit
5cc8cfb209
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import date, datetime, timedelta
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@ -74,6 +75,7 @@ class LocalCalendarEntity(CalendarEntity):
|
|||||||
"""Initialize LocalCalendarEntity."""
|
"""Initialize LocalCalendarEntity."""
|
||||||
self._store = store
|
self._store = store
|
||||||
self._calendar = calendar
|
self._calendar = calendar
|
||||||
|
self._calendar_lock = asyncio.Lock()
|
||||||
self._event: CalendarEvent | None = None
|
self._event: CalendarEvent | None = None
|
||||||
self._attr_name = name
|
self._attr_name = name
|
||||||
self._attr_unique_id = unique_id
|
self._attr_unique_id = unique_id
|
||||||
@ -110,8 +112,10 @@ class LocalCalendarEntity(CalendarEntity):
|
|||||||
async def async_create_event(self, **kwargs: Any) -> None:
|
async def async_create_event(self, **kwargs: Any) -> None:
|
||||||
"""Add a new event to calendar."""
|
"""Add a new event to calendar."""
|
||||||
event = _parse_event(kwargs)
|
event = _parse_event(kwargs)
|
||||||
EventStore(self._calendar).add(event)
|
async with self._calendar_lock:
|
||||||
await self._async_store()
|
event_store = EventStore(self._calendar)
|
||||||
|
await self.hass.async_add_executor_job(event_store.add, event)
|
||||||
|
await self._async_store()
|
||||||
await self.async_update_ha_state(force_refresh=True)
|
await self.async_update_ha_state(force_refresh=True)
|
||||||
|
|
||||||
async def async_delete_event(
|
async def async_delete_event(
|
||||||
@ -124,15 +128,16 @@ class LocalCalendarEntity(CalendarEntity):
|
|||||||
range_value: Range = Range.NONE
|
range_value: Range = Range.NONE
|
||||||
if recurrence_range == Range.THIS_AND_FUTURE:
|
if recurrence_range == Range.THIS_AND_FUTURE:
|
||||||
range_value = Range.THIS_AND_FUTURE
|
range_value = Range.THIS_AND_FUTURE
|
||||||
try:
|
async with self._calendar_lock:
|
||||||
EventStore(self._calendar).delete(
|
try:
|
||||||
uid,
|
EventStore(self._calendar).delete(
|
||||||
recurrence_id=recurrence_id,
|
uid,
|
||||||
recurrence_range=range_value,
|
recurrence_id=recurrence_id,
|
||||||
)
|
recurrence_range=range_value,
|
||||||
except EventStoreError as err:
|
)
|
||||||
raise HomeAssistantError(f"Error while deleting event: {err}") from err
|
except EventStoreError as err:
|
||||||
await self._async_store()
|
raise HomeAssistantError(f"Error while deleting event: {err}") from err
|
||||||
|
await self._async_store()
|
||||||
await self.async_update_ha_state(force_refresh=True)
|
await self.async_update_ha_state(force_refresh=True)
|
||||||
|
|
||||||
async def async_update_event(
|
async def async_update_event(
|
||||||
@ -147,16 +152,23 @@ class LocalCalendarEntity(CalendarEntity):
|
|||||||
range_value: Range = Range.NONE
|
range_value: Range = Range.NONE
|
||||||
if recurrence_range == Range.THIS_AND_FUTURE:
|
if recurrence_range == Range.THIS_AND_FUTURE:
|
||||||
range_value = Range.THIS_AND_FUTURE
|
range_value = Range.THIS_AND_FUTURE
|
||||||
try:
|
|
||||||
EventStore(self._calendar).edit(
|
async with self._calendar_lock:
|
||||||
uid,
|
event_store = EventStore(self._calendar)
|
||||||
new_event,
|
|
||||||
recurrence_id=recurrence_id,
|
def apply_edit() -> None:
|
||||||
recurrence_range=range_value,
|
event_store.edit(
|
||||||
)
|
uid,
|
||||||
except EventStoreError as err:
|
new_event,
|
||||||
raise HomeAssistantError(f"Error while updating event: {err}") from err
|
recurrence_id=recurrence_id,
|
||||||
await self._async_store()
|
recurrence_range=range_value,
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
await self.hass.async_add_executor_job(apply_edit)
|
||||||
|
except EventStoreError as err:
|
||||||
|
raise HomeAssistantError(f"Error while updating event: {err}") from err
|
||||||
|
await self._async_store()
|
||||||
await self.async_update_ha_state(force_refresh=True)
|
await self.async_update_ha_state(force_refresh=True)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"""A Local To-do todo platform."""
|
"""A Local To-do todo platform."""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -130,6 +131,7 @@ class LocalTodoListEntity(TodoListEntity):
|
|||||||
"""Initialize LocalTodoListEntity."""
|
"""Initialize LocalTodoListEntity."""
|
||||||
self._store = store
|
self._store = store
|
||||||
self._calendar = calendar
|
self._calendar = calendar
|
||||||
|
self._calendar_lock = asyncio.Lock()
|
||||||
self._attr_name = name.capitalize()
|
self._attr_name = name.capitalize()
|
||||||
self._attr_unique_id = unique_id
|
self._attr_unique_id = unique_id
|
||||||
|
|
||||||
@ -159,23 +161,28 @@ class LocalTodoListEntity(TodoListEntity):
|
|||||||
async def async_create_todo_item(self, item: TodoItem) -> None:
|
async def async_create_todo_item(self, item: TodoItem) -> None:
|
||||||
"""Add an item to the To-do list."""
|
"""Add an item to the To-do list."""
|
||||||
todo = _convert_item(item)
|
todo = _convert_item(item)
|
||||||
self._new_todo_store().add(todo)
|
async with self._calendar_lock:
|
||||||
await self.async_save()
|
todo_store = self._new_todo_store()
|
||||||
|
await self.hass.async_add_executor_job(todo_store.add, todo)
|
||||||
|
await self.async_save()
|
||||||
await self.async_update_ha_state(force_refresh=True)
|
await self.async_update_ha_state(force_refresh=True)
|
||||||
|
|
||||||
async def async_update_todo_item(self, item: TodoItem) -> None:
|
async def async_update_todo_item(self, item: TodoItem) -> None:
|
||||||
"""Update an item to the To-do list."""
|
"""Update an item to the To-do list."""
|
||||||
todo = _convert_item(item)
|
todo = _convert_item(item)
|
||||||
self._new_todo_store().edit(todo.uid, todo)
|
async with self._calendar_lock:
|
||||||
await self.async_save()
|
todo_store = self._new_todo_store()
|
||||||
|
await self.hass.async_add_executor_job(todo_store.edit, todo.uid, todo)
|
||||||
|
await self.async_save()
|
||||||
await self.async_update_ha_state(force_refresh=True)
|
await self.async_update_ha_state(force_refresh=True)
|
||||||
|
|
||||||
async def async_delete_todo_items(self, uids: list[str]) -> None:
|
async def async_delete_todo_items(self, uids: list[str]) -> None:
|
||||||
"""Delete an item from the To-do list."""
|
"""Delete an item from the To-do list."""
|
||||||
store = self._new_todo_store()
|
store = self._new_todo_store()
|
||||||
for uid in uids:
|
async with self._calendar_lock:
|
||||||
store.delete(uid)
|
for uid in uids:
|
||||||
await self.async_save()
|
store.delete(uid)
|
||||||
|
await self.async_save()
|
||||||
await self.async_update_ha_state(force_refresh=True)
|
await self.async_update_ha_state(force_refresh=True)
|
||||||
|
|
||||||
async def async_move_todo_item(
|
async def async_move_todo_item(
|
||||||
@ -184,23 +191,24 @@ class LocalTodoListEntity(TodoListEntity):
|
|||||||
"""Re-order an item to the To-do list."""
|
"""Re-order an item to the To-do list."""
|
||||||
if uid == previous_uid:
|
if uid == previous_uid:
|
||||||
return
|
return
|
||||||
todos = self._calendar.todos
|
async with self._calendar_lock:
|
||||||
item_idx: dict[str, int] = {itm.uid: idx for idx, itm in enumerate(todos)}
|
todos = self._calendar.todos
|
||||||
if uid not in item_idx:
|
item_idx: dict[str, int] = {itm.uid: idx for idx, itm in enumerate(todos)}
|
||||||
raise HomeAssistantError(
|
if uid not in item_idx:
|
||||||
"Item '{uid}' not found in todo list {self.entity_id}"
|
raise HomeAssistantError(
|
||||||
)
|
"Item '{uid}' not found in todo list {self.entity_id}"
|
||||||
if previous_uid and previous_uid not in item_idx:
|
)
|
||||||
raise HomeAssistantError(
|
if previous_uid and previous_uid not in item_idx:
|
||||||
"Item '{previous_uid}' not found in todo list {self.entity_id}"
|
raise HomeAssistantError(
|
||||||
)
|
"Item '{previous_uid}' not found in todo list {self.entity_id}"
|
||||||
dst_idx = item_idx[previous_uid] + 1 if previous_uid else 0
|
)
|
||||||
src_idx = item_idx[uid]
|
dst_idx = item_idx[previous_uid] + 1 if previous_uid else 0
|
||||||
src_item = todos.pop(src_idx)
|
src_idx = item_idx[uid]
|
||||||
if dst_idx > src_idx:
|
src_item = todos.pop(src_idx)
|
||||||
dst_idx -= 1
|
if dst_idx > src_idx:
|
||||||
todos.insert(dst_idx, src_item)
|
dst_idx -= 1
|
||||||
await self.async_save()
|
todos.insert(dst_idx, src_item)
|
||||||
|
await self.async_save()
|
||||||
await self.async_update_ha_state(force_refresh=True)
|
await self.async_update_ha_state(force_refresh=True)
|
||||||
|
|
||||||
async def async_save(self) -> None:
|
async def async_save(self) -> None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user