diff --git a/frontend/components/Domain/Group/GroupWebhookEditor.vue b/frontend/components/Domain/Group/GroupWebhookEditor.vue index b29b70cf01d7..93b4df4362f2 100644 --- a/frontend/components/Domain/Group/GroupWebhookEditor.vue +++ b/frontend/components/Domain/Group/GroupWebhookEditor.vue @@ -18,6 +18,8 @@ icon: $globals.icons.testTube, text: $tc('general.test'), event: 'test', + // TODO: There is no functionality hooked up to this. Enable it when there is + disabled: true, }, { icon: $globals.icons.save, diff --git a/frontend/components/global/BaseButtonGroup.vue b/frontend/components/global/BaseButtonGroup.vue index f72908538ff9..356b9b9615d6 100644 --- a/frontend/components/global/BaseButtonGroup.vue +++ b/frontend/components/global/BaseButtonGroup.vue @@ -25,7 +25,7 @@ content-class="text-caption" > @@ -43,6 +43,7 @@ export interface ButtonOption { text: string; event: string; children?: ButtonOption[]; + disabled?: boolean; } export default defineComponent({ diff --git a/frontend/lib/api/admin/admin-tasks.ts b/frontend/lib/api/admin/admin-tasks.ts index 46fe970d164d..af4635cc341c 100644 --- a/frontend/lib/api/admin/admin-tasks.ts +++ b/frontend/lib/api/admin/admin-tasks.ts @@ -1,5 +1,6 @@ import { BaseAPI } from "../base/base-clients"; import { ServerTask } from "~/lib/api/types/server"; +import { PaginationData } from "~/lib/api/types/non-generated"; const prefix = "/api"; @@ -13,6 +14,6 @@ export class AdminTaskAPI extends BaseAPI { } async getAll() { - return await this.requests.get(routes.base); + return await this.requests.get>(routes.base); } } diff --git a/frontend/pages/admin/background-tasks.vue b/frontend/pages/admin/background-tasks.vue index 9005bb98934c..f73b185e557a 100644 --- a/frontend/pages/admin/background-tasks.vue +++ b/frontend/pages/admin/background-tasks.vue @@ -57,7 +57,7 @@ export default defineComponent({ const { data } = await api.serverTasks.getAll(); if (data) { - tasks.value = data; + tasks.value = data.items; } loading.value = false; } diff --git a/mealie/routes/groups/controller_group_notifications.py b/mealie/routes/groups/controller_group_notifications.py index 5f9430f1aad0..ba7a82054ef2 100644 --- a/mealie/routes/groups/controller_group_notifications.py +++ b/mealie/routes/groups/controller_group_notifications.py @@ -100,5 +100,5 @@ class GroupEventsNotifierController(BaseUserController): document_data=EventDocumentDataBase(document_type=EventDocumentType.generic, operation=EventOperation.info), ) - test_listener = AppriseEventListener(self.event_bus.session, self.group_id) + test_listener = AppriseEventListener(self.group_id) test_listener.publish_to_subscribers(test_event, [item.apprise_url]) diff --git a/mealie/services/event_bus_service/event_bus_listeners.py b/mealie/services/event_bus_service/event_bus_listeners.py index ddf526c12104..f618cebd9e2a 100644 --- a/mealie/services/event_bus_service/event_bus_listeners.py +++ b/mealie/services/event_bus_service/event_bus_listeners.py @@ -13,7 +13,6 @@ from sqlalchemy.orm.session import Session from mealie.db.db_setup import session_context from mealie.db.models.group.webhooks import GroupWebhooksModel -from mealie.repos.all_repositories import get_repositories from mealie.repos.repository_factory import AllRepositories from mealie.schema.group.group_events import GroupEventNotifierPrivate from mealie.schema.group.webhook import ReadWebhook @@ -24,12 +23,14 @@ from .publisher import ApprisePublisher, PublisherLike, WebhookPublisher class EventListenerBase(ABC): - session: Session | None + _session: Session | None + _repos: AllRepositories | None - def __init__(self, session: Session, group_id: UUID4, publisher: PublisherLike) -> None: - self.session = session + def __init__(self, group_id: UUID4, publisher: PublisherLike) -> None: self.group_id = group_id self.publisher = publisher + self._session = None + self._repos = None @abstractmethod def get_subscribers(self, event: Event) -> list: @@ -52,22 +53,29 @@ class EventListenerBase(ABC): may be constructed during a request where the session is provided by the request, but the when run as a scheduled task, the session is not provided and must be created. """ - if self.session is None: + if self._session is None: with session_context() as session: - self.session = session - yield self.session + self._session = session + yield self._session else: - yield self.session + yield self._session + + @contextlib.contextmanager + def ensure_repos(self) -> Generator[AllRepositories, None, None]: + if self._repos is None: + with self.ensure_session() as session: + self._repos = AllRepositories(session) + yield self._repos + else: + yield self._repos class AppriseEventListener(EventListenerBase): - def __init__(self, session: Session, group_id: UUID4) -> None: - super().__init__(session, group_id, ApprisePublisher()) + def __init__(self, group_id: UUID4) -> None: + super().__init__(group_id, ApprisePublisher()) def get_subscribers(self, event: Event) -> list[str]: - with self.ensure_session(): - repos = AllRepositories(self.session) - + with self.ensure_repos() as repos: notifiers: list[GroupEventNotifierPrivate] = repos.group_event_notifier.by_group( # type: ignore self.group_id ).multi_query({"enabled": True}, override_schema=GroupEventNotifierPrivate) @@ -115,9 +123,8 @@ class AppriseEventListener(EventListenerBase): class WebhookEventListener(EventListenerBase): - def __init__(self, session: Session, group_id: UUID4) -> None: - super().__init__(session, group_id, WebhookPublisher()) - self.repos = get_repositories(session) + def __init__(self, group_id: UUID4) -> None: + super().__init__(group_id, WebhookPublisher()) def get_subscribers(self, event: Event) -> list[ReadWebhook]: # we only care about events that contain webhook information @@ -127,19 +134,19 @@ class WebhookEventListener(EventListenerBase): scheduled_webhooks = self.get_scheduled_webhooks( event.document_data.webhook_start_dt, event.document_data.webhook_end_dt ) - return scheduled_webhooks def publish_to_subscribers(self, event: Event, subscribers: list[ReadWebhook]) -> None: - if event.document_data.document_type == EventDocumentType.mealplan: - # TODO: limit mealplan data to a date range instead of returning all mealplans - meal_repo = self.repos.meals.by_group(self.group_id) - meal_pagination_data = meal_repo.page_all(pagination=PaginationQuery(page=1, per_page=-1)) - meal_data = meal_pagination_data.items - if meal_data: - webhook_data = cast(EventWebhookData, event.document_data) - webhook_data.webhook_body = meal_data - self.publisher.publish(event, [webhook.url for webhook in subscribers]) + with self.ensure_repos() as repos: + if event.document_data.document_type == EventDocumentType.mealplan: + # TODO: limit mealplan data to a date range instead of returning all mealplans + meal_repo = repos.meals.by_group(self.group_id) + meal_pagination_data = meal_repo.page_all(pagination=PaginationQuery(page=1, per_page=-1)) + meal_data = meal_pagination_data.items + if meal_data: + webhook_data = cast(EventWebhookData, event.document_data) + webhook_data.webhook_body = meal_data + self.publisher.publish(event, [webhook.url for webhook in subscribers]) def get_scheduled_webhooks(self, start_dt: datetime, end_dt: datetime) -> list[ReadWebhook]: """Fetches all scheduled webhooks from the database""" diff --git a/mealie/services/event_bus_service/event_bus_service.py b/mealie/services/event_bus_service/event_bus_service.py index 4af00ecc1fee..ecc8daee0807 100644 --- a/mealie/services/event_bus_service/event_bus_service.py +++ b/mealie/services/event_bus_service/event_bus_service.py @@ -50,8 +50,8 @@ class EventBusService: self.group_id = group_id self.listeners: list[EventListenerBase] = [ - AppriseEventListener(self.session, self.group_id), - WebhookEventListener(self.session, self.group_id), + AppriseEventListener(self.group_id), + WebhookEventListener(self.group_id), ] def dispatch( diff --git a/tests/unit_tests/services_tests/scheduler/tasks/test_post_webhook.py b/tests/unit_tests/services_tests/scheduler/tasks/test_post_webhook.py index 8afbef0a17f4..f09bbf8ae5fa 100644 --- a/tests/unit_tests/services_tests/scheduler/tasks/test_post_webhook.py +++ b/tests/unit_tests/services_tests/scheduler/tasks/test_post_webhook.py @@ -51,7 +51,7 @@ def test_get_scheduled_webhooks_filter_query(database: AllRepositories, unique_u if new_item.enabled: expected.append(new_item) - event_bus_listener = WebhookEventListener(database.session, unique_user.group_id) # type: ignore + event_bus_listener = WebhookEventListener(unique_user.group_id) # type: ignore results = event_bus_listener.get_scheduled_webhooks(start, datetime.now() + timedelta(minutes=5)) assert len(results) == len(expected)