diff --git a/front/plugins/_publisher_apprise/README.md b/front/plugins/_publisher_apprise/README.md new file mode 100755 index 00000000..e32cc3f2 --- /dev/null +++ b/front/plugins/_publisher_apprise/README.md @@ -0,0 +1,8 @@ +## Overview + +[Apprise](front/plugins/arp_scan/README.md) is a notification gateway/publisher that allows you to push notifications to 80+ different services. + +### Usage + +- Go to settings and fill in relevant details. + diff --git a/front/plugins/_publisher_apprise/apprise.py b/front/plugins/_publisher_apprise/apprise.py index 27b23fc8..08f7ebd9 100755 --- a/front/plugins/_publisher_apprise/apprise.py +++ b/front/plugins/_publisher_apprise/apprise.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# Based on the work of https://github.com/leiweibau/Pi.Alert import json import subprocess @@ -23,13 +22,15 @@ from database import DB CUR_PATH = str(pathlib.Path(__file__).parent.resolve()) RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log') +pluginName = 'APPRISE' + def main(): - mylog('verbose', ['[APPRISE](publisher) In script']) + mylog('verbose', [f'[{pluginName}](publisher) In script']) # Check if basic config settings supplied if check_config() == False: - mylog('none', ['[Check Config] Error: Apprise service not set up correctly. Check your pialert.conf APPRISE_* variables.']) + mylog('none', [f'[{pluginName}] Error: Publisher notification gateway not set up correctly. Check your pialert.conf {pluginName}_* variables.']) return # Create a database connection @@ -53,7 +54,7 @@ def main(): # Log result plugin_objects.add_object( - primaryId = 'APPRISE', + primaryId = pluginName, secondaryId = timeNowTZ(), watched1 = notification["GUID"], watched2 = result, diff --git a/front/plugins/_publisher_email/README.md b/front/plugins/_publisher_email/README.md new file mode 100755 index 00000000..e32cc3f2 --- /dev/null +++ b/front/plugins/_publisher_email/README.md @@ -0,0 +1,8 @@ +## Overview + +[Apprise](front/plugins/arp_scan/README.md) is a notification gateway/publisher that allows you to push notifications to 80+ different services. + +### Usage + +- Go to settings and fill in relevant details. + diff --git a/front/plugins/_publisher_email/config.json b/front/plugins/_publisher_email/config.json new file mode 100755 index 00000000..d073f963 --- /dev/null +++ b/front/plugins/_publisher_email/config.json @@ -0,0 +1,424 @@ +{ + "code_name": "_publisher_apprise", + "unique_prefix": "SMTP", + "enabled": true, + "data_source": "script", + "show_ui": true, + "localized": ["display_name", "description", "icon"], + "display_name" : [ + { + "language_code": "en_us", + "string" : "Apprise publisher" + }, + { + "language_code": "es_es", + "string" : "Habilitar Apprise" + } + ], + "icon":[{ + "language_code": "en_us", + "string" : "" + }], + "description": [ + { + "language_code": "en_us", + "string" : "A plugin to publish a notification via the Apprise gateway." + } + ], + "params" : [], + "database_column_definitions": + [ + { + "column": "Index", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code": "en_us", + "string" : "N/A" + }, + { + "language_code": "es_es", + "string" : "N/A" + }] + }, + { + "column": "Plugin", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code": "en_us", + "string" : "N/A" + }, + { + "language_code": "es_es", + "string" : "N/A" + }] + }, + { + "column": "Object_PrimaryID", + "css_classes": "col-sm-2", + "show": false, + "type": "url", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code": "en_us", + "string" : "N/A" + }] + }, + { + "column": "Object_SecondaryID", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code": "en_us", + "string" : "N/A" + }, + { + "language_code": "es_es", + "string" : "N/A" + }] + }, + { + "column": "DateTimeCreated", + "css_classes": "col-sm-2", + "show": true, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code": "en_us", + "string" : "Sent when" + }] + }, + { + "column": "DateTimeChanged", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code": "en_us", + "string" : "Changed" + }, + { + "language_code": "es_es", + "string" : "Cambiado" + }] + }, + { + "column": "Watched_Value1", + "css_classes": "col-sm-2", + "show": true, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code": "en_us", + "string" : "Notification GUID" + }] + }, + { + "column": "Watched_Value2", + "css_classes": "col-sm-8", + "show": true, + "type": "textarea_readonly", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code": "en_us", + "string" : "Result" + }] + }, + { + "column": "Watched_Value3", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code": "en_us", + "string" : "N/A" + }, + { + "language_code": "es_es", + "string" : "N/A" + }] + }, + { + "column": "Watched_Value4", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code": "en_us", + "string" : "N/A" + }, + { + "language_code": "es_es", + "string" : "N/A" + }] + }, + { + "column": "UserData", + "css_classes": "col-sm-2", + "show": false, + "type": "textbox_save", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code": "en_us", + "string" : "Comments" + }, + { + "language_code": "es_es", + "string" : "Comentarios" + }] + }, + { + "column": "Status", + "css_classes": "col-sm-1", + "show": false, + "type": "replace", + "default_value":"", + "options": [ + { + "equals": "watched-not-changed", + "replacement": "
http:// or https://. (do not forget to include /notify at the end)"
+ },
+ {
+ "language_code": "es_es",
+ "string" : "URL del host de Apprise que comienza con http:// o https://. (no olvide incluir /notify al final)"
+ }]
+ },
+ {
+ "function": "URL",
+ "type": "text",
+ "default_value": "",
+ "options": [],
+ "localized": ["name", "description"],
+ "name" : [{
+ "language_code": "en_us",
+ "string" : "Apprise notification URL"
+ },
+ {
+ "language_code": "es_es",
+ "string" : "URL de notificación de Apprise"
+ }],
+ "description": [{
+ "language_code": "en_us",
+ "string" : "Apprise notification target URL. For example for Telegram it would be tgram://{bot_token}/{chat_id}."
+ },
+ {
+ "language_code": "es_es",
+ "string" : "Informar de la URL de destino de la notificación. Por ejemplo, para Telegram sería tgram://{bot_token}/{chat_id}."
+ }]
+ },
+ {
+ "function": "PAYLOAD",
+ "type": "text.select",
+ "default_value": "html",
+ "options": ["html", "text"],
+ "localized": ["name", "description"],
+ "name" : [{
+ "language_code": "en_us",
+ "string" : "Payload type"
+ },
+ {
+ "language_code": "es_es",
+ "string" : "Tipo de carga"
+ }],
+ "description": [{
+ "language_code": "en_us",
+ "string" : "Select the payoad type sent to Apprise. For example html works well with emails, text with chat apps, such as Telegram."
+ },
+ {
+ "language_code": "es_es",
+ "string" : "Seleccione el tipo de carga útil enviada a Apprise. Por ejemplo, html funciona bien con correos electrónicos, text con aplicaciones de chat, como Telegram."
+ }]
+ },
+ {
+ "function": "SIZE",
+ "type": "integer",
+ "default_value": 1024,
+ "options": [],
+ "localized": ["name", "description"],
+ "name" : [{
+ "language_code": "en_us",
+ "string" : "Max payload size"
+ },
+ {
+ "language_code": "es_es",
+ "string" : "Tamaño máximo de carga útil"
+ }],
+ "description": [{
+ "language_code": "en_us",
+ "string" : "The maximum size of the apprise payload as number of characters in the passed string. If above limit, it will be truncated and a (text was truncated) message is appended."
+ },
+ {
+ "language_code": "es_es",
+ "string" : "El tamaño máximo de la carga útil de información como número de caracteres en la cadena pasada. Si supera el límite, se truncará y se agregará un mensaje (text was truncated)."
+ }]
+ }
+ ]
+}
diff --git a/front/plugins/_publisher_email/email.py b/front/plugins/_publisher_email/email.py
new file mode 100755
index 00000000..25f1d638
--- /dev/null
+++ b/front/plugins/_publisher_email/email.py
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+import json
+import subprocess
+import argparse
+import os
+import pathlib
+import sys
+from datetime import datetime
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+import smtplib
+import socket
+
+# Replace these paths with the actual paths to your Pi.Alert directories
+sys.path.extend(["/home/pi/pialert/front/plugins", "/home/pi/pialert/pialert"])
+
+# PiAlert modules
+import conf
+from plugin_helper import Plugin_Objects
+from logger import mylog, append_line_to_file, print_log
+from helper import timeNowTZ, noti_obj, get_setting_value, hide_email
+from notification import Notification_obj
+from database import DB
+
+
+CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
+RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log')
+
+pluginName = 'SMTP'
+
+def main():
+
+ mylog('verbose', [f'[{pluginName}](publisher) In script'])
+
+ # Check if basic config settings supplied
+ if check_config() == False:
+ mylog('none', [f'[{pluginName}] Error: Publisher notification gateway not set up correctly. Check your pialert.conf {pluginName}_* variables.'])
+ return
+
+ # Create a database connection
+ db = DB() # instance of class DB
+ db.open()
+
+ # Initialize the Plugin obj output file
+ plugin_objects = Plugin_Objects(RESULT_FILE)
+
+ # Create a Notification_obj instance
+ notifications = Notification_obj(db)
+
+ # Retrieve new notifications
+ new_notifications = notifications.getNew()
+
+ # Process the new notifications
+ for notification in new_notifications:
+
+ # Send notification
+ result = send(notification["HTML"], notification["Text"])
+
+ # Log result
+ plugin_objects.add_object(
+ primaryId = pluginName,
+ secondaryId = timeNowTZ(),
+ watched1 = notification["GUID"],
+ watched2 = result,
+ watched3 = 'null',
+ watched4 = 'null',
+ extra = 'null',
+ foreignKey = 'null'
+ )
+
+ plugin_objects.write_result_file()
+
+#-------------------------------------------------------------------------------
+def check_config ():
+ if get_setting_value('SMTP_SERVER') == '' or get_setting_value('REPORT_FROM') == '' or get_setting_value('REPORT_TO') == '':
+ mylog('none', ['[Email Check Config] Error: Email service not set up correctly. Check your pialert.conf SMTP_*, REPORT_FROM and REPORT_TO variables.'])
+ return False
+ else:
+ return True
+
+#-------------------------------------------------------------------------------
+def send(pHTML, pText):
+
+ mylog('debug', [f'[{pluginName}] REPORT_TO: {hide_email(str(get_setting_value('REPORT_TO')))} SMTP_USER: {hide_email(str(get_setting_value('SMTP_USER')))}'])
+
+ # Compose email
+ msg = MIMEMultipart('alternative')
+ msg['Subject'] = 'Pi.Alert Report'
+ msg['From'] = get_setting_value('REPORT_FROM')
+ msg['To'] = get_setting_value('REPORT_TO')
+ msg.attach (MIMEText (pText, 'plain'))
+ msg.attach (MIMEText (pHTML, 'html'))
+
+ failedAt = ''
+
+ failedAt = print_log ('SMTP try')
+
+ try:
+ # Send mail
+ failedAt = print_log('Trying to open connection to ' + str(get_setting_value('SMTP_SERVER')) + ':' + str(get_setting_value('SMTP_PORT')))
+
+ # Set a timeout for the SMTP connection (in seconds)
+ smtp_timeout = 30
+
+ if get_setting_value('SMTP_FORCE_SSL'):
+ failedAt = print_log('SMTP_FORCE_SSL == True so using .SMTP_SSL()')
+ if get_setting_value('SMTP_PORT') == 0:
+ failedAt = print_log('SMTP_PORT == 0 so sending .SMTP_SSL(SMTP_SERVER)')
+ smtp_connection = smtplib.SMTP_SSL(get_setting_value('SMTP_SERVER'))
+ else:
+ failedAt = print_log('SMTP_PORT == 0 so sending .SMTP_SSL(SMTP_SERVER, SMTP_PORT)')
+ smtp_connection = smtplib.SMTP_SSL(get_setting_value('SMTP_SERVER'), get_setting_value('SMTP_PORT'), timeout=smtp_timeout)
+
+ else:
+ failedAt = print_log('SMTP_FORCE_SSL == False so using .SMTP()')
+ if get_setting_value('SMTP_PORT') == 0:
+ failedAt = print_log('SMTP_PORT == 0 so sending .SMTP(SMTP_SERVER)')
+ smtp_connection = smtplib.SMTP (get_setting_value('SMTP_SERVER'))
+ else:
+ failedAt = print_log('SMTP_PORT == 0 so sending .SMTP(SMTP_SERVER, SMTP_PORT)')
+ smtp_connection = smtplib.SMTP (get_setting_value('SMTP_SERVER'), get_setting_value('SMTP_PORT'))
+
+ failedAt = print_log('Setting SMTP debug level')
+
+ # Log level set to debug of the communication between SMTP server and client
+ if get_setting_value('LOG_LEVEL') == 'debug':
+ smtp_connection.set_debuglevel(1)
+
+ failedAt = print_log( 'Sending .ehlo()')
+ smtp_connection.ehlo()
+
+ if not get_setting_value('SMTP_SKIP_TLS'):
+ failedAt = print_log('SMTP_SKIP_TLS == False so sending .starttls()')
+ smtp_connection.starttls()
+ failedAt = print_log('SMTP_SKIP_TLS == False so sending .ehlo()')
+ smtp_connection.ehlo()
+ if not get_setting_value('SMTP_SKIP_LOGIN'):
+ failedAt = print_log('SMTP_SKIP_LOGIN') == False so sending .login()')
+ smtp_connection.login (get_setting_value('SMTP_USER'), get_setting_value('SMTP_PASS'))
+
+ failedAt = print_log('Sending .sendmail()')
+ smtp_connection.sendmail (get_setting_value('REPORT_FROM'), get_setting_value('REPORT_TO'), msg.as_string())
+ smtp_connection.quit()
+ except smtplib.SMTPAuthenticationError as e:
+ mylog('none', [' ERROR: Failed at - ', failedAt])
+ mylog('none', [' ERROR: Couldn\'t connect to the SMTP server (SMTPAuthenticationError), skipping Email (enable LOG_LEVEL=debug for more logging)'])
+ mylog('none', [' ERROR: ', str(e)])
+ except smtplib.SMTPServerDisconnected as e:
+ mylog('none', [' ERROR: Failed at - ', failedAt])
+ mylog('none', [' ERROR: Couldn\'t connect to the SMTP server (SMTPServerDisconnected), skipping Email (enable LOG_LEVEL=debug for more logging)'])
+ mylog('none', [' ERROR: ', str(e)])
+ except socket.gaierror as e:
+ mylog('none', [' ERROR: Failed at - ', failedAt])
+ mylog('none', [' ERROR: Could not resolve hostname (socket.gaierror), skipping Email (enable LOG_LEVEL=debug for more logging)'])
+ mylog('none', [' ERROR: ', str(e)])
+
+ mylog('debug', [f'[{pluginName}] Last executed - {str(failedAt)}'])
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/front/plugins/internet_speedtest/script.py b/front/plugins/internet_speedtest/script.py
index 10b65cc0..8acadaba 100755
--- a/front/plugins/internet_speedtest/script.py
+++ b/front/plugins/internet_speedtest/script.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python
-# Based on the work of https://github.com/leiweibau/Pi.Alert
import argparse
import os