mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-04 05:39:00 -05:00
Add ConnectorManager component which allows for Connectors to listen to triggers and do actions on them. Also add HomeAssistantConfig which stores the configuration for the HomeAssistantConnector
This commit is contained in:
98
cookbook/connectors/connector_manager.py
Normal file
98
cookbook/connectors/connector_manager.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import asyncio
|
||||
from enum import Enum
|
||||
from types import UnionType
|
||||
from typing import List, Any, Dict
|
||||
|
||||
from django_scopes import scope
|
||||
|
||||
from cookbook.connectors.connector import Connector
|
||||
from cookbook.connectors.homeassistant import HomeAssistant
|
||||
from cookbook.models import ShoppingListEntry, Recipe, MealPlan, Space
|
||||
|
||||
|
||||
class ActionType(Enum):
|
||||
CREATED = 1
|
||||
UPDATED = 2
|
||||
DELETED = 3
|
||||
|
||||
|
||||
class ConnectorManager:
|
||||
_connectors: Dict[str, List[Connector]]
|
||||
_listening_to_classes: UnionType = ShoppingListEntry | Recipe | MealPlan | Connector
|
||||
max_concurrent_tasks = 2
|
||||
|
||||
def __init__(self):
|
||||
self._connectors = dict()
|
||||
|
||||
def __call__(self, instance: Any, **kwargs) -> None:
|
||||
if not isinstance(instance, self._listening_to_classes):
|
||||
return
|
||||
|
||||
# If a Connector was changed/updated, refresh connector from the database for said space
|
||||
purge_connector_cache = isinstance(instance, Connector)
|
||||
|
||||
space: Space = instance.space
|
||||
if space.name in self._connectors and not purge_connector_cache:
|
||||
connectors: List[Connector] = self._connectors[space.name]
|
||||
else:
|
||||
with scope(space=space):
|
||||
connectors: List[Connector] = [HomeAssistant(config) for config in space.homeassistantconfig_set.all()]
|
||||
self._connectors[space.name] = connectors
|
||||
|
||||
if len(connectors) == 0 or purge_connector_cache:
|
||||
return
|
||||
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_until_complete(self.run_connectors(connectors, space, instance, **kwargs))
|
||||
loop.close()
|
||||
|
||||
@staticmethod
|
||||
async def run_connectors(connectors: List[Connector], space: Space, instance: Any, **kwargs):
|
||||
action_type: ActionType
|
||||
if "created" in kwargs and kwargs["created"]:
|
||||
action_type = ActionType.CREATED
|
||||
elif "created" in kwargs and not kwargs["created"]:
|
||||
action_type = ActionType.UPDATED
|
||||
elif "origin" in kwargs:
|
||||
action_type = ActionType.DELETED
|
||||
else:
|
||||
return
|
||||
|
||||
tasks: List[asyncio.Task] = list()
|
||||
|
||||
if isinstance(instance, ShoppingListEntry):
|
||||
shopping_list_entry: ShoppingListEntry = instance
|
||||
|
||||
match action_type:
|
||||
case ActionType.CREATED:
|
||||
for connector in connectors:
|
||||
tasks.append(asyncio.create_task(connector.on_shopping_list_entry_created(space, shopping_list_entry)))
|
||||
case ActionType.UPDATED:
|
||||
for connector in connectors:
|
||||
tasks.append(asyncio.create_task(connector.on_shopping_list_entry_updated(space, shopping_list_entry)))
|
||||
case ActionType.DELETED:
|
||||
for connector in connectors:
|
||||
tasks.append(asyncio.create_task(connector.on_shopping_list_entry_deleted(space, shopping_list_entry)))
|
||||
|
||||
try:
|
||||
await asyncio.gather(*tasks, return_exceptions=False)
|
||||
except BaseException as e:
|
||||
print("received an exception from one of the tasks: ", e)
|
||||
# if isinstance(instance, Recipe):
|
||||
# if "created" in kwargs and kwargs["created"]:
|
||||
# for connector in self._connectors:
|
||||
# connector.on_recipe_created(instance, **kwargs)
|
||||
# return
|
||||
# for connector in self._connectors:
|
||||
# connector.on_recipe_updated(instance, **kwargs)
|
||||
# return
|
||||
#
|
||||
# if isinstance(instance, MealPlan):
|
||||
# if "created" in kwargs and kwargs["created"]:
|
||||
# for connector in self._connectors:
|
||||
# connector.on_meal_plan_created(instance, **kwargs)
|
||||
# return
|
||||
# for connector in self._connectors:
|
||||
# connector.on_meal_plan_updated(instance, **kwargs)
|
||||
# return
|
||||
Reference in New Issue
Block a user