Refactoring the code to make it easy to implement other notification providers.

This commit is contained in:
Stefano Marinelli 2023-10-13 08:46:01 +02:00
parent 483b169577
commit e4b35dfe31
2 changed files with 39 additions and 16 deletions

View file

@ -134,25 +134,28 @@ class EmailProcessor:
print('Subject:', email_message.get('Subject')) print('Subject:', email_message.get('Subject'))
print('Body:', email_message.get_payload()) print('Body:', email_message.get_payload())
print('------') 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 # Add UID to database to ensure it is not processed in future runs
self.db_handler.add_email(uid, 1) self.db_handler.add_email(uid, 1)
# Delete entries older than 7 days # Delete entries older than 7 days
self.db_handler.delete_old_emails() self.db_handler.delete_old_emails()
class Notifier: class NotificationProvider:
@staticmethod def send_notification(self, mail_from, mail_subject):
def send_notification(mail_from, mail_subject): raise NotImplementedError("Subclasses must implement this method")
# Check if mail_subject and mail_from are None and replace them with default strings
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_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" 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_subject = mail_subject.encode('latin-1', errors='replace').decode('latin-1')
sanitized_from = mail_from.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 ntfy_url in self.ntfy_urls:
for key, ntfy_url in config['NTFY'].items():
try: try:
response = requests.post( response = requests.post(
ntfy_url, ntfy_url,
@ -169,6 +172,15 @@ class Notifier:
time.sleep(5) # Ensure a delay between notifications 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: class IMAPHandler:
def __init__(self, host, email_user, email_pass): def __init__(self, host, email_user, email_pass):
self.host = host self.host = host
@ -183,7 +195,7 @@ class IMAPHandler:
self.mail.select('inbox') self.mail.select('inbox')
except imaplib.IMAP4.error as e: except imaplib.IMAP4.error as e:
print(f"Cannot connect: {str(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 raise
def idle(self): def idle(self):
@ -202,14 +214,14 @@ class IMAPHandler:
self.mail.readline() self.mail.readline()
except imaplib.IMAP4.abort as e: except imaplib.IMAP4.abort as e:
print(f"Connection closed by server: {str(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...") raise ConnectionAbortedError("Connection lost. Trying to reconnect...")
except socket.timeout: except socket.timeout:
print("Socket timeout during IDLE, re-establishing connection...") print("Socket timeout during IDLE, re-establishing connection...")
raise ConnectionAbortedError("Socket timeout. Trying to reconnect...") raise ConnectionAbortedError("Socket timeout. Trying to reconnect...")
except Exception as e: except Exception as e:
print(f"An error occurred: {str(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 raise
finally: finally:
print("IDLE mode stopped.") print("IDLE mode stopped.")
@ -227,6 +239,17 @@ email_user = config['EMAIL']['EmailUser']
email_pass = config['EMAIL']['EmailPass'] email_pass = config['EMAIL']['EmailPass']
host = config['EMAIL']['Host'] 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 # Set a global timeout for all socket operations
socket.setdefaulttimeout(600) # e.g., 600 seconds or 10 minutes 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 time.sleep(30) # wait for 30 seconds before trying to reconnect
except Exception as e: except Exception as e:
print(f"An unexpected error occurred: {str(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: finally:
print("Logging out and closing the connection...") print("Logging out and closing the connection...")
try: try:

View file

@ -3,8 +3,8 @@ EmailUser = your@address.com
EmailPass = YourPassword EmailPass = YourPassword
Host = mail.server.com Host = mail.server.com
[NTFY] #If your provider is NTFY, uncomment the following lines
NtfyURL1 = https://ntfy.sh/YOUR_TOPIC1 #[NTFY]
#NtfyURL2 = https://yourserver.sh/YOUR_TOPIC2 #Url1 = https://ntfy.sh/TOPIC1
#NtfyURL3 = https://otherserver.sh/YOUR_TOPIC3 #Url2 = https://ntfy.sh/TOPIC2