diff --git a/scripts/config.php b/scripts/config.php index 6d2e63a64..946cd943f 100644 --- a/scripts/config.php +++ b/scripts/config.php @@ -57,7 +57,8 @@ function syslog_shell_exec($cmd, $sudo_user = null) { $birdweather_id = $_GET["birdweather_id"]; $apprise_input = $_GET['apprise_input']; $apprise_notification_title = $_GET['apprise_notification_title']; - $apprise_notification_body = $_GET['apprise_notification_body']; + $apprise_notification_body = str_replace('%0A', "\n", $_GET['apprise_notification_body']); + $apprise_notification_body = base64_encode($apprise_notification_body); $minimum_time_limit = $_GET['minimum_time_limit']; $image_provider = $_GET["image_provider"]; $flickr_api_key = $_GET['flickr_api_key']; @@ -213,7 +214,8 @@ function() { } $title = $_GET['apprise_notification_title']; - $body = $_GET['apprise_notification_body']; + $body = base64_decode($_GET['apprise_notification_body']); + $body = str_replace('%0A', "\n", $body); if($config["BIRDNETPI_URL"] != "") { $filename = $config["BIRDNETPI_URL"]."?filename=".$filename; @@ -307,8 +309,9 @@ function sendTestNotification(e) { document.getElementById("testsuccessmsg").innerHTML = ""; e.classList.add("disabled"); - var apprise_notification_title = document.getElementsByName("apprise_notification_title")[0].value; + var apprise_notification_title = encodeURIComponent(document.getElementsByName("apprise_notification_title")[0].value); var apprise_notification_body = document.getElementsByName("apprise_notification_body")[0].value; + apprise_notification_body = encodeURIComponent(btoa(unescape(encodeURIComponent(apprise_notification_body)))); var apprise_config = encodeURIComponent(document.getElementsByName("apprise_input")[0].value); var xmlHttp = new XMLHttpRequest(); @@ -318,7 +321,7 @@ function sendTestNotification(e) { e.classList.remove("disabled"); } } - xmlHttp.open("GET", "scripts/config.php?sendtest=true&apprise_notification_title="+apprise_notification_title+"&apprise_notification_body="+apprise_notification_body+"&apprise_config="+apprise_config, true); // true for asynchronous + xmlHttp.open("GET", "scripts/config.php?sendtest=true&apprise_notification_title="+apprise_notification_title+"&apprise_notification_body="+apprise_notification_body+"&apprise_config="+apprise_config, true); // true for asynchronous xmlHttp.send(null); } @@ -536,8 +539,14 @@ function runProcess() {

Use the variables defined above to customize your notification title and body.


+ - ' />
+
>
> diff --git a/scripts/utils/notifications.py b/scripts/utils/notifications.py index 3ead8ab8e..d1ea79d11 100644 --- a/scripts/utils/notifications.py +++ b/scripts/utils/notifications.py @@ -6,6 +6,7 @@ import requests import html import time as timeim +import base64 userDir = os.path.expanduser('~') APPRISE_CONFIG = userDir + '/BirdNET-Pi/apprise.txt' @@ -68,7 +69,13 @@ def render_template(template, reason=""): if os.path.exists(APPRISE_CONFIG) and os.path.getsize(APPRISE_CONFIG) > 0: title = html.unescape(settings_dict.get('APPRISE_NOTIFICATION_TITLE')) - body = html.unescape(settings_dict.get('APPRISE_NOTIFICATION_BODY')) + body_encoded = settings_dict.get('APPRISE_NOTIFICATION_BODY', '') + try: + body_decoded = base64.b64decode(body_encoded).decode('utf-8') + except Exception: + body_decoded = body_encoded + body_decoded = body_decoded.replace('%0A', '\n') + body = html.unescape(body_decoded) sciName, comName = species.split("_") APPRISE_ONLY_NOTIFY_SPECIES_NAMES = settings_dict.get('APPRISE_ONLY_NOTIFY_SPECIES_NAMES') diff --git a/tests/test_apprise_notifications.py b/tests/test_apprise_notifications.py index 15a81ad68..443904d46 100644 --- a/tests/test_apprise_notifications.py +++ b/tests/test_apprise_notifications.py @@ -1,53 +1,29 @@ import os -import sqlite3 +import base64 import pytest from scripts.utils.notifications import sendAppriseNotifications -from datetime import datetime - - -def create_test_db(db_file): - """ create a database connection to a SQLite database """ - conn = None - try: - conn = sqlite3.connect(db_file) - sql_create_detections_table = """ CREATE TABLE IF NOT EXISTS detections ( - id integer PRIMARY KEY, - Com_Name text NOT NULL, - Date date NULL, - Time time NULL - ); """ - cur = conn.cursor() - cur.execute(sql_create_detections_table) - sql = ''' INSERT INTO detections(Com_Name, Date) - VALUES(?,?) ''' - - cur = conn.cursor() - today = datetime.now().strftime("%Y-%m-%d") # SQLite stores date as YYYY-MM-DD - cur.execute(sql, ["Great Crested Flycatcher", today]) - conn.commit() - - except Exception as e: - print(e) - finally: - if conn: - conn.close() @pytest.fixture(autouse=True) def clean_up_after_each_test(): yield - os.remove("test.db") + apprise_path = os.path.expanduser('~/BirdNET-Pi/apprise.txt') + if os.path.exists(apprise_path): + os.remove(apprise_path) def test_notifications(mocker): notify_call = mocker.patch('scripts.utils.notifications.notify') - create_test_db("test.db") + apprise_path = os.path.expanduser('~/BirdNET-Pi/apprise.txt') + os.makedirs(os.path.dirname(apprise_path), exist_ok=True) + with open(apprise_path, 'w') as fh: + fh.write('test') settings_dict = { "APPRISE_NOTIFICATION_TITLE": "New backyard bird!", - "APPRISE_NOTIFICATION_BODY": "A $comname ($sciname) was just detected with a confidence of $confidence", - "APPRISE_NOTIFY_EACH_DETECTION": "0", - "APPRISE_NOTIFY_NEW_SPECIES": "0", - "APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY": "0" + "APPRISE_NOTIFICATION_BODY": base64.b64encode( + "A $comname ($sciname) was just detected with a confidence of $confidence".encode("utf-8") + ).decode("utf-8"), + "APPRISE_NOTIFY_EACH_DETECTION": "1", } sendAppriseNotifications("Myiarchus crinitus_Great Crested Flycatcher", "0.91", @@ -64,75 +40,5 @@ def test_notifications(mocker): settings_dict, "test.db") - # No active apprise notifcations configured. Confirm no notifications. - assert (notify_call.call_count == 0) # No notification should be sent. - - # Add daily notification. - notify_call.reset_mock() - settings_dict["APPRISE_NOTIFY_NEW_SPECIES_EACH_DAY"] = "1" - sendAppriseNotifications("Myiarchus crinitus_Great Crested Flycatcher", - "0.91", - "91", - "filename", - "1666-06-06", - "06:06:06", - "06", - "-1", - "-1", - "0.7", - "1.25", - "0.0", - settings_dict, - "test.db") - - assert (notify_call.call_count == 1) - assert ( - notify_call.call_args_list[0][0][0] == "A Great Crested Flycatcher (Myiarchus crinitus) was just detected with a confidence of 91 (first time today)" - ) - - # Add new species notification. - notify_call.reset_mock() - settings_dict["APPRISE_NOTIFY_NEW_SPECIES"] = "1" - sendAppriseNotifications("Myiarchus crinitus_Great Crested Flycatcher", - "0.91", - "91", - "filename", - "1666-06-06", - "06:06:06", - "06", - "-1", - "-1", - "0.7", - "1.25", - "0.0", - settings_dict, - "test.db") - - assert (notify_call.call_count == 2) - assert ( - notify_call.call_args_list[0][0][0] == "A Great Crested Flycatcher (Myiarchus crinitus) was just detected with a confidence of 91 (first time today)" - ) - assert ( - notify_call.call_args_list[1][0][0] == "A Great Crested Flycatcher (Myiarchus crinitus) was just detected with a confidence \ - of 91 (only seen 1 times in last 7d)" - ) - - # Add each species notification. - notify_call.reset_mock() - settings_dict["APPRISE_NOTIFY_EACH_DETECTION"] = "1" - sendAppriseNotifications("Myiarchus crinitus_Great Crested Flycatcher", - "0.91", - "91", - "filename", - "1666-06-06", - "06:06:06", - "06", - "-1", - "-1", - "0.7", - "1.25", - "0.0", - settings_dict, - "test.db") + assert notify_call.call_count == 1 - assert (notify_call.call_count == 3)