diff --git a/front/plugins/README.md b/front/plugins/README.md
index 69bf683a..53353fdc 100755
--- a/front/plugins/README.md
+++ b/front/plugins/README.md
@@ -542,8 +542,8 @@ Required attributes are:
| `"name"` | Displayed on the Settings page. An array of localized strings. See Localized strings below. |
| `"description"` | Displayed on the Settings page. An array of localized strings. See Localized strings below. |
| (optional) `"events"` | Specifies whether to generate an execution button next to the input field of the setting. Supported values: |
-| | - `test` |
-| | - `run` |
+| | - `"test"` - For notification plugins testing |
+| | - `"run"` - Regular plugins testing |
| (optional) `"override_value"` | Used to determine a user-defined override for the setting. Useful for template-based plugins, where you can choose to leave the current value or override it with the value defined in the setting. (Work in progress) |
| (optional) `"events"` | Used to trigger the plugin. Usually used on the `RUN` setting. Not fully tested in all scenarios. Will show a play button next to the setting. After clicking, an event is generated for the backend in the `Parameters` database table to process the front-end event on the next run. |
diff --git a/front/plugins/_publisher_apprise/apprise.py b/front/plugins/_publisher_apprise/apprise.py
index 85a61f38..2feb151f 100755
--- a/front/plugins/_publisher_apprise/apprise.py
+++ b/front/plugins/_publisher_apprise/apprise.py
@@ -43,7 +43,7 @@ def main():
plugin_objects = Plugin_Objects(RESULT_FILE)
# Create a Notification_obj instance
- Notification_obj(db)
+ notifications = Notification_obj(db)
# Retrieve new notifications
new_notifications = notifications.getNew()
@@ -86,15 +86,15 @@ def send(html, text):
# truncate size
if get_setting_value('APPRISE_PAYLOAD') == 'html':
- if len(msg.html) > limit:
- payloadData = msg.html[:limit] + "
(text was truncated)
"
+ if len(html) > limit:
+ payloadData = html[:limit] + "(text was truncated)
"
else:
- payloadData = msg.html
+ payloadData = html
if get_setting_value('APPRISE_PAYLOAD') == 'text':
- if len(msg.text) > limit:
- payloadData = msg.text[:limit] + " (text was truncated)"
+ if len(text) > limit:
+ payloadData = text[:limit] + " (text was truncated)"
else:
- payloadData = msg.text
+ payloadData = text
# Define Apprise compatible payload (https://github.com/caronc/apprise-api#stateless-solution)
diff --git a/front/plugins/_publisher_apprise/config.json b/front/plugins/_publisher_apprise/config.json
index 7443919a..1d890b7c 100755
--- a/front/plugins/_publisher_apprise/config.json
+++ b/front/plugins/_publisher_apprise/config.json
@@ -254,7 +254,7 @@
"settings":[
{
"function": "RUN",
- "events": ["run"],
+ "events": ["test"],
"type": "text.select",
"default_value":"disabled",
"options": ["disabled", "on_notification" ],
diff --git a/pialert/helper.py b/pialert/helper.py
index 1207ec92..19e1aabe 100755
--- a/pialert/helper.py
+++ b/pialert/helper.py
@@ -243,18 +243,32 @@ def write_file(pPath, pText):
#-------------------------------------------------------------------------------
# Return whole setting touple
def get_setting(key):
- result = None
- # index order: key, name, desc, inputtype, options, regex, result, group, events
- for set in conf.mySettings:
- if set[0] == key:
- result = set
-
- if result is None:
- mylog('minimal', [' Error - setting_missing - Setting not found for key: ', key])
- mylog('minimal', [' Error - logging the settings into file: ', logPath + '/setting_missing.json'])
- write_file (logPath + '/setting_missing.json', json.dumps({ 'data' : conf.mySettings}))
- return result
+ settingsFile = apiPath + '/table_settings.json'
+
+ try:
+ with open(settingsFile, 'r') as json_file:
+
+ data = json.load(json_file)
+
+ # if not isinstance(data, list):
+ # mylog('minimal', [f' [Settings] Data is not a list of dictionaries (file: {settingsFile})'])
+
+ for item in data.get("data",[]):
+ if item.get("Code_Name") == key:
+ return item
+
+ mylog('minimal', [f'[Settings] Error - setting_missing - Setting not found for key: {key} in file {settingsFile}'])
+
+ return None
+
+ except (FileNotFoundError, json.JSONDecodeError, ValueError) as e:
+ # Handle the case when the file is not found, JSON decoding fails, or data is not in the expected format
+ mylog('minimal', [f'[Settings] Error - JSONDecodeError or FileNotFoundError for file {settingsFile}'])
+
+ return None
+
+
#-------------------------------------------------------------------------------
# Return setting value
@@ -264,8 +278,8 @@ def get_setting_value(key):
if get_setting(key) is not None:
- setVal = set[6] # setting value
- setTyp = set[3] # setting type
+ setVal = set["Value"] # setting value
+ setTyp = set["Type"] # setting type
return setVal
diff --git a/pialert/plugin.py b/pialert/plugin.py
index 70557dcd..5e77e61a 100755
--- a/pialert/plugin.py
+++ b/pialert/plugin.py
@@ -13,7 +13,7 @@ from const import pluginsPath, logPath
from logger import mylog
from helper import timeNowTZ, updateState, get_file_content, write_file, get_setting, get_setting_value
from api import update_api
-from plugin_utils import logEventStatusCounts, get_plugin_string, get_plugin_setting, print_plugin_info, flatten_array, combine_plugin_objects, resolve_wildcards_arr, get_plugin_setting_value, handle_empty, custom_plugin_decoder
+from plugin_utils import logEventStatusCounts, get_plugin_string, get_plugin_setting, print_plugin_info, list_to_csv, combine_plugin_objects, resolve_wildcards_arr, get_plugin_setting_value, handle_empty, custom_plugin_decoder
#-------------------------------------------------------------------------------
@@ -27,8 +27,8 @@ class plugin_param:
inputValue = get_setting(param["value"])
if inputValue != None:
- setVal = inputValue[6] # setting value
- setTyp = inputValue[3] # setting type
+ setVal = inputValue["Value"] # setting value
+ setTyp = inputValue["Type"] # setting type
noConversion = ['text', 'string', 'integer', 'boolean', 'password', 'readonly', 'integer.select', 'text.select', 'integer.checkbox' ]
arrayConversion = ['text.multiselect', 'list', 'subnets']
@@ -45,11 +45,8 @@ class plugin_param:
elif setTyp in arrayConversion:
# make them safely passable to a python or linux script
- resolved = flatten_array(setVal)
+ resolved = list_to_csv(setVal)
- elif setTyp in arrayConversionBase64:
- # make them safely passable to a python or linux script by converting them to a base64 string if necessary (if the arg contains spaces)
- resolved = flatten_array(setVal)
else:
for item in jsonConversion:
if setTyp.endswith(item):
@@ -66,7 +63,7 @@ class plugin_param:
paramValuesCount = len(inputValue)
# make them safely passable to a python or linux script
- resolved = flatten_array(inputValue)
+ resolved = list_to_csv(inputValue)
mylog('debug', f'[Plugins] Resolved value: {resolved}')
@@ -750,7 +747,7 @@ def check_and_run_user_event(db, pluginsState):
return pluginsState
if event == 'test':
- handle_test(param)
+ pluginsState = handle_test(param, db, pluginsState)
if event == 'run':
pluginsState = handle_run(param, db, pluginsState)
@@ -778,34 +775,41 @@ def handle_run(runType, db, pluginsState):
#-------------------------------------------------------------------------------
-def handle_test(testType):
+def handle_test(runType, db, pluginsState):
mylog('minimal', ['[', timeNowTZ(), '] START Test: ', testType])
+
+ # TODO finish
- # Open text sample
- sample_txt = get_file_content(pialertPath + '/back/report_sample.txt')
+ # # Open text sample
+ # sample_txt = get_file_content(pialertPath + '/back/report_sample.txt')
- # Open html sample
- sample_html = get_file_content(pialertPath + '/back/report_sample.html')
+ # # Open html sample
+ # sample_html = get_file_content(pialertPath + '/back/report_sample.html')
- # Open json sample and get only the payload part
- sample_json_payload = json.loads(get_file_content(pialertPath + '/back/webhook_json_sample.json'))[0]["body"]["attachments"][0]["text"]
+ # # Open json sample and get only the payload part
+ # sample_json_payload = json.loads(get_file_content(pialertPath + '/back/webhook_json_sample.json'))[0]["body"]["attachments"][0]["text"]
- sample_msg = noti_obj(sample_json_payload, sample_txt, sample_html, "test_sample")
+ # sample_msg = noti_obj(sample_json_payload, sample_txt, sample_html, "test_sample")
+
+
+ pluginsState = handle_run(param, db, pluginsState)
- if testType == 'Email':
- send_email(sample_msg)
- elif testType == 'Webhooks':
- send_webhook (sample_msg)
- elif testType == 'Apprise':
- send_apprise (sample_msg)
- elif testType == 'NTFY':
- send_ntfy (sample_msg)
- elif testType == 'PUSHSAFER':
- send_pushsafer (sample_msg)
- else:
- mylog('none', ['[Test Publishers] No test matches: ', testType])
+ # if testType == 'Email':
+ # send_email(sample_msg)
+ # elif testType == 'Webhooks':
+ # send_webhook (sample_msg)
+ # elif testType == 'Apprise':
+ # send_apprise (sample_msg)
+ # elif testType == 'NTFY':
+ # send_ntfy (sample_msg)
+ # elif testType == 'PUSHSAFER':
+ # send_pushsafer (sample_msg)
+ # else:
+ # mylog('none', ['[Test Publishers] No test matches: ', testType])
- mylog('minimal', ['[Test Publishers] END Test: ', testType])
+ # mylog('minimal', ['[Test Publishers] END Test: ', testType])
+
+ return pluginsState
diff --git a/pialert/plugin_utils.py b/pialert/plugin_utils.py
index ed85cf8d..258f76bc 100755
--- a/pialert/plugin_utils.py
+++ b/pialert/plugin_utils.py
@@ -71,30 +71,42 @@ def get_plugin_string(props, el):
#-------------------------------------------------------------------------------
-def flatten_array(arr):
+# generates a comma separated list of values from a list (or a string representing a list)
+def list_to_csv(arr):
tmp = ''
arrayItemStr = ''
- mylog('debug', '[Plugins] Flattening the below array')
-
+ mylog('debug', '[Plugins] Flattening the below array')
mylog('debug', arr)
- for arrayItem in arr:
- # only one column flattening is supported
- if isinstance(arrayItem, list):
- arrayItemStr = str(arrayItem[0]).replace("'", '') # removing single quotes - not allowed
- else:
- # is string already
- arrayItemStr = arrayItem
+
+ mylog('debug', f'[Plugins] isinstance(arr, list) : {isinstance(arr, list)}')
+ mylog('debug', f'[Plugins] isinstance(arr, str) : {isinstance(arr, str)}')
+
+ if isinstance(arr, str):
+ return arr.replace('[','').replace(']','').replace("'", '') # removing brackets and single quotes (not allowed)
+
+ elif isinstance(arr, list):
+ for arrayItem in arr:
+ # only one column flattening is supported
+ if isinstance(arrayItem, list):
+ arrayItemStr = str(arrayItem[0]).replace("'", '') # removing single quotes - not allowed
+ else:
+ # is string already
+ arrayItemStr = arrayItem
- tmp += f'{arrayItemStr},'
+ tmp += f'{arrayItemStr},'
- tmp = tmp[:-1] # Remove last comma ','
+ tmp = tmp[:-1] # Remove last comma ','
- mylog('debug', f'[Plugins] Flattened array: {tmp}')
+ mylog('debug', f'[Plugins] Flattened array: {tmp}')
+
+ return tmp
+
+ else:
+ mylog('none', f'[Plugins] ERROR Could not convert array: {arr}')
- return tmp
diff --git a/pialert/reporting.py b/pialert/reporting.py
index 14d84b1d..3ed380a8 100755
--- a/pialert/reporting.py
+++ b/pialert/reporting.py
@@ -317,26 +317,26 @@ def get_notifications (db):
-#-------------------------------------------------------------------------------
-def check_config(service):
+# #-------------------------------------------------------------------------------
+# def check_config(service):
- if service == 'email':
- return email_check_config()
+# if service == 'email':
+# return email_check_config()
- if service == 'apprise':
- return apprise_check_config()
+# if service == 'apprise':
+# return apprise_check_config()
- if service == 'webhook':
- return webhook_check_config()
+# if service == 'webhook':
+# return webhook_check_config()
- if service == 'ntfy':
- return ntfy_check_config ()
+# if service == 'ntfy':
+# return ntfy_check_config ()
- if service == 'pushsafer':
- return pushsafer_check_config()
+# if service == 'pushsafer':
+# return pushsafer_check_config()
- if service == 'mqtt':
- return mqtt_check_config()
+# if service == 'mqtt':
+# return mqtt_check_config()
#-------------------------------------------------------------------------------
# Replacing table headers