diff --git a/custom_components/shopping_list_manager/__init__.py b/custom_components/shopping_list_manager/__init__.py index e092b15..56cbb4d 100644 --- a/custom_components/shopping_list_manager/__init__.py +++ b/custom_components/shopping_list_manager/__init__.py @@ -6,6 +6,8 @@ import logging from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.components import websocket_api as ha_websocket +from .websocket_api import websocket_create_list + from .const import DOMAIN from .manager import ShoppingListManager @@ -34,6 +36,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: hass.data[DOMAIN]["manager"] = manager # Register WebSocket commands using Home Assistant's websocket_api + ha_websocket.async_register_command(hass, websocket_create_list) ha_websocket.async_register_command(hass, websocket_add_product) ha_websocket.async_register_command(hass, websocket_set_qty) ha_websocket.async_register_command(hass, websocket_get_products) @@ -50,4 +53,4 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload Shopping List Manager.""" hass.data[DOMAIN].pop("manager", None) - return True \ No newline at end of file + return True diff --git a/custom_components/shopping_list_manager/manager.py b/custom_components/shopping_list_manager/manager.py index cc7bf77..2dfd07f 100644 --- a/custom_components/shopping_list_manager/manager.py +++ b/custom_components/shopping_list_manager/manager.py @@ -207,6 +207,34 @@ class ShoppingListManager: # PUBLIC API - All operations enforce invariants # ======================================================================== + import time + + async def async_create_list( + self, + list_id: str, + catalogue: str, + owner: str, + visibility: str = "shared", + ): + await self._ensure_catalogues_loaded() + await self._ensure_lists_loaded() + + if list_id in self._lists: + raise ValueError(f"List '{list_id}' already exists") + + if catalogue not in self._catalogues: + raise ValueError(f"Catalogue '{catalogue}' does not exist") + + self._lists[list_id] = { + "catalogue": catalogue, + "owner": owner, + "visibility": visibility, + "created_at": time.time(), + "updated_at": time.time(), + } + + await self._store_lists.async_save(self._lists) + async def async_add_product( self, list_id: str, @@ -375,4 +403,4 @@ class ShoppingListManager: # and would need updating to support per-list structure: # - async_get_full_state() # - get_product() - # - get_active_qty() \ No newline at end of file + # - get_active_qty() diff --git a/custom_components/shopping_list_manager/websocket_api.py b/custom_components/shopping_list_manager/websocket_api.py index f7d61dc..da53906 100644 --- a/custom_components/shopping_list_manager/websocket_api.py +++ b/custom_components/shopping_list_manager/websocket_api.py @@ -10,6 +10,33 @@ from .models import InvariantError _LOGGER = logging.getLogger(__name__) +@websocket_api.websocket_command({ + vol.Required("type"): "shopping_list_manager/create_list", + vol.Required("list_id"): str, + vol.Required("catalogue"): str, + vol.Optional("visibility", default="shared"): vol.In(["shared", "private"]), +}) +@websocket_api.async_response +async def websocket_create_list( + hass: HomeAssistant, + connection: websocket_api.ActiveConnection, + msg: dict, +) -> None: + manager = hass.data[DOMAIN]["manager"] + + try: + await manager.async_create_list( + list_id=msg["list_id"], + catalogue=msg["catalogue"], + owner=connection.user.id, + visibility=msg.get("visibility", "shared"), + ) + + connection.send_result(msg["id"], {"success": True}) + + except Exception as err: + connection.send_error(msg["id"], "create_list_failed", str(err)) + @websocket_api.websocket_command({ vol.Required("type"): "shopping_list_manager/add_product", @@ -295,4 +322,4 @@ async def websocket_delete_product( except Exception as err: _LOGGER.error("Error deleting product from list '%s': %s", list_id, err) - connection.send_error(msg["id"], "delete_product_failed", str(err)) \ No newline at end of file + connection.send_error(msg["id"], "delete_product_failed", str(err))