From 4e04e11d8c8facf525b7644ecee25341416c181e Mon Sep 17 00:00:00 2001 From: maxDorninger <97409287+maxDorninger@users.noreply.github.com> Date: Tue, 1 Jul 2025 15:28:47 +0200 Subject: [PATCH] add notification manager --- media_manager/notification/manager.py | 88 +++++++++++++++++++++++++++ media_manager/notification/service.py | 8 +++ 2 files changed, 96 insertions(+) create mode 100644 media_manager/notification/manager.py diff --git a/media_manager/notification/manager.py b/media_manager/notification/manager.py new file mode 100644 index 0000000..da8ef7e --- /dev/null +++ b/media_manager/notification/manager.py @@ -0,0 +1,88 @@ +""" +Notification Manager - Orchestrates sending notifications through all configured service providers +""" +import logging +from typing import List, Dict, Any +from media_manager.notification.schemas import MessageNotification +from media_manager.notification.service_providers.abstractNotificationServiceProvider import AbstractNotificationServiceProvider +from media_manager.notification.service_providers.email import EmailNotificationServiceProvider +from media_manager.notification.service_providers.gotify import GotifyNotificationServiceProvider +from media_manager.notification.service_providers.ntfy import NtfyNotificationServiceProvider +from media_manager.notification.service_providers.pushover import PushoverNotificationServiceProvider +from media_manager.notification.config import NotificationConfig + +logger = logging.getLogger(__name__) + + +class NotificationManager: + """ + Manages and orchestrates notifications across all configured service providers. + """ + + def __init__(self): + self.config = NotificationConfig() + self.providers: List[AbstractNotificationServiceProvider] = [] + self._initialize_providers() + + def _initialize_providers(self) -> None: + # Email provider + if self.config.email: + try: + self.providers.append(EmailNotificationServiceProvider()) + logger.info("Email notification provider initialized") + except Exception as e: + logger.error(f"Failed to initialize Email provider: {e}") + + # Gotify provider + if self.config.gotify_api_key and self.config.gotify_url: + try: + self.providers.append(GotifyNotificationServiceProvider()) + logger.info("Gotify notification provider initialized") + except Exception as e: + logger.error(f"Failed to initialize Gotify provider: {e}") + + # Ntfy provider + if self.config.ntfy_url: + try: + self.providers.append(NtfyNotificationServiceProvider()) + logger.info("Ntfy notification provider initialized") + except Exception as e: + logger.error(f"Failed to initialize Ntfy provider: {e}") + + # Pushover provider + if self.config.pushover_api_key and self.config.pushover_user: + try: + self.providers.append(PushoverNotificationServiceProvider()) + logger.info("Pushover notification provider initialized") + except Exception as e: + logger.error(f"Failed to initialize Pushover provider: {e}") + + logger.info(f"Initialized {len(self.providers)} notification providers") + + def send_notification(self, title: str, message: str) -> None: + if not self.providers: + logger.warning("No notification providers configured") + + notification = MessageNotification(title=title, message=message) + + for provider in self.providers: + provider_name = provider.__class__.__name__ + try: + success = provider.send_notification(notification) + if success: + logger.info(f"Notification sent successfully via {provider_name}") + else: + logger.warning(f"Failed to send notification via {provider_name}") + + except Exception as e: + logger.error(f"Error sending notification via {provider_name}: {e}") + + + def get_configured_providers(self) -> List[str]: + return [provider.__class__.__name__ for provider in self.providers] + + def is_configured(self) -> bool: + return len(self.providers) > 0 + + +notification_manager = NotificationManager() diff --git a/media_manager/notification/service.py b/media_manager/notification/service.py index 38be884..d173f3c 100644 --- a/media_manager/notification/service.py +++ b/media_manager/notification/service.py @@ -11,6 +11,7 @@ from media_manager.indexer.schemas import IndexerQueryResultId from media_manager.metadataProvider.schemas import MetaDataProviderSearchResult from media_manager.notification.repository import NotificationRepository from media_manager.notification.schemas import NotificationId, Notification +from media_manager.notification.manager import notification_manager from media_manager.torrent.schemas import Torrent, TorrentStatus from media_manager.torrent.service import TorrentService from media_manager.movies import log @@ -46,6 +47,7 @@ class NotificationService: notification_repository: NotificationRepository, ): self.notification_repository = notification_repository + self.notification_manager = notification_manager def get_notification(self, id: NotificationId) -> Notification: return self.notification_repository.get_notification(id=id) @@ -68,3 +70,9 @@ class NotificationService: def delete_notification(self, id: NotificationId) -> None: return self.notification_repository.delete_notification(id=id) + def send_notification_to_all_providers(self, title: str, message: str) -> None: + self.notification_manager.send_notification(title, message) + + internal_notification = Notification(message=f"{title}: {message}", read=False) + self.save_notification(internal_notification) + return \ No newline at end of file