diff --git a/NotiMail.py b/NotiMail.py index a2947b6..22f98b0 100755 --- a/NotiMail.py +++ b/NotiMail.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """ NotiMail -Version: 0.11 +Version: 0.12 Author: Stefano Marinelli License: BSD 3-Clause License @@ -80,6 +80,9 @@ from email.parser import BytesParser # Argument parsing to get the config file parser = argparse.ArgumentParser(description='NotiMail Notification Service.') parser.add_argument('-c', '--config', type=str, default='config.ini', help='Path to the configuration file.') +parser.add_argument('--print-config', action='store_true', help='Print the configuration options from config.ini') +parser.add_argument('--test-config', action='store_true', help='Test the configuration options to ensure they work properly') +parser.add_argument('--list-folders', action='store_true', help='List all IMAP folders of the configured mailboxes') args = parser.parse_args() # Configuration reading @@ -275,17 +278,18 @@ class Notifier: class IMAPHandler: - def __init__(self, host, email_user, email_pass): + def __init__(self, host, email_user, email_pass, folder="inbox"): self.host = host self.email_user = email_user self.email_pass = email_pass + self.folder = folder self.mail = None def connect(self): try: self.mail = imaplib.IMAP4_SSL(self.host, 993) self.mail.login(self.email_user, self.email_pass) - self.mail.select('inbox') + self.mail.select(self.folder) except imaplib.IMAP4.error as e: print(f"Cannot connect: {str(e)}") notifier.send_notification("Script Error", f"Cannot connect: {str(e)}") @@ -293,7 +297,7 @@ class IMAPHandler: def idle(self): print("IDLE mode started. Waiting for new email...") - logging.info(f"[{self.email_user}] IDLE mode started. Waiting for new email...") + logging.info(f"[{self.email_user} - {self.folder}] IDLE mode started. Waiting for new email...") try: tag = self.mail._new_tag().decode() self.mail.send(f'{tag} IDLE\r\n'.encode('utf-8')) @@ -333,7 +337,7 @@ class IMAPHandler: class MultiIMAPHandler: def __init__(self, accounts): self.accounts = accounts - self.handlers = [IMAPHandler(account['Host'], account['EmailUser'], account['EmailPass']) for account in accounts] + self.handlers = [IMAPHandler(account['Host'], account['EmailUser'], account['EmailPass'], account['Folder']) for account in accounts] def run(self): threads = [] @@ -349,8 +353,8 @@ class MultiIMAPHandler: @staticmethod def monitor_account(handler): - print(f"Monitoring {handler.email_user}") - logging.info(f"Monitoring {handler.email_user}") + print(f"Monitoring {handler.email_user} - Folder: {handler.folder}") + logging.info(f"Monitoring {handler.email_user} - Folder: {handler.folder}") while True: # Add a loop to keep retrying on connection loss try: handler.connect() @@ -393,12 +397,15 @@ def multi_account_main(): # Check for new format [EMAIL:accountX] for section in config.sections(): if section.startswith("EMAIL:"): - account = { - 'EmailUser': config[section]['EmailUser'], - 'EmailPass': config[section]['EmailPass'], - 'Host': config[section]['Host'] - } - accounts.append(account) + folders = config[section].get('Folders', 'inbox').split(', ') + for folder in folders: + account = { + 'EmailUser': config[section]['EmailUser'], + 'EmailPass': config[section]['EmailPass'], + 'Host': config[section]['Host'], + 'Folder': folder + } + accounts.append(account) providers = [] @@ -444,6 +451,97 @@ def multi_account_main(): except: pass -if __name__ == "__main__": - multi_account_main() +def print_config(): + """ + Function to print the configuration options from config.ini + """ + for section in config.sections(): + print(f"[{section}]") + for key, value in config[section].items(): + print(f"{key} = {value}") + print() + +def test_config(): + """ + Function to test the configuration options + """ + # Test Email accounts + for section in config.sections(): + if section.startswith("EMAIL:"): + print(f"Testing {section}...") + handler = IMAPHandler(config[section]['Host'], config[section]['EmailUser'], config[section]['EmailPass']) + try: + handler.connect() + print(f"Connection successful for {section}") + handler.mail.logout() # Explicitly logging out after testing + except Exception as e: + print(f"Connection failed for {section}. Reason: {str(e)}") + + # Testing NTFY Notification Provider + if 'NTFY' in config: + print("Testing NTFY Notification Provider...") + ntfy_data = [] + for key in config['NTFY']: + if key.startswith("url"): + url = config['NTFY'][key] + token_key = "token" + key[3:] + token = config['NTFY'].get(token_key, None) + ntfy_data.append((url, token)) + ntfy_provider = NTFYNotificationProvider(ntfy_data) + try: + ntfy_provider.send_notification("Test Sender", "Test Notification from NotiMail") + print("Test notification sent successfully via NTFY!") + except Exception as e: + print(f"Failed to send test notification via NTFY. Reason: {str(e)}") + + # Testing Pushover Notification Provider + if 'PUSHOVER' in config: + print("Testing Pushover Notification Provider...") + pushover_provider = PushoverNotificationProvider(config['PUSHOVER']['ApiToken'], config['PUSHOVER']['UserKey']) + try: + pushover_provider.send_notification("Test Sender", "Test Notification from NotiMail") + print("Test notification sent successfully via Pushover!") + except Exception as e: + print(f"Failed to send test notification via Pushover. Reason: {str(e)}") + + # Testing Gotify Notification Provider + if 'GOTIFY' in config: + print("Testing Gotify Notification Provider...") + gotify_provider = GotifyNotificationProvider(config['GOTIFY']['Url'], config['GOTIFY']['Token']) + try: + gotify_provider.send_notification("Test Sender", "Test Notification from NotiMail") + print("Test notification sent successfully via Gotify!") + except Exception as e: + print(f"Failed to send test notification via Gotify. Reason: {str(e)}") + + print("Testing done!") + + +def list_imap_folders(): + """ + Function to list all IMAP folders of the configured mailboxes + """ + for section in config.sections(): + if section.startswith("EMAIL:"): + print(f"Listing folders for {section}...") + handler = IMAPHandler(config[section]['Host'], config[section]['EmailUser'], config[section]['EmailPass']) + try: + handler.connect() + typ, folders = handler.mail.list() + for folder in folders: + print(folder.decode()) + handler.mail.logout() # Explicitly logging out after listing folders + except Exception as e: + print(f"Failed to list folders for {section}. Reason: {str(e)}") + + +if __name__ == "__main__": + if args.print_config: + print_config() + elif args.test_config: + test_config() + elif args.list_folders: + list_imap_folders() + else: + multi_account_main() diff --git a/README.md b/README.md index be2b168..5496cbd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # NotiMail 📧 -**Version 0.11 is here, read the changelog for more information!** +**Version 0.12 is here, read the changelog for more information!** **Development is ongoing, and the project is in the early alpha stage - things may break!** @@ -10,18 +10,19 @@ Mobile devices often use IMAP IDLE, maintaining a persistent connection to ensur ## Features 🌟 -- **Monitors Multiple Emails on the Server**: With version 0.9, NotiMail can now monitor multiple email accounts. Ensure you never miss an email regardless of which account it's sent to. - -- **Processes and Notifies**: Once a new email is detected, NotiMail swiftly processes its details. - -- **Leverages Multiple Push Providers for Alerts**: Rather than having your device always on alert, NotiMail sends notifications via multiple push providers, ensuring you're promptly informed. +- **Monitors Multiple Emails on the Server**: From version 0.9 onwards, NotiMail can monitor multiple email accounts. Ensure you never miss an email regardless of which account it's sent to. -- **Database Integration**: NotiMail uses an SQLite3 database to store and manage processed email UIDs, preventing repeated processing. - -- **Built for Resilience**: With connectivity hiccups in mind, NotiMail ensures you're always the first to know. +- **Monitors Multiple Folders per Account**: With version 0.12, you can configure NotiMail to monitor multiple folders for each email account. Whether it's your 'inbox', 'junk', or any other folder, stay informed with NotiMail. -- **Multiple And Different Push providers supported**: You can use one or more of the supported Push providers - all support authentication, which currently include ntfy, Gotify and Pushover. - +- **Processes and Notifies**: Once a new email is detected, NotiMail swiftly processes its details. + +- **Leverages Multiple Push Providers for Alerts**: Rather than having your device always on alert, NotiMail sends notifications via multiple push providers, ensuring you're promptly informed. + +- **Database Integration**: NotiMail uses an SQLite3 database to store and manage processed email UIDs, preventing repeated processing. + +- **Built for Resilience**: With connectivity hiccups in mind, NotiMail ensures you're always the first to know. + +- **Multiple And Different Push providers supported**: You can use one or more of the supported Push providers - all support authentication, which currently include ntfy, Gotify, and Pushover. ## Benefits 🚀 @@ -136,6 +137,21 @@ With that, you should have NotiMail up and running on your system! Enjoy a more ## Changelog +### Version 0.12 + +#### New Features: + +- **Multiple Folder Monitoring**: From this version onwards, NotiMail supports monitoring multiple folders for each configured email account. This allows users to, for example, monitor both the 'inbox' and 'junk' folders simultaneously. Each folder is treated as a separate connection, ensuring robust and comprehensive monitoring. +- **Configuration Validation**: Introduced command-line functions to validate the config.ini file. This ensures that your settings are correctly configured before you start the NotiMail service. +- **Notification Provider Testing**: You can now test the notification providers by sending a test notification to verify their correct setup and functioning. +- **IMAP Folder Listing**: Added a feature to list all IMAP folders of the configured mailboxes, providing better insights and facilitating precise folder monitoring. + +#### Changes: + +- **Configuration (`config.ini`)**: Introduced the ability to specify multiple folders for each email account using the `Folders` configuration key. If not specified, it defaults to the 'inbox' folder. +- **Logging Enhancements**: All logging and print statements now include the folder name, providing a clearer understanding of ongoing operations per folder. +- **Codebase**: Enhanced error handling, and improved logging to provide clearer insights into the application's operations. + ### Version 0.11 #### New Features: diff --git a/config.ini.sample b/config.ini.sample index 0fd6091..3ad682d 100644 --- a/config.ini.sample +++ b/config.ini.sample @@ -6,25 +6,27 @@ DataBaseLocation = /var/cache/notimail/processed_emails.db EmailUser = your@address.com EmailPass = YourPassword Host = mail.server.com +#Folders = inbox, sent #[EMAIL:account2] #EmailUser = your@address.com #EmailPass = YourPassword #Host = mail.server.com +#Folders = inbox, sent -#If your provider is NTFY, uncomment the following lines and configure +#If your provider is NTFY, uncomment the following lines and configure. If using NTFY, also uncomment the [NTFY] line #[NTFY] #Url1 = https://ntfy.sh/TOPIC1 #Token1 = Optional token to send notifications to protected topics #Url2 = https://ntfy.sh/TOPIC2 #Token2 = Optional token to send notifications to protected topics -#If your provider is PUSHOVER, uncomment the following lines and configure +#If your provider is PUSHOVER, uncomment the following lines and configure. If using PUSHOVER, also uncomment the [PUSHOVER] line #[PUSHOVER] #ApiToken = YOUR_PUSHOVER_API_TOKEN #UserKey = YOUR_PUSHOVER_USER_KEY -#If your provider is GOTIFY, uncomment the following lines and configure +#If your provider is GOTIFY, uncomment the following lines and configure. If using GOTIFY, also uncomment the [GOTIFY] line #[GOTIFY] #Url = https://gotify.example.com/message #Token = your_gotify_token diff --git a/man/notimail.1 b/man/notimail.1 index 2d0bb7f..614c7b8 100644 --- a/man/notimail.1 +++ b/man/notimail.1 @@ -1,28 +1,44 @@ .\" Man page for NotiMail -.TH MAN 1 "23 October 2023" +.TH MAN 1 "24 October 2023" .SH NAME -NotiMail \- Monitor email inbox(es) and send HTTP POST notifications upon new email arrivals. +NotiMail \- Monitor email inbox(es) and send notifications upon new email arrivals using various providers. .SH SYNOPSIS .B notimail [\fB-c\fR \fICONFIG\fR] +[\fB--check-config\fR] +[\fB--test-config\fR] +[\fB--list-folders\fR] .SH DESCRIPTION -NotiMail is a script designed to monitor one or more email inbox(es) using the IMAP IDLE feature and send notifications via HTTP POST requests when a new email arrives. The script can connect to multiple email servers and send notifications to different platforms, including NTFY, Pushover, and Gotify. +NotiMail is a script designed to monitor one or more email inboxes using the IMAP IDLE feature. It sends notifications when a new email arrives. The script can connect to multiple email servers and send notifications to different platforms, including NTFY, Pushover, and Gotify. .P Key features: .RS .IP "*" Monitors one or more email inboxes using IMAP IDLE. .IP "*" +Supports monitoring of multiple folders per email account. +.IP "*" Sends notifications containing the sender and subject of new emails. .IP "*" Maintains a SQLite database to ensure that emails are not processed repeatedly. .IP "*" Supports multiple notification providers: NTFY, Pushover, and Gotify. +.IP "*" +Provides command-line functionalities to validate, test, and list IMAP folders. .RE .SH OPTIONS .TP \fB-c\fR, \fB--config\fR \fICONFIG\fR Specify the path to the configuration file. Defaults to \fIconfig.ini\fR. +.TP +\fB--check-config\fR +Check and print the configurations set in the `config.ini` file. +.TP +\fB--test-config\fR +Test if the configurations set in the `config.ini` file are working properly. +.TP +\fB--list-folders\fR +List all the IMAP folders of the configured mailboxes. .SH CONFIGURATION Configuration data is read from a file named \fIconfig.ini\fR. Ensure it's correctly set up before running the script. The configuration file has multiple sections: .P @@ -40,6 +56,8 @@ The email address. The password for the email address. .IP Host: The email server. +.IP Folders: +A comma-separated list of folders to monitor. .IP "[NTFY]:" Configuration for the NTFY notification provider. .IP UrlX: @@ -98,10 +116,24 @@ notimail .IP "" notimail \-c /path/to/custom_config.ini .RE +3. Checking the current configuration: +.RS +.IP "" +notimail --check-config +.RE +4. Testing the configuration settings: +.RS +.IP "" +notimail --test-config +.RE +5. Listing IMAP folders of the configured mailboxes: +.RS +.IP "" +notimail --list-folders +.RE .SH AUTHOR Stefano Marinelli .SH LICENSE BSD 3-Clause License. See the source distribution for details. .SH SEE ALSO IMAP IDLE, SQLite3, NTFY, Pushover, Gotify. -