From 519cf9f69a0895b144f895d437c440bb07993f77 Mon Sep 17 00:00:00 2001 From: Jokob-sk Date: Sun, 4 Feb 2024 13:17:41 +1100 Subject: [PATCH] =?UTF-8?q?Workflows=20v0.1.1=20=F0=9F=86=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 3 +- docs/NETWORK_TREE.md | 2 +- front/appEventsCore.php | 86 +++++++++++++++ front/deviceDetails.php | 2 +- front/js/pialert_common.js | 8 ++ front/php/templates/header.php | 6 +- front/php/templates/language/en_us.json | 21 +++- front/php/templates/language/fr_fr.json | 0 front/plugins/db_cleanup/config.json | 2 +- front/plugins/db_cleanup/script.py | 69 +++++++++--- front/plugins/workflows/README.md | 7 ++ front/plugins/workflows/config.json | 57 ++++++++++ front/pluginsCore.php | 2 +- front/{flows.php => workflows.php} | 4 +- pialert/api.py | 3 +- pialert/appevent.py | 139 ++++++++++++++++++++++-- pialert/const.py | 1 + pialert/database.py | 126 ++++++++++----------- pialert/device.py | 2 + pialert/plugin.py | 2 +- 20 files changed, 440 insertions(+), 102 deletions(-) create mode 100755 front/appEventsCore.php mode change 100644 => 100755 front/php/templates/language/fr_fr.json create mode 100755 front/plugins/workflows/README.md create mode 100755 front/plugins/workflows/config.json rename front/{flows.php => workflows.php} (93%) diff --git a/docker-compose.yml b/docker-compose.yml index 4f5716be..39e130ff 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -52,7 +52,8 @@ services: - ${DEV_LOCATION}/front/settings.php:/home/pi/pialert/front/settings.php - ${DEV_LOCATION}/front/systeminfo.php:/home/pi/pialert/front/systeminfo.php - ${DEV_LOCATION}/front/report.php:/home/pi/pialert/front/report.php - - ${DEV_LOCATION}/front/flows.php:/home/pi/pialert/front/flows.php + - ${DEV_LOCATION}/front/workflows.php:/home/pi/pialert/front/workflows.php + - ${DEV_LOCATION}/front/appEventsCore.php:/home/pi/pialert/front/appEventsCore.php - ${DEV_LOCATION}/front/donations.php:/home/pi/pialert/front/donations.php - ${DEV_LOCATION}/front/plugins:/home/pi/pialert/front/plugins # DELETE END anyone trying to use this file: comment out / delete ABOVE lines, they are only for development purposes diff --git a/docs/NETWORK_TREE.md b/docs/NETWORK_TREE.md index 21368df2..b0646f72 100755 --- a/docs/NETWORK_TREE.md +++ b/docs/NETWORK_TREE.md @@ -1,6 +1,6 @@ ## How to setup your Network page -Make sure you have a root device with the MAC `Internet` (No other MAC addresses are currently supported as the root node). +Make sure you have a root device with the MAC `Internet` (No other MAC addresses are currently supported as the root node) set to a network device type (e.g.: **Type**:`Router`). > 💡 Tip: You can add dummy devices via the [Undiscoverables plugin](https://github.com/jokob-sk/Pi.Alert/blob/main/front/plugins/undiscoverables/README.md) diff --git a/front/appEventsCore.php b/front/appEventsCore.php new file mode 100755 index 00000000..0523c535 --- /dev/null +++ b/front/appEventsCore.php @@ -0,0 +1,86 @@ +
+ +
+ + + + + + + diff --git a/front/deviceDetails.php b/front/deviceDetails.php index b0c89e0d..4adbc431 100755 --- a/front/deviceDetails.php +++ b/front/deviceDetails.php @@ -1475,7 +1475,7 @@ function updateApi() { // value has to be in format event|param. e.g. run|ARPSCAN - action = `update_api|devices` + action = `update_api|devices,appevents` $.ajax({ method: "POST", diff --git a/front/js/pialert_common.js b/front/js/pialert_common.js index be9a9e58..4b663b2f 100755 --- a/front/js/pialert_common.js +++ b/front/js/pialert_common.js @@ -418,6 +418,14 @@ function saveData(functionName, id, value) { } +// ----------------------------------------------------------------------------- +// create a link to the device +function createDeviceLink(mac) +{ + return `${getNameByMacAddress(mac)}` +} + + // ----------------------------------------------------------------------------- // remove an item from an array function removeItemFromArray(arr, value) { diff --git a/front/php/templates/header.php b/front/php/templates/header.php index 486528af..bf45cb21 100755 --- a/front/php/templates/header.php +++ b/front/php/templates/header.php @@ -252,9 +252,9 @@ if ($ENABLED_DARKMODE === True) {
  • - +
  • + +
  • diff --git a/front/php/templates/language/en_us.json b/front/php/templates/language/en_us.json index 965bd679..c757b769 100755 --- a/front/php/templates/language/en_us.json +++ b/front/php/templates/language/en_us.json @@ -3,6 +3,25 @@ "About_Title": "Open Source Network Guard", "About_Design" : "Designed for:", "About_Exit" : "Sign out", + "AppEvents_GUID" : "Application Event GUID", + "AppEvents_DateTimeCreated" : "Logged", + "AppEvents_ObjectType" : "Object Type", + "AppEvents_ObjectPlugin" : "Linked Plugin", + "AppEvents_ObjectMAC" : "Linked MAC (at log time)", + "AppEvents_ObjectIP" : "Linked IP (at log time)", + "AppEvents_ObjectPrimaryID" : "Primary ID", + "AppEvents_ObjectSecondaryID" : "Secondary ID", + "AppEvents_ObjectForeignKey" : "Foreign Key", + "AppEvents_ObjectIndex" : "Index", + "AppEvents_ObjectIsNew" : "Is new (at log time)", + "AppEvents_ObjectIsArchived" : "Is archived (at log time)", + "AppEvents_ObjectStatusColumn" : "Status column", + "AppEvents_ObjectStatus" : "Status (at log time)", + "AppEvents_Type" : "Type", + "AppEvents_Helper1" : "Helper 1", + "AppEvents_Helper2" : "Helper 2", + "AppEvents_Helper3" : "Helper 3", + "AppEvents_Extra" : "Extra", "Gen_Delete" : "Delete", "Gen_DeleteAll" : "Delete all", "Gen_Cancel" : "Cancel", @@ -44,7 +63,7 @@ "Navigation_Maintenance" : "Maintenance", "Navigation_Settings" : "Settings", "Navigation_SystemInfo" : "System info", - "Navigation_Flows" : "Flows", + "Navigation_Workflows" : "Workflows", "Navigation_HelpFAQ" : "Help / FAQ", "Navigation_Donations" : "Donations", "Device_Title" : "Devices", diff --git a/front/php/templates/language/fr_fr.json b/front/php/templates/language/fr_fr.json old mode 100644 new mode 100755 diff --git a/front/plugins/db_cleanup/config.json b/front/plugins/db_cleanup/config.json index cc4cfc3e..f022ac17 100755 --- a/front/plugins/db_cleanup/config.json +++ b/front/plugins/db_cleanup/config.json @@ -188,7 +188,7 @@ "description": [ { "language_code": "en_us", - "string": "How many historical entries of Notifications should be kept. This influences how mane entries are also available in the Report section in the UI" + "string": "How many historical entries of Notifications should be kept. This influences how many entries are also available in the Report section in the UI" } ] } diff --git a/front/plugins/db_cleanup/script.py b/front/plugins/db_cleanup/script.py index 94e3534f..4b09d865 100755 --- a/front/plugins/db_cleanup/script.py +++ b/front/plugins/db_cleanup/script.py @@ -66,17 +66,20 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP conn = sqlite3.connect(dbPath) cursor = conn.cursor() + # ----------------------------------------------------- # Cleanup Online History mylog('verbose', [f'[{pluginName}] Online_History: Delete all but keep latest 150 entries']) cursor.execute ("""DELETE from Online_History where "Index" not in ( SELECT "Index" from Online_History order by Scan_Date desc limit 150)""") - mylog('verbose', [f'[{pluginName}] Optimize Database']) + + + # ----------------------------------------------------- # Cleanup Events mylog('verbose', [f'[{pluginName}] Events: Delete all older than {str(DAYS_TO_KEEP_EVENTS)} days (DAYS_TO_KEEP_EVENTS setting)']) cursor.execute (f"""DELETE FROM Events WHERE eve_DateTime <= date('now', '-{str(DAYS_TO_KEEP_EVENTS)} day')""") - + # ----------------------------------------------------- # Trim Plugins_History entries to less than PLUGINS_KEEP_HIST setting per unique "Plugin" column entry mylog('verbose', [f'[{pluginName}] Plugins_History: Trim Plugins_History entries to less than {str(PLUGINS_KEEP_HIST)} per Plugin (PLUGINS_KEEP_HIST setting)']) @@ -94,7 +97,7 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP cursor.execute(delete_query) - + # ----------------------------------------------------- # Trim Notifications entries to less than DBCLNP_NOTIFI_HIST setting histCount = get_setting_value('DBCLNP_NOTIFI_HIST') @@ -115,19 +118,58 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP cursor.execute(delete_query) - # Cleanup Pholus_Scan - if PHOLUS_DAYS_DATA != 0: - mylog('verbose', [f'[{pluginName}] Pholus_Scan: Delete all older than ' + str(PHOLUS_DAYS_DATA) + ' days (PHOLUS_DAYS_DATA setting)']) - # todo: improvement possibility: keep at least N per mac - cursor.execute (f"""DELETE FROM Pholus_Scan - WHERE Time <= date('now', '-{str(PHOLUS_DAYS_DATA)} day')""") + + # ----------------------------------------------------- + # Trim Workflow entries to less than WORKFLOWS_AppEvents_hist setting + histCount = get_setting_value('WORKFLOWS_AppEvents_hist') + + mylog('verbose', [f'[{pluginName}] Trim AppEvents to less than {histCount}']) + + # Build the SQL query to delete entries + delete_query = f"""DELETE FROM AppEvents + WHERE "Index" NOT IN ( + SELECT "Index" + FROM ( + SELECT "Index", + ROW_NUMBER() OVER(PARTITION BY "AppEvents" ORDER BY DateTimeCreated DESC) AS row_num + FROM AppEvents + ) AS ranked_objects + WHERE row_num <= {histCount} + );""" + + cursor.execute(delete_query) + + + # ----------------------------------------------------- # Cleanup New Devices if HRS_TO_KEEP_NEWDEV != 0: mylog('verbose', [f'[{pluginName}] Devices: Delete all New Devices older than {str(HRS_TO_KEEP_NEWDEV)} hours (HRS_TO_KEEP_NEWDEV setting)']) cursor.execute (f"""DELETE FROM Devices WHERE dev_NewDevice = 1 AND dev_FirstConnection < date('now', '+{str(HRS_TO_KEEP_NEWDEV)} hour')""") + # ----------------------------------------------------- + # Cleanup Pholus_Scan + if PHOLUS_DAYS_DATA != 0: + mylog('verbose', [f'[{pluginName}] Pholus_Scan: Delete all older than ' + str(PHOLUS_DAYS_DATA) + ' days (PHOLUS_DAYS_DATA setting)']) + # todo: improvement possibility: keep at least N per mac + cursor.execute (f"""DELETE FROM Pholus_Scan + WHERE Time <= date('now', '-{str(PHOLUS_DAYS_DATA)} day')""") + + + # ----------------------------------------------------- + # De-Dupe (de-duplicate - remove duplicate entries) from the Pholus_Scan table + mylog('verbose', [f'[{pluginName}] Pholus_Scan: Delete all duplicates']) + cursor.execute ("""DELETE FROM Pholus_Scan + WHERE rowid > ( + SELECT MIN(rowid) FROM Pholus_Scan p2 + WHERE Pholus_Scan.MAC = p2.MAC + AND Pholus_Scan.Value = p2.Value + AND Pholus_Scan.Record_Type = p2.Record_Type + );""") + + + # ----------------------------------------------------- # De-dupe (de-duplicate) from the Plugins_Objects table # TODO This shouldn't be necessary - probably a concurrency bug somewhere in the code :( mylog('verbose', [f'[{pluginName}] Plugins_Objects: Delete all duplicates']) @@ -142,15 +184,6 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP ) """) - # De-Dupe (de-duplicate - remove duplicate entries) from the Pholus_Scan table - mylog('verbose', [f'[{pluginName}] Pholus_Scan: Delete all duplicates']) - cursor.execute ("""DELETE FROM Pholus_Scan - WHERE rowid > ( - SELECT MIN(rowid) FROM Pholus_Scan p2 - WHERE Pholus_Scan.MAC = p2.MAC - AND Pholus_Scan.Value = p2.Value - AND Pholus_Scan.Record_Type = p2.Record_Type - );""") conn.commit() diff --git a/front/plugins/workflows/README.md b/front/plugins/workflows/README.md new file mode 100755 index 00000000..e024b14d --- /dev/null +++ b/front/plugins/workflows/README.md @@ -0,0 +1,7 @@ +## Overview + +TBC + +### Usage + +- Check the Settings page for details. diff --git a/front/plugins/workflows/config.json b/front/plugins/workflows/config.json new file mode 100755 index 00000000..87656059 --- /dev/null +++ b/front/plugins/workflows/config.json @@ -0,0 +1,57 @@ +{ + "code_name": "workflows", + "unique_prefix": "WORKFLOWS", + "plugin_type": "system", + "enabled": true, + "data_source": "script", + "show_ui": false, + "localized": ["display_name", "description", "icon"], + + "display_name": [ + { + "language_code": "en_us", + "string": "Workflows" + } + ], + "icon": [ + { + "language_code": "en_us", + "string": "" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "A plugin to adjust behavior of workflows." + } + ], + "params" : [ + ], + + "settings": [ + { + "function": "AppEvents_hist", + "type": "integer", + "default_value": 10000, + "options": [], + "localized": ["name", "description"], + "name": [ + { + "language_code": "en_us", + "string": "App Events History" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "How many historical entries of Application Events should be kept. This influences how many entries are also available in the Workflows section in the UI." + } + ] + } + ], + + "database_column_definitions": + [ + + ] +} diff --git a/front/pluginsCore.php b/front/pluginsCore.php index 9cbd6153..43ac99e1 100755 --- a/front/pluginsCore.php +++ b/front/pluginsCore.php @@ -123,7 +123,7 @@ function processColumnValue(dbColumnDef, value, index, type) { `; break; case 'device_name_mac': - value = `${getNameByMacAddress(value)}`; + value = createDeviceLink(value); break; case 'device_mac': value = `${value}`; diff --git a/front/flows.php b/front/workflows.php similarity index 93% rename from front/flows.php rename to front/workflows.php index d038c774..962f15db 100755 --- a/front/flows.php +++ b/front/workflows.php @@ -13,14 +13,14 @@

    - +

    diff --git a/pialert/api.py b/pialert/api.py index ea627007..f2c60ac0 100755 --- a/pialert/api.py +++ b/pialert/api.py @@ -3,7 +3,7 @@ import json # pialert modules import conf -from const import (apiPath, sql_devices_all, sql_events_pending_alert, sql_settings, sql_plugins_events, sql_plugins_history, sql_plugins_objects,sql_language_strings, sql_notifications_all) +from const import (apiPath, sql_appevents, sql_devices_all, sql_events_pending_alert, sql_settings, sql_plugins_events, sql_plugins_history, sql_plugins_objects,sql_language_strings, sql_notifications_all) from logger import mylog from helper import write_file @@ -23,6 +23,7 @@ def update_api(db, isNotification = False, updateOnlyDataSources = []): # prepare database tables we want to expose dataSourcesSQLs = [ + ["appevents", sql_appevents], ["devices", sql_devices_all], ["events_pending_alert", sql_events_pending_alert], ["settings", sql_settings], diff --git a/pialert/appevent.py b/pialert/appevent.py index a9a850a4..7d2050fa 100755 --- a/pialert/appevent.py +++ b/pialert/appevent.py @@ -16,6 +16,15 @@ class AppEvent_obj: def __init__(self, db): self.db = db + # drop table + self.db.sql.execute("""DROP TABLE IF EXISTS "AppEvents" """) + + # Drop all triggers + self.db.sql.execute('DROP TRIGGER IF EXISTS trg_create_device;') + self.db.sql.execute('DROP TRIGGER IF EXISTS trg_read_device;') + self.db.sql.execute('DROP TRIGGER IF EXISTS trg_update_device;') + self.db.sql.execute('DROP TRIGGER IF EXISTS trg_delete_device;') + # Create AppEvent table if missing self.db.sql.execute("""CREATE TABLE IF NOT EXISTS "AppEvents" ( "Index" INTEGER, @@ -29,18 +38,133 @@ class AppEvent_obj: "ObjectPrimaryID" TEXT, "ObjectSecondaryID" TEXT, "ObjectForeignKey" TEXT, - "ObjectIndex" TEXT, - "ObjectRowID" TEXT, + "ObjectIndex" TEXT, + "ObjectIsNew" BOOLEAN, + "ObjectIsArchived" BOOLEAN, "ObjectStatusColumn" TEXT, -- Status (Notifications, Plugins), eve_EventType (Events) - "ObjectStatus" TEXT, -- new_devices, down_devices, events, new, watched-changed, watched-not-changed, missing-in-last-scan, Device down, New Device, IP Changed, Connected, Disconnected, VOIDED - Disconnected, VOIDED - Connected, - "AppEventStatus" TEXT, -- TBD "new", "used", "cleanup-next" - "Extra" TEXT, + "ObjectStatus" TEXT, -- new_devices, down_devices, events, new, watched-changed, watched-not-changed, missing-in-last-scan, Device down, New Device, IP Changed, Connected, Disconnected, VOIDED - Disconnected, VOIDED - Connected, + "AppEventType" TEXT, -- "create", "update", "delete" (+TBD) + "Helper1" TEXT, + "Helper2" TEXT, + "Helper3" TEXT, + "Extra" TEXT, PRIMARY KEY("Index" AUTOINCREMENT) ); """) + # Generate a GUID + sql_generateGuid = ''' + lower( + hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-' || '4' || + substr(hex( randomblob(2)), 2) || '-' || + substr('AB89', 1 + (abs(random()) % 4) , 1) || + substr(hex(randomblob(2)), 2) || '-' || + hex(randomblob(6)) + ) + ''' + + sql_mappedColumns = ''' + "GUID", + "DateTimeCreated", + "ObjectType", + "ObjectMAC", + "ObjectIP", + "ObjectStatus", + "ObjectStatusColumn", + "ObjectIsNew", + "ObjectIsArchived", + "ObjectForeignKey", + "AppEventType" + ''' + + # Trigger for create event + self.db.sql.execute(f''' + CREATE TRIGGER IF NOT EXISTS "trg_create_device" + AFTER INSERT ON "Devices" + BEGIN + INSERT INTO "AppEvents" ( + {sql_mappedColumns} + ) + VALUES ( + -- below generates a GUID + {sql_generateGuid}, + DATETIME('now'), + 'Devices', + NEW.dev_MAC, + NEW.dev_LastIP, + CASE WHEN NEW.dev_PresentLastScan = 1 THEN 'online' ELSE 'offline' END, + 'dev_PresentLastScan', + NEW.dev_NewDevice, + NEW.dev_Archived, + NEW.dev_MAC, + 'create' + ); + END; + ''') + + # 🔴 This would generate too many events, disabled for now + # # Trigger for read event + # self.db.sql.execute(''' + # TODO + # ''') + + # Trigger for update event + self.db.sql.execute(f''' + CREATE TRIGGER IF NOT EXISTS "trg_update_device" + AFTER UPDATE ON "Devices" + BEGIN + INSERT INTO "AppEvents" ( + {sql_mappedColumns} + ) + VALUES ( + -- below generates a GUID + {sql_generateGuid}, + DATETIME('now'), + 'Devices', + NEW.dev_MAC, + NEW.dev_LastIP, + CASE WHEN NEW.dev_PresentLastScan = 1 THEN 'online' ELSE 'offline' END, + 'dev_PresentLastScan', + NEW.dev_NewDevice, + NEW.dev_Archived, + NEW.dev_MAC, + 'update' + ); + END; + ''') + + # Trigger for delete event + self.db.sql.execute(f''' + CREATE TRIGGER IF NOT EXISTS "trg_delete_device" + AFTER DELETE ON "Devices" + BEGIN + INSERT INTO "AppEvents" ( + {sql_mappedColumns} + ) + VALUES ( + -- below generates a GUID + {sql_generateGuid}, + DATETIME('now'), + 'Devices', + OLD.dev_MAC, + OLD.dev_LastIP, + CASE WHEN OLD.dev_PresentLastScan = 1 THEN 'online' ELSE 'offline' END, + 'dev_PresentLastScan', + OLD.dev_NewDevice, + OLD.dev_Archived, + OLD.dev_MAC, + 'delete' + ); + END; + ''') + self.save() + # ------------------------------------------------------------------------------- + # ------------------------------------------------------------------------------- + # below code is unused + # ------------------------------------------------------------------------------- + # Create a new DB entry if new notifications are available, otherwise skip def create(self, Extra="", **kwargs): # Check if nothing to report, end @@ -72,11 +196,6 @@ class AppEvent_obj: return True - # Update the status of the entry - def updateStatus(self, newStatus): - self.ObjectStatus = newStatus - self.upsert() - def upsert(self): self.db.sql.execute(""" INSERT OR REPLACE INTO AppEvents ( diff --git a/pialert/const.py b/pialert/const.py index 62a10aea..e9174649 100755 --- a/pialert/const.py +++ b/pialert/const.py @@ -23,6 +23,7 @@ vendorsPath = '/usr/share/arp-scan/ieee-oui.txt' # SQL queries #=============================================================================== sql_devices_all = """select rowid, * from Devices""" +sql_appevents = """select * from AppEvents""" sql_devices_stats = """SELECT Online_Devices as online, Down_Devices as down, All_Devices as 'all', Archived_Devices as archived, (select count(*) from Devices a where dev_NewDevice = 1 ) as new, (select count(*) from Devices a where dev_Name = '(unknown)' or dev_Name = '(name not found)' ) as unknown diff --git a/pialert/database.py b/pialert/database.py index 53f0d505..30e7bfe5 100755 --- a/pialert/database.py +++ b/pialert/database.py @@ -7,6 +7,7 @@ from const import fullDbPath, sql_devices_stats, sql_devices_all from logger import mylog from helper import json_obj, initOrSetParam, row_to_json, timeNowTZ #, updateState +from appevent import AppEvent_obj @@ -83,8 +84,8 @@ class DB(): # indicates, if Online_History table is available onlineHistoryAvailable = self.sql.execute(""" - SELECT name FROM sqlite_master WHERE type='table' - AND name='Online_History'; + SELECT name FROM sqlite_master WHERE type='table' + AND name='Online_History'; """).fetchall() != [] # Check if it is incompatible (Check if table has all required columns) @@ -92,8 +93,8 @@ class DB(): if onlineHistoryAvailable : isIncompatible = self.sql.execute (""" - SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Online_History') WHERE name='Archived_Devices' - """).fetchone()[0] == 0 + SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Online_History') WHERE name='Archived_Devices' + """).fetchone()[0] == 0 # Drop table if available, but incompatible if onlineHistoryAvailable and isIncompatible: @@ -119,35 +120,35 @@ class DB(): # ------------------------------------------------------------------------- # dev_Network_Node_MAC_ADDR column dev_Network_Node_MAC_ADDR_missing = self.sql.execute (""" - SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Network_Node_MAC_ADDR' + SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Network_Node_MAC_ADDR' """).fetchone()[0] == 0 if dev_Network_Node_MAC_ADDR_missing : mylog('verbose', ["[upgradeDB] Adding dev_Network_Node_MAC_ADDR to the Devices table"]) self.sql.execute(""" - ALTER TABLE "Devices" ADD "dev_Network_Node_MAC_ADDR" TEXT + ALTER TABLE "Devices" ADD "dev_Network_Node_MAC_ADDR" TEXT """) # dev_Network_Node_port column dev_Network_Node_port_missing = self.sql.execute (""" - SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Network_Node_port' + SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Network_Node_port' """).fetchone()[0] == 0 if dev_Network_Node_port_missing : mylog('verbose', ["[upgradeDB] Adding dev_Network_Node_port to the Devices table"]) self.sql.execute(""" - ALTER TABLE "Devices" ADD "dev_Network_Node_port" INTEGER + ALTER TABLE "Devices" ADD "dev_Network_Node_port" INTEGER """) # dev_Icon column dev_Icon_missing = self.sql.execute (""" - SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Icon' + SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Icon' """).fetchone()[0] == 0 if dev_Icon_missing : mylog('verbose', ["[upgradeDB] Adding dev_Icon to the Devices table"]) self.sql.execute(""" - ALTER TABLE "Devices" ADD "dev_Icon" TEXT + ALTER TABLE "Devices" ADD "dev_Icon" TEXT """) @@ -263,61 +264,61 @@ class DB(): # Plugin state sql_Plugins_Objects = """ CREATE TABLE IF NOT EXISTS Plugins_Objects( - "Index" INTEGER, - Plugin TEXT NOT NULL, - Object_PrimaryID TEXT NOT NULL, - Object_SecondaryID TEXT NOT NULL, - DateTimeCreated TEXT NOT NULL, - DateTimeChanged TEXT NOT NULL, - Watched_Value1 TEXT NOT NULL, - Watched_Value2 TEXT NOT NULL, - Watched_Value3 TEXT NOT NULL, - Watched_Value4 TEXT NOT NULL, - Status TEXT NOT NULL, - Extra TEXT NOT NULL, - UserData TEXT NOT NULL, - ForeignKey TEXT NOT NULL, - PRIMARY KEY("Index" AUTOINCREMENT) + "Index" INTEGER, + Plugin TEXT NOT NULL, + Object_PrimaryID TEXT NOT NULL, + Object_SecondaryID TEXT NOT NULL, + DateTimeCreated TEXT NOT NULL, + DateTimeChanged TEXT NOT NULL, + Watched_Value1 TEXT NOT NULL, + Watched_Value2 TEXT NOT NULL, + Watched_Value3 TEXT NOT NULL, + Watched_Value4 TEXT NOT NULL, + Status TEXT NOT NULL, + Extra TEXT NOT NULL, + UserData TEXT NOT NULL, + ForeignKey TEXT NOT NULL, + PRIMARY KEY("Index" AUTOINCREMENT) ); """ self.sql.execute(sql_Plugins_Objects) # Plugin execution results sql_Plugins_Events = """ CREATE TABLE IF NOT EXISTS Plugins_Events( - "Index" INTEGER, - Plugin TEXT NOT NULL, - Object_PrimaryID TEXT NOT NULL, - Object_SecondaryID TEXT NOT NULL, - DateTimeCreated TEXT NOT NULL, - DateTimeChanged TEXT NOT NULL, - Watched_Value1 TEXT NOT NULL, - Watched_Value2 TEXT NOT NULL, - Watched_Value3 TEXT NOT NULL, - Watched_Value4 TEXT NOT NULL, - Status TEXT NOT NULL, - Extra TEXT NOT NULL, - UserData TEXT NOT NULL, - ForeignKey TEXT NOT NULL, - PRIMARY KEY("Index" AUTOINCREMENT) + "Index" INTEGER, + Plugin TEXT NOT NULL, + Object_PrimaryID TEXT NOT NULL, + Object_SecondaryID TEXT NOT NULL, + DateTimeCreated TEXT NOT NULL, + DateTimeChanged TEXT NOT NULL, + Watched_Value1 TEXT NOT NULL, + Watched_Value2 TEXT NOT NULL, + Watched_Value3 TEXT NOT NULL, + Watched_Value4 TEXT NOT NULL, + Status TEXT NOT NULL, + Extra TEXT NOT NULL, + UserData TEXT NOT NULL, + ForeignKey TEXT NOT NULL, + PRIMARY KEY("Index" AUTOINCREMENT) ); """ self.sql.execute(sql_Plugins_Events) # Plugin execution history sql_Plugins_History = """ CREATE TABLE IF NOT EXISTS Plugins_History( - "Index" INTEGER, - Plugin TEXT NOT NULL, - Object_PrimaryID TEXT NOT NULL, - Object_SecondaryID TEXT NOT NULL, - DateTimeCreated TEXT NOT NULL, - DateTimeChanged TEXT NOT NULL, - Watched_Value1 TEXT NOT NULL, - Watched_Value2 TEXT NOT NULL, - Watched_Value3 TEXT NOT NULL, - Watched_Value4 TEXT NOT NULL, - Status TEXT NOT NULL, - Extra TEXT NOT NULL, - UserData TEXT NOT NULL, - ForeignKey TEXT NOT NULL, - PRIMARY KEY("Index" AUTOINCREMENT) + "Index" INTEGER, + Plugin TEXT NOT NULL, + Object_PrimaryID TEXT NOT NULL, + Object_SecondaryID TEXT NOT NULL, + DateTimeCreated TEXT NOT NULL, + DateTimeChanged TEXT NOT NULL, + Watched_Value1 TEXT NOT NULL, + Watched_Value2 TEXT NOT NULL, + Watched_Value3 TEXT NOT NULL, + Watched_Value4 TEXT NOT NULL, + Status TEXT NOT NULL, + Extra TEXT NOT NULL, + UserData TEXT NOT NULL, + ForeignKey TEXT NOT NULL, + PRIMARY KEY("Index" AUTOINCREMENT) ); """ self.sql.execute(sql_Plugins_History) @@ -328,12 +329,12 @@ class DB(): # Dynamically generated language strings self.sql.execute("DROP TABLE IF EXISTS Plugins_Language_Strings;") self.sql.execute(""" CREATE TABLE IF NOT EXISTS Plugins_Language_Strings( - "Index" INTEGER, - Language_Code TEXT NOT NULL, - String_Key TEXT NOT NULL, - String_Value TEXT NOT NULL, - Extra TEXT NOT NULL, - PRIMARY KEY("Index" AUTOINCREMENT) + "Index" INTEGER, + Language_Code TEXT NOT NULL, + String_Key TEXT NOT NULL, + String_Value TEXT NOT NULL, + Extra TEXT NOT NULL, + PRIMARY KEY("Index" AUTOINCREMENT) ); """) self.commitDB() @@ -355,6 +356,9 @@ class DB(): ); """) + # Init the AppEvent database table + AppEvent_obj(self) + # ------------------------------------------------------------------------- # DELETING OBSOLETE TABLES - to remove with updated db file after 1/1/2024 # ------------------------------------------------------------------------- diff --git a/pialert/device.py b/pialert/device.py index 5f293444..2741ab09 100755 --- a/pialert/device.py +++ b/pialert/device.py @@ -194,6 +194,8 @@ def create_new_devices (db): '{get_setting_value('NEWDEV_dev_Icon')}' """ + # Bulk-inserting devices from the CurrentScan table as new devices in the table Devices ... + # ... with new device defaults and ignoring specidfied IPs and MACs) sqlQuery = f"""INSERT OR IGNORE INTO Devices (dev_MAC, dev_name, dev_Vendor, dev_LastIP, dev_FirstConnection, dev_LastConnection, {newDevColumns}) diff --git a/pialert/plugin.py b/pialert/plugin.py index d0ce49cd..6eeba48e 100755 --- a/pialert/plugin.py +++ b/pialert/plugin.py @@ -374,7 +374,7 @@ def execute_plugin(db, plugin, pluginsState = plugins_state() ): pluginsState = process_plugin_events(db, plugin, pluginsState, sqlParams) # update API endpoints - update_api(db, False, ["plugins_events","plugins_objects", "plugins_history"]) + update_api(db, False, ["plugins_events","plugins_objects", "plugins_history", "appevents"]) return pluginsState