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)