From e4b35dfe31d4507f1683af00ff507426f44841fd Mon Sep 17 00:00:00 2001 From: Stefano Marinelli Date: Fri, 13 Oct 2023 08:46:01 +0200 Subject: [PATCH] Refactoring the code to make it easy to implement other notification providers. --- NotiMail.py | 47 +++++++++++++++++++++++++++++++++++------------ config.ini | 8 ++++---- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/NotiMail.py b/NotiMail.py index e6a2796..0377b86 100644 --- a/NotiMail.py +++ b/NotiMail.py @@ -134,25 +134,28 @@ class EmailProcessor: print('Subject:', email_message.get('Subject')) print('Body:', email_message.get_payload()) print('------') - Notifier.send_notification(email_message.get('From'), email_message.get('Subject')) + notifier.send_notification(email_message.get('From'), email_message.get('Subject')) # Add UID to database to ensure it is not processed in future runs self.db_handler.add_email(uid, 1) # Delete entries older than 7 days self.db_handler.delete_old_emails() -class Notifier: - @staticmethod - def send_notification(mail_from, mail_subject): - # Check if mail_subject and mail_from are None and replace them with default strings +class NotificationProvider: + def send_notification(self, mail_from, mail_subject): + raise NotImplementedError("Subclasses must implement this method") + +class NTFYNotificationProvider(NotificationProvider): + def __init__(self, ntfy_urls): + self.ntfy_urls = ntfy_urls # Expecting a list of URLs + + def send_notification(self, mail_from, mail_subject): mail_subject = mail_subject if mail_subject is not None else "No Subject" mail_from = mail_from if mail_from is not None else "Unknown Sender" - # Sanitize mail_subject and mail_from to ensure they only contain characters that can be encoded in 'latin-1' sanitized_subject = mail_subject.encode('latin-1', errors='replace').decode('latin-1') sanitized_from = mail_from.encode('latin-1', errors='replace').decode('latin-1') - # Iterate over all notification URLs in the configuration and send notifications - for key, ntfy_url in config['NTFY'].items(): + for ntfy_url in self.ntfy_urls: try: response = requests.post( ntfy_url, @@ -169,6 +172,15 @@ class Notifier: time.sleep(5) # Ensure a delay between notifications +class Notifier: + def __init__(self, providers): + self.providers = providers + + def send_notification(self, mail_from, mail_subject): + for provider in self.providers: + provider.send_notification(mail_from, mail_subject) + + class IMAPHandler: def __init__(self, host, email_user, email_pass): self.host = host @@ -183,7 +195,7 @@ class IMAPHandler: self.mail.select('inbox') except imaplib.IMAP4.error as e: print(f"Cannot connect: {str(e)}") - Notifier.send_notification("Script Error", f"Cannot connect: {str(e)}") + notifier.send_notification("Script Error", f"Cannot connect: {str(e)}") raise def idle(self): @@ -202,14 +214,14 @@ class IMAPHandler: self.mail.readline() except imaplib.IMAP4.abort as e: print(f"Connection closed by server: {str(e)}") - Notifier.send_notification("Script Error", f"Connection closed by server: {str(e)}") + notifier.send_notification("Script Error", f"Connection closed by server: {str(e)}") raise ConnectionAbortedError("Connection lost. Trying to reconnect...") except socket.timeout: print("Socket timeout during IDLE, re-establishing connection...") raise ConnectionAbortedError("Socket timeout. Trying to reconnect...") except Exception as e: print(f"An error occurred: {str(e)}") - Notifier.send_notification("Script Error", f"An error occurred: {str(e)}") + notifier.send_notification("Script Error", f"An error occurred: {str(e)}") raise finally: print("IDLE mode stopped.") @@ -227,6 +239,17 @@ email_user = config['EMAIL']['EmailUser'] email_pass = config['EMAIL']['EmailPass'] host = config['EMAIL']['Host'] +# Example: Creating notification providers based on configuration +providers = [] + +if 'NTFY' in config: + ntfy_urls = [config['NTFY'][url_key] for url_key in config['NTFY']] + providers.append(NTFYNotificationProvider(ntfy_urls)) + +# Initialize Notifier with providers +notifier = Notifier(providers) + + # Set a global timeout for all socket operations socket.setdefaulttimeout(600) # e.g., 600 seconds or 10 minutes @@ -260,7 +283,7 @@ try: time.sleep(30) # wait for 30 seconds before trying to reconnect except Exception as e: print(f"An unexpected error occurred: {str(e)}") - Notifier.send_notification("Script Error", f"An unexpected error occurred: {str(e)}") + notifier.send_notification("Script Error", f"An unexpected error occurred: {str(e)}") finally: print("Logging out and closing the connection...") try: diff --git a/config.ini b/config.ini index 3a5da79..51cb10a 100644 --- a/config.ini +++ b/config.ini @@ -3,8 +3,8 @@ EmailUser = your@address.com EmailPass = YourPassword Host = mail.server.com -[NTFY] -NtfyURL1 = https://ntfy.sh/YOUR_TOPIC1 -#NtfyURL2 = https://yourserver.sh/YOUR_TOPIC2 -#NtfyURL3 = https://otherserver.sh/YOUR_TOPIC3 +#If your provider is NTFY, uncomment the following lines +#[NTFY] +#Url1 = https://ntfy.sh/TOPIC1 +#Url2 = https://ntfy.sh/TOPIC2