mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 04:10:06 -05:00
convert example & homeassistant specific configs to a generic with all optional fields
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from cookbook.models import ShoppingListEntry, Space
|
||||
from cookbook.models import ShoppingListEntry, Space, ConnectorConfig
|
||||
|
||||
|
||||
class Connector(ABC):
|
||||
@abstractmethod
|
||||
def __init__(self, config: ConnectorConfig):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def on_shopping_list_entry_created(self, space: Space, instance: ShoppingListEntry) -> None:
|
||||
pass
|
||||
@@ -20,5 +24,4 @@ class Connector(ABC):
|
||||
async def close(self) -> None:
|
||||
pass
|
||||
|
||||
# TODO: Maybe add an 'IsEnabled(self) -> Bool' to here
|
||||
# TODO: Add Recipes & possibly Meal Place listeners/hooks (And maybe more?)
|
||||
|
||||
@@ -12,15 +12,13 @@ from typing import List, Any, Dict, Optional
|
||||
from django_scopes import scope
|
||||
|
||||
from cookbook.connectors.connector import Connector
|
||||
from cookbook.connectors.example import Example
|
||||
from cookbook.connectors.homeassistant import HomeAssistant
|
||||
from cookbook.models import ShoppingListEntry, Recipe, MealPlan, Space, HomeAssistantConfig, ExampleConfig
|
||||
from cookbook.models import ShoppingListEntry, Recipe, MealPlan, Space, ConnectorConfig
|
||||
|
||||
multiprocessing.set_start_method('fork') # https://code.djangoproject.com/ticket/31169
|
||||
|
||||
QUEUE_MAX_SIZE = 25
|
||||
REGISTERED_CLASSES: UnionType = ShoppingListEntry | Recipe | MealPlan
|
||||
CONNECTOR_UPDATE_CLASSES: UnionType = HomeAssistantConfig | ExampleConfig
|
||||
|
||||
|
||||
class ActionType(Enum):
|
||||
@@ -37,7 +35,7 @@ class Work:
|
||||
|
||||
class ConnectorManager:
|
||||
_queue: JoinableQueue
|
||||
_listening_to_classes = REGISTERED_CLASSES | CONNECTOR_UPDATE_CLASSES
|
||||
_listening_to_classes = REGISTERED_CLASSES | ConnectorConfig
|
||||
|
||||
def __init__(self):
|
||||
self._queue = multiprocessing.JoinableQueue(maxsize=QUEUE_MAX_SIZE)
|
||||
@@ -88,7 +86,7 @@ class ConnectorManager:
|
||||
break
|
||||
|
||||
# If a Connector was changed/updated, refresh connector from the database for said space
|
||||
refresh_connector_cache = isinstance(item.instance, CONNECTOR_UPDATE_CLASSES)
|
||||
refresh_connector_cache = isinstance(item.instance, ConnectorConfig)
|
||||
|
||||
space: Space = item.instance.space
|
||||
connectors: Optional[List[Connector]] = _connectors.get(space.name)
|
||||
@@ -98,10 +96,11 @@ class ConnectorManager:
|
||||
loop.run_until_complete(close_connectors(connectors))
|
||||
|
||||
with scope(space=space):
|
||||
connectors: List[Connector] = [
|
||||
*(HomeAssistant(config) for config in space.homeassistantconfig_set.all() if config.enabled),
|
||||
*(Example(config) for config in space.exampleconfig_set.all() if config.enabled)
|
||||
]
|
||||
connectors: List[Connector] = list(
|
||||
filter(
|
||||
lambda x: x is not None,
|
||||
[ConnectorManager.get_connected_for_config(config) for config in space.connectorconfig_set.all() if config.enabled],
|
||||
))
|
||||
_connectors[space.name] = connectors
|
||||
|
||||
if len(connectors) == 0 or refresh_connector_cache:
|
||||
@@ -113,6 +112,14 @@ class ConnectorManager:
|
||||
|
||||
loop.close()
|
||||
|
||||
@staticmethod
|
||||
def get_connected_for_config(config: ConnectorConfig) -> Optional[Connector]:
|
||||
match config.type:
|
||||
case ConnectorConfig.HOMEASSISTANT:
|
||||
return HomeAssistant(config)
|
||||
case _:
|
||||
return None
|
||||
|
||||
|
||||
async def close_connectors(connectors: List[Connector]):
|
||||
tasks: List[Task] = [asyncio.create_task(connector.close()) for connector in connectors]
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
from cookbook.connectors.connector import Connector
|
||||
from cookbook.models import ExampleConfig, Space, ShoppingListEntry
|
||||
|
||||
|
||||
class Example(Connector):
|
||||
_config: ExampleConfig
|
||||
|
||||
def __init__(self, config: ExampleConfig):
|
||||
self._config = config
|
||||
|
||||
async def on_shopping_list_entry_created(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None:
|
||||
if not self._config.on_shopping_list_entry_created_enabled:
|
||||
return
|
||||
pass
|
||||
|
||||
async def on_shopping_list_entry_updated(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None:
|
||||
if not self._config.on_shopping_list_entry_updated_enabled:
|
||||
return
|
||||
pass
|
||||
|
||||
async def on_shopping_list_entry_deleted(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None:
|
||||
if not self._config.on_shopping_list_entry_deleted_enabled:
|
||||
return
|
||||
pass
|
||||
|
||||
async def close(self) -> None:
|
||||
pass
|
||||
@@ -4,16 +4,19 @@ from logging import Logger
|
||||
from homeassistant_api import Client, HomeassistantAPIError, Domain
|
||||
|
||||
from cookbook.connectors.connector import Connector
|
||||
from cookbook.models import ShoppingListEntry, HomeAssistantConfig, Space
|
||||
from cookbook.models import ShoppingListEntry, ConnectorConfig, Space
|
||||
|
||||
|
||||
class HomeAssistant(Connector):
|
||||
_domains_cache: dict[str, Domain]
|
||||
_config: HomeAssistantConfig
|
||||
_config: ConnectorConfig
|
||||
_logger: Logger
|
||||
_client: Client
|
||||
|
||||
def __init__(self, config: HomeAssistantConfig):
|
||||
def __init__(self, config: ConnectorConfig):
|
||||
if not config.token or not config.url or not config.todo_entity:
|
||||
raise ValueError("config for HomeAssistantConnector in incomplete")
|
||||
|
||||
self._domains_cache = dict()
|
||||
self._config = config
|
||||
self._logger = logging.getLogger("connector.HomeAssistant")
|
||||
|
||||
Reference in New Issue
Block a user