🔺GraphQL v0.1 + Devices table rebuild + removal of backend compatible scripts

This commit is contained in:
jokob-sk
2024-11-10 21:22:45 +11:00
parent 3cf3305b8f
commit 0bc8b39cec
76 changed files with 1622 additions and 2878 deletions

View File

@@ -19,6 +19,7 @@ import sys
import time
import datetime
import multiprocessing
import subprocess
# Register NetAlertX modules
import conf
@@ -34,7 +35,6 @@ from notification import Notification_obj
from plugin import run_plugin_scripts, check_and_run_user_event
from device import update_devices_names
#===============================================================================
#===============================================================================
# MAIN
@@ -78,6 +78,11 @@ def main ():
#===============================================================================
# This is the main loop of NetAlertX
#===============================================================================
mylog('debug', '[MAIN] Starting GraphQL server')
# Path to your `graphql_server.py` file
flask_app_path = applicationPath + '/server/graphql_server.py'
mylog('debug', '[MAIN] Starting loop')

View File

@@ -7,6 +7,9 @@ from const import (apiPath, sql_appevents, sql_devices_all, sql_events_pending_a
from logger import mylog
from helper import write_file
# Import the start_server function
from graphql_server.graphql_server_start import start_server
apiEndpoints = []
#===============================================================================
@@ -42,6 +45,9 @@ def update_api(db, all_plugins, isNotification = False, updateOnlyDataSources =
if updateOnlyDataSources == [] or dsSQL[0] in updateOnlyDataSources:
api_endpoint_class(db, dsSQL[1], folder + 'table_' + dsSQL[0] + '.json')
# Start the GraphQL server
start_server()
#-------------------------------------------------------------------------------

View File

@@ -82,13 +82,13 @@ class AppEvent_obj:
{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,
NEW.devMac,
NEW.devLastIP,
CASE WHEN NEW.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END,
'devPresentLastScan',
NEW.devIsNew,
NEW.devIsArchived,
NEW.devMac,
'create'
);
END;
@@ -112,13 +112,13 @@ class AppEvent_obj:
{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,
NEW.devMac,
NEW.devLastIP,
CASE WHEN NEW.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END,
'devPresentLastScan',
NEW.devIsNew,
NEW.devIsArchived,
NEW.devMac,
'update'
);
END;
@@ -136,13 +136,13 @@ class AppEvent_obj:
{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,
OLD.devMac,
OLD.devLastIP,
CASE WHEN OLD.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END,
'devPresentLastScan',
OLD.devIsNew,
OLD.devIsArchived,
OLD.devMac,
'delete'
);
END;

View File

@@ -43,4 +43,4 @@ REPORT_DASHBOARD_URL = 'http://netalertx/'
# -------------------------------------------
# API
API_CUSTOM_SQL = 'SELECT * FROM Devices WHERE dev_PresentLastScan = 0'
API_CUSTOM_SQL = 'SELECT * FROM Devices WHERE devPresentLastScan = 0'

View File

@@ -30,8 +30,8 @@ vendorsPathNewest = '/usr/share/arp-scan/ieee-oui_all_filtered.txt'
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
(select count(*) from Devices a where devIsNew = 1 ) as new,
(select count(*) from Devices a where devName = '(unknown)' or devName = '(name not found)' ) as unknown
from Online_History order by Scan_Date desc limit 1"""
sql_events_pending_alert = "SELECT * FROM Events where eve_PendingAlertEmail is not 0"
sql_settings = "SELECT * FROM Settings"
@@ -42,14 +42,14 @@ sql_online_history = "SELECT * FROM Online_History"
sql_plugins_events = "SELECT * FROM Plugins_Events"
sql_plugins_history = "SELECT * FROM Plugins_History ORDER BY DateTimeChanged DESC"
sql_new_devices = """SELECT * FROM (
SELECT eve_IP as dev_LastIP, eve_MAC as dev_MAC
SELECT eve_IP as devLastIP, eve_MAC as devMac
FROM Events_Devices
WHERE eve_PendingAlertEmail = 1
AND eve_EventType = 'New Device'
ORDER BY eve_DateTime ) t1
LEFT JOIN
( SELECT dev_Name, dev_MAC as dev_MAC_t2 FROM Devices) t2
ON t1.dev_MAC = t2.dev_MAC_t2"""
( SELECT devName, devMac as devMac_t2 FROM Devices) t2
ON t1.devMac = t2.devMac_t2"""
sql_generateGuid = '''

View File

@@ -81,149 +81,306 @@ class DB():
"""
Check the current tables in the DB and upgrade them if neccessary
"""
# indicates, if Online_History table is available
onlineHistoryAvailable = self.sql.execute("""
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)
isIncompatible = False
if onlineHistoryAvailable :
isIncompatible = self.sql.execute ("""
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:
mylog('none','[upgradeDB] Table is incompatible, Dropping the Online_History table')
self.sql.execute("DROP TABLE Online_History;")
onlineHistoryAvailable = False
if onlineHistoryAvailable == False :
self.sql.execute("""
CREATE TABLE "Online_History" (
self.sql.execute("""
CREATE TABLE IF NOT EXISTS "Online_History" (
"Index" INTEGER,
"Scan_Date" TEXT,
"Online_Devices" INTEGER,
"Down_Devices" INTEGER,
"All_Devices" INTEGER,
"Archived_Devices" INTEGER,
"Offline_Devices" INTEGER,
PRIMARY KEY("Index" AUTOINCREMENT)
);
""")
# Offline_Devices column
Offline_Devices_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Online_History') WHERE name='Offline_Devices'
# -------------------------------------------------------------------
# DevicesNew - cleanup after 6/6/2025
# check if migration already done based on devMac
devMac_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='devMac'
""").fetchone()[0] == 0
if devMac_missing:
# SQL to create Devices table with indexes
sql_create_devices_new_tmp = """
CREATE TABLE IF NOT EXISTS Devices_tmp (
devMac STRING (50) PRIMARY KEY NOT NULL COLLATE NOCASE,
devName STRING (50) NOT NULL DEFAULT "(unknown)",
devOwner STRING (30) DEFAULT "(unknown)" NOT NULL,
devType STRING (30),
devVendor STRING (250),
devFavorite BOOLEAN CHECK (devFavorite IN (0, 1)) DEFAULT (0) NOT NULL,
devGroup STRING (10),
devComments TEXT,
devFirstConnection DATETIME NOT NULL,
devLastConnection DATETIME NOT NULL,
devLastIP STRING (50) NOT NULL COLLATE NOCASE,
devStaticIP BOOLEAN DEFAULT (0) NOT NULL CHECK (devStaticIP IN (0, 1)),
devScan INTEGER DEFAULT (1) NOT NULL,
devLogEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devLogEvents IN (0, 1)),
devAlertEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devAlertEvents IN (0, 1)),
devAlertDown BOOLEAN NOT NULL DEFAULT (0) CHECK (devAlertDown IN (0, 1)),
devSkipRepeated INTEGER DEFAULT 0 NOT NULL,
devLastNotification DATETIME,
devPresentLastScan BOOLEAN NOT NULL DEFAULT (0) CHECK (devPresentLastScan IN (0, 1)),
devIsNew BOOLEAN NOT NULL DEFAULT (1) CHECK (devIsNew IN (0, 1)),
devLocation STRING (250) COLLATE NOCASE,
devIsArchived BOOLEAN NOT NULL DEFAULT (0) CHECK (devIsArchived IN (0, 1)),
devParentMAC TEXT,
devParentPort INTEGER,
devIcon TEXT,
devGUID TEXT,
devSite TEXT,
devSSID TEXT,
devSyncHubNode TEXT,
devSourcePlugin TEXT
);
if Offline_Devices_missing :
mylog('verbose', ["[upgradeDB] Adding Offline_Devices to the Online_History table"])
self.sql.execute("""
ALTER TABLE "Online_History" ADD "Offline_Devices" INTEGER
""")
CREATE INDEX IF NOT EXISTS IDX_dev_PresentLastScan ON Devices_tmp (devPresentLastScan);
CREATE INDEX IF NOT EXISTS IDX_dev_FirstConnection ON Devices_tmp (devFirstConnection);
CREATE INDEX IF NOT EXISTS IDX_dev_AlertDeviceDown ON Devices_tmp (devAlertDown);
CREATE INDEX IF NOT EXISTS IDX_dev_StaticIP ON Devices_tmp (devStaticIP);
CREATE INDEX IF NOT EXISTS IDX_dev_ScanCycle ON Devices_tmp (devScan);
CREATE INDEX IF NOT EXISTS IDX_dev_Favorite ON Devices_tmp (devFavorite);
CREATE INDEX IF NOT EXISTS IDX_dev_LastIP ON Devices_tmp (devLastIP);
CREATE INDEX IF NOT EXISTS IDX_dev_NewDevice ON Devices_tmp (devIsNew);
CREATE INDEX IF NOT EXISTS IDX_dev_Archived ON Devices_tmp (devIsArchived);
"""
# -------------------------------------------------------------------------
# Alter Devices table
# -------------------------------------------------------------------------
# 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'
""").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
""")
# 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'
""").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
""")
# dev_Icon column
dev_Icon_missing = self.sql.execute ("""
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
""")
# dev_GUID column
dev_GUID_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_GUID'
""").fetchone()[0] == 0
if dev_GUID_missing :
mylog('verbose', ["[upgradeDB] Adding dev_GUID to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_GUID" TEXT
""")
# dev_NetworkSite column
dev_NetworkSite_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_NetworkSite'
""").fetchone()[0] == 0
if dev_NetworkSite_missing :
mylog('verbose', ["[upgradeDB] Adding dev_NetworkSite to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_NetworkSite" TEXT
""")
# dev_SSID column
dev_SSID_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SSID'
""").fetchone()[0] == 0
if dev_SSID_missing :
mylog('verbose', ["[upgradeDB] Adding dev_SSID to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_SSID" TEXT
""")
# SQL query to update missing dev_GUID
self.sql.execute(f'''
UPDATE Devices
SET dev_GUID = {sql_generateGuid}
WHERE dev_GUID IS NULL
''')
# dev_SyncHubNodeName column
dev_SyncHubNodeName_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SyncHubNodeName'
""").fetchone()[0] == 0
if dev_SyncHubNodeName_missing :
mylog('verbose', ["[upgradeDB] Adding dev_SyncHubNodeName to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_SyncHubNodeName" TEXT
""")
# Execute the creation of the Devices table and indexes
self.sql.executescript(sql_create_devices_new_tmp)
# dev_SourcePlugin column
dev_SourcePlugin_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SourcePlugin'
""").fetchone()[0] == 0
# copy over data
sql_copy_from_devices = """
INSERT OR IGNORE INTO Devices_tmp (
devMac,
devName,
devOwner,
devType,
devVendor,
devFavorite,
devGroup,
devComments,
devFirstConnection,
devLastConnection,
devLastIP,
devStaticIP,
devScan,
devLogEvents,
devAlertEvents,
devAlertDown,
devSkipRepeated,
devLastNotification,
devPresentLastScan,
devIsNew,
devLocation,
devIsArchived,
devParentMAC,
devParentPort,
devIcon,
devGUID,
devSite,
devSSID,
devSyncHubNode,
devSourcePlugin
)
SELECT
dev_MAC AS devMac,
dev_Name AS devName,
dev_Owner AS devOwner,
dev_DeviceType AS devType,
dev_Vendor AS devVendor,
dev_Favorite AS devFavorite,
dev_Group AS devGroup,
dev_Comments AS devComments,
dev_FirstConnection AS devFirstConnection,
dev_LastConnection AS devLastConnection,
dev_LastIP AS devLastIP,
dev_StaticIP AS devStaticIP,
dev_ScanCycle AS devScan,
dev_LogEvents AS devLogEvents,
dev_AlertEvents AS devAlertEvents,
dev_AlertDeviceDown AS devAlertDown,
dev_SkipRepeated AS devSkipRepeated,
dev_LastNotification AS devLastNotification,
dev_PresentLastScan AS devPresentLastScan,
dev_NewDevice AS devIsNew,
dev_Location AS devLocation,
dev_Archived AS devIsArchived,
dev_Network_Node_MAC_ADDR AS devParentMAC,
dev_Network_Node_port AS devParentPort,
dev_Icon AS devIcon,
dev_GUID AS devGUID,
dev_NetworkSite AS devSite,
dev_SSID AS devSSID,
dev_SyncHubNodeName AS devSyncHubNode,
dev_SourcePlugin AS devSourcePlugin
FROM Devices;
"""
self.sql.execute(sql_copy_from_devices)
self.sql.execute(""" DROP TABLE Devices;""")
# SQL to create Devices table with indexes
sql_create_devices_new = """
CREATE TABLE IF NOT EXISTS Devices (
devMac STRING (50) PRIMARY KEY NOT NULL COLLATE NOCASE,
devName STRING (50) NOT NULL DEFAULT "(unknown)",
devOwner STRING (30) DEFAULT "(unknown)" NOT NULL,
devType STRING (30),
devVendor STRING (250),
devFavorite BOOLEAN CHECK (devFavorite IN (0, 1)) DEFAULT (0) NOT NULL,
devGroup STRING (10),
devComments TEXT,
devFirstConnection DATETIME NOT NULL,
devLastConnection DATETIME NOT NULL,
devLastIP STRING (50) NOT NULL COLLATE NOCASE,
devStaticIP BOOLEAN DEFAULT (0) NOT NULL CHECK (devStaticIP IN (0, 1)),
devScan INTEGER DEFAULT (1) NOT NULL,
devLogEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devLogEvents IN (0, 1)),
devAlertEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devAlertEvents IN (0, 1)),
devAlertDown BOOLEAN NOT NULL DEFAULT (0) CHECK (devAlertDown IN (0, 1)),
devSkipRepeated INTEGER DEFAULT 0 NOT NULL,
devLastNotification DATETIME,
devPresentLastScan BOOLEAN NOT NULL DEFAULT (0) CHECK (devPresentLastScan IN (0, 1)),
devIsNew BOOLEAN NOT NULL DEFAULT (1) CHECK (devIsNew IN (0, 1)),
devLocation STRING (250) COLLATE NOCASE,
devIsArchived BOOLEAN NOT NULL DEFAULT (0) CHECK (devIsArchived IN (0, 1)),
devParentMAC TEXT,
devParentPort INTEGER,
devIcon TEXT,
devGUID TEXT,
devSite TEXT,
devSSID TEXT,
devSyncHubNode TEXT,
devSourcePlugin TEXT
);
CREATE INDEX IF NOT EXISTS IDX_dev_PresentLastScan ON Devices (devPresentLastScan);
CREATE INDEX IF NOT EXISTS IDX_dev_FirstConnection ON Devices (devFirstConnection);
CREATE INDEX IF NOT EXISTS IDX_dev_AlertDeviceDown ON Devices (devAlertDown);
CREATE INDEX IF NOT EXISTS IDX_dev_StaticIP ON Devices (devStaticIP);
CREATE INDEX IF NOT EXISTS IDX_dev_ScanCycle ON Devices (devScan);
CREATE INDEX IF NOT EXISTS IDX_dev_Favorite ON Devices (devFavorite);
CREATE INDEX IF NOT EXISTS IDX_dev_LastIP ON Devices (devLastIP);
CREATE INDEX IF NOT EXISTS IDX_dev_NewDevice ON Devices (devIsNew);
CREATE INDEX IF NOT EXISTS IDX_dev_Archived ON Devices (devIsArchived);
"""
# Execute the creation of the Devices table and indexes
self.sql.executescript(sql_create_devices_new)
# copy over data
sql_copy_from_devices_tmp = """
INSERT OR IGNORE INTO Devices (
devMac,
devName,
devOwner,
devType,
devVendor,
devFavorite,
devGroup,
devComments,
devFirstConnection,
devLastConnection,
devLastIP,
devStaticIP,
devScan,
devLogEvents,
devAlertEvents,
devAlertDown,
devSkipRepeated,
devLastNotification,
devPresentLastScan,
devIsNew,
devLocation,
devIsArchived,
devParentMAC,
devParentPort,
devIcon,
devGUID,
devSite,
devSSID,
devSyncHubNode,
devSourcePlugin
)
SELECT
devMac,
devName,
devOwner,
devType,
devVendor,
devFavorite,
devGroup,
devComments,
devFirstConnection,
devLastConnection,
devLastIP,
devStaticIP,
devScan,
devLogEvents,
devAlertEvents,
devAlertDown,
devSkipRepeated,
devLastNotification,
devPresentLastScan,
devIsNew,
devLocation,
devIsArchived,
devParentMAC,
devParentPort,
devIcon,
devGUID,
devSite,
devSSID,
devSyncHubNode,
devSourcePlugin
FROM Devices_tmp;
"""
self.sql.execute(sql_copy_from_devices_tmp)
self.sql.execute(""" DROP TABLE Devices_tmp;""")
# VIEWS
self.sql.execute(""" DROP VIEW IF EXISTS Events_Devices;""")
self.sql.execute(""" CREATE VIEW Events_Devices AS
SELECT *
FROM Events
LEFT JOIN Devices ON eve_MAC = devMac;
""")
self.sql.execute(""" DROP VIEW IF EXISTS LatestEventsPerMAC;""")
self.sql.execute("""CREATE VIEW LatestEventsPerMAC AS
WITH RankedEvents AS (
SELECT
e.*,
ROW_NUMBER() OVER (PARTITION BY e.eve_MAC ORDER BY e.eve_DateTime DESC) AS row_num
FROM Events AS e
)
SELECT
e.*,
d.*,
c.*
FROM RankedEvents AS e
LEFT JOIN Devices AS d ON e.eve_MAC = d.devMac
INNER JOIN CurrentScan AS c ON e.eve_MAC = c.cur_MAC
WHERE e.row_num = 1;""")
self.sql.execute(""" DROP VIEW IF EXISTS Sessions_Devices;""")
self.sql.execute("""CREATE VIEW Sessions_Devices AS SELECT * FROM Sessions LEFT JOIN "Devices" ON ses_MAC = devMac;""")
if dev_SourcePlugin_missing :
mylog('verbose', ["[upgradeDB] Adding dev_SourcePlugin to the Devices table"])
self.sql.execute("""
ALTER TABLE "Devices" ADD "dev_SourcePlugin" TEXT
""")
# -------------------------------------------------------------------------
# Settings table setup
@@ -284,96 +441,7 @@ class DB():
"par_Value" TEXT
);
""")
# -------------------------------------------------------------------------
# Nmap_Scan table setup DEPRECATED after 9/9/2024
# -------------------------------------------------------------------------
# indicates, if Nmap_Scan table is available
nmapScanMissing = self.sql.execute("""
SELECT name FROM sqlite_master WHERE type='table'
AND name='Nmap_Scan';
""").fetchone() == None
if nmapScanMissing == False:
# move data into the PLugins_Objects table
self.sql.execute("""INSERT INTO Plugins_Objects (
Plugin,
Object_PrimaryID,
Object_SecondaryID,
DateTimeCreated,
DateTimeChanged,
Watched_Value1,
Watched_Value2,
Watched_Value3,
Watched_Value4,
Status,
Extra,
UserData,
ForeignKey
)
SELECT
'NMAP' AS Plugin,
MAC AS Object_PrimaryID,
Port AS Object_SecondaryID,
Time AS DateTimeCreated,
DATETIME('now') AS DateTimeChanged,
State AS Watched_Value1,
Service AS Watched_Value2,
'' AS Watched_Value3,
'' AS Watched_Value4,
'watched-not-changed' AS Status,
Extra AS Extra,
Extra AS UserData,
MAC AS ForeignKey
FROM Nmap_Scan;""")
# Delete the Nmap_Scan table
self.sql.execute("DROP TABLE Nmap_Scan;")
nmapScanMissing = True
# -------------------------------------------------------------------------
# Nmap_Scan table setup DEPRECATED after 9/9/2024 cleanup above
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# Icon format migration table setup DEPRECATED after 9/9/2024 cleanup below
# -------------------------------------------------------------------------
sql_Icons = """ UPDATE Devices SET dev_Icon = '<i class="fa fa-' || dev_Icon || '"></i>'
WHERE dev_Icon NOT LIKE '<i class="fa fa-%'
AND dev_Icon NOT LIKE '<svg%'
AND dev_Icon NOT LIKE 'PGkg%'
AND dev_Icon NOT LIKE 'PHN%'
AND dev_Icon NOT IN ('', 'null')
"""
self.sql.execute(sql_Icons)
self.commitDB()
# Base64 conversion
self.sql.execute("SELECT dev_MAC, dev_Icon FROM Devices WHERE dev_Icon like '<%' ")
icons = self.sql.fetchall()
# Loop through the icons, encode them, and update the database
for icon_tuple in icons:
icon = icon_tuple[1]
# Encode the icon as base64
encoded_icon = base64.b64encode(icon.encode('utf-8')).decode('ascii')
# Update the database with the encoded icon
sql_update = f"""
UPDATE Devices
SET dev_Icon = '{encoded_icon}'
WHERE dev_MAC = '{icon_tuple[0]}'
"""
self.sql.execute(sql_update)
# -------------------------------------------------------------------------
# Icon format migration table setup DEPRECATED after 9/9/2024 cleanup above
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# Plugins tables setup
@@ -395,10 +463,18 @@ class DB():
Extra TEXT NOT NULL,
UserData TEXT NOT NULL,
ForeignKey TEXT NOT NULL,
SyncHubNodeName TEXT,
"HelpVal1" TEXT,
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT,
PRIMARY KEY("Index" AUTOINCREMENT)
); """
self.sql.execute(sql_Plugins_Objects)
# -----------------------------------------
# REMOVE after 6/6/2025 - START
# -----------------------------------------
# syncHubNodeName column
plug_SyncHubNodeName_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Objects') WHERE name='SyncHubNodeName'
@@ -421,6 +497,10 @@ class DB():
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal2" TEXT')
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal3" TEXT')
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal4" TEXT')
# -----------------------------------------
# REMOVE after 6/6/2025 - END
# -----------------------------------------
# Plugin execution results
sql_Plugins_Events = """ CREATE TABLE IF NOT EXISTS Plugins_Events(
@@ -438,10 +518,19 @@ class DB():
Extra TEXT NOT NULL,
UserData TEXT NOT NULL,
ForeignKey TEXT NOT NULL,
SyncHubNodeName TEXT,
"HelpVal1" TEXT,
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT,
PRIMARY KEY("Index" AUTOINCREMENT)
); """
self.sql.execute(sql_Plugins_Events)
# -----------------------------------------
# REMOVE after 6/6/2025 - START
# -----------------------------------------
# syncHubNodeName column
plug_SyncHubNodeName_missing = self.sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Events') WHERE name='SyncHubNodeName'
@@ -464,6 +553,10 @@ class DB():
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal2" TEXT')
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal3" TEXT')
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal4" TEXT')
# -----------------------------------------
# REMOVE after 6/6/2025 - END
# -----------------------------------------
# Plugin execution history
@@ -482,9 +575,18 @@ class DB():
Extra TEXT NOT NULL,
UserData TEXT NOT NULL,
ForeignKey TEXT NOT NULL,
SyncHubNodeName TEXT,
"HelpVal1" TEXT,
"HelpVal2" TEXT,
"HelpVal3" TEXT,
"HelpVal4" TEXT,
PRIMARY KEY("Index" AUTOINCREMENT)
); """
self.sql.execute(sql_Plugins_History)
# -----------------------------------------
# REMOVE after 6/6/2025 - START
# -----------------------------------------
# syncHubNodeName column
plug_SyncHubNodeName_missing = self.sql.execute ("""
@@ -509,6 +611,9 @@ class DB():
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal3" TEXT')
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal4" TEXT')
# -----------------------------------------
# REMOVE after 6/6/2025 - END
# -----------------------------------------
# -------------------------------------------------------------------------
# Plugins_Language_Strings table setup
@@ -573,7 +678,7 @@ class DB():
d.*,
c.*
FROM RankedEvents AS e
LEFT JOIN Devices AS d ON e.eve_MAC = d.dev_MAC
LEFT JOIN Devices AS d ON e.eve_MAC = d.devMac
INNER JOIN CurrentScan AS c ON e.eve_MAC = c.cur_MAC
WHERE e.row_num = 1;
""")

View File

@@ -25,16 +25,16 @@ class Device_obj:
# Get all with unknown names
def getUnknown(self):
self.db.sql.execute("""
SELECT * FROM Devices WHERE dev_Name in ("(unknown)", "(name not found)", "" )
SELECT * FROM Devices WHERE devName in ("(unknown)", "(name not found)", "" )
""")
return self.db.sql.fetchall()
# Get specific column value based on dev_MAC
def getValueWithMac(self, column_name, dev_MAC):
# Get specific column value based on devMac
def getValueWithMac(self, column_name, devMac):
query = f"SELECT {column_name} FROM Devices WHERE dev_MAC = ?"
query = f"SELECT {column_name} FROM Devices WHERE devMac = ?"
self.db.sql.execute(query, (dev_MAC,))
self.db.sql.execute(query, (devMac,))
result = self.db.sql.fetchone()
@@ -102,12 +102,12 @@ def print_scan_stats(db):
query = """
SELECT
(SELECT COUNT(*) FROM CurrentScan) AS devices_detected,
(SELECT COUNT(*) FROM CurrentScan WHERE NOT EXISTS (SELECT 1 FROM Devices WHERE dev_MAC = cur_MAC)) AS new_devices,
(SELECT COUNT(*) FROM Devices WHERE dev_AlertDeviceDown != 0 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE dev_MAC = cur_MAC)) AS down_alerts,
(SELECT COUNT(*) FROM Devices WHERE dev_AlertDeviceDown != 0 AND dev_PresentLastScan = 1 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE dev_MAC = cur_MAC)) AS new_down_alerts,
(SELECT COUNT(*) FROM Devices WHERE dev_PresentLastScan = 0) AS new_connections,
(SELECT COUNT(*) FROM Devices WHERE dev_PresentLastScan = 1 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE dev_MAC = cur_MAC)) AS disconnections,
(SELECT COUNT(*) FROM Devices, CurrentScan WHERE dev_MAC = cur_MAC AND dev_LastIP <> cur_IP) AS ip_changes,
(SELECT COUNT(*) FROM CurrentScan WHERE NOT EXISTS (SELECT 1 FROM Devices WHERE devMac = cur_MAC)) AS new_devices,
(SELECT COUNT(*) FROM Devices WHERE devAlertDown != 0 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE devMac = cur_MAC)) AS down_alerts,
(SELECT COUNT(*) FROM Devices WHERE devAlertDown != 0 AND devPresentLastScan = 1 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE devMac = cur_MAC)) AS new_down_alerts,
(SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 0) AS new_connections,
(SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 1 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE devMac = cur_MAC)) AS disconnections,
(SELECT COUNT(*) FROM Devices, CurrentScan WHERE devMac = cur_MAC AND devLastIP <> cur_IP) AS ip_changes,
cur_ScanMethod,
COUNT(*) AS scan_method_count
FROM CurrentScan
@@ -175,7 +175,7 @@ def create_new_devices (db):
SELECT cur_MAC, cur_IP, '{startTime}', 'New Device', cur_Vendor, 1
FROM CurrentScan
WHERE NOT EXISTS (SELECT 1 FROM Devices
WHERE dev_MAC = cur_MAC)
WHERE devMac = cur_MAC)
"""
@@ -197,33 +197,33 @@ def create_new_devices (db):
mylog('debug','[New Devices] 2 Create devices')
# default New Device values preparation
newDevColumns = """dev_AlertEvents,
dev_AlertDeviceDown,
dev_PresentLastScan,
dev_Archived,
dev_NewDevice,
dev_SkipRepeated,
dev_ScanCycle,
dev_Owner,
dev_Favorite,
dev_Group,
dev_Comments,
dev_LogEvents,
dev_Location"""
newDevColumns = """devAlertEvents,
devAlertDown,
devPresentLastScan,
devIsArchived,
devIsNew,
devSkipRepeated,
devScan,
devOwner,
devFavorite,
devGroup,
devComments,
devLogEvents,
devLocation"""
newDevDefaults = f"""{get_setting_value('NEWDEV_dev_AlertEvents')},
{get_setting_value('NEWDEV_dev_AlertDeviceDown')},
{get_setting_value('NEWDEV_dev_PresentLastScan')},
{get_setting_value('NEWDEV_dev_Archived')},
{get_setting_value('NEWDEV_dev_NewDevice')},
{get_setting_value('NEWDEV_dev_SkipRepeated')},
{get_setting_value('NEWDEV_dev_ScanCycle')},
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Owner'))}',
{get_setting_value('NEWDEV_dev_Favorite')},
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Group'))}',
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Comments'))}',
{get_setting_value('NEWDEV_dev_LogEvents')},
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Location'))}'"""
newDevDefaults = f"""{get_setting_value('NEWDEV_devAlertEvents')},
{get_setting_value('NEWDEV_devAlertDown')},
{get_setting_value('NEWDEV_devPresentLastScan')},
{get_setting_value('NEWDEV_devIsArchived')},
{get_setting_value('NEWDEV_devIsNew')},
{get_setting_value('NEWDEV_devSkipRepeated')},
{get_setting_value('NEWDEV_devScan')},
'{sanitize_SQL_input(get_setting_value('NEWDEV_devOwner'))}',
{get_setting_value('NEWDEV_devFavorite')},
'{sanitize_SQL_input(get_setting_value('NEWDEV_devGroup'))}',
'{sanitize_SQL_input(get_setting_value('NEWDEV_devComments'))}',
{get_setting_value('NEWDEV_devLogEvents')},
'{sanitize_SQL_input(get_setting_value('NEWDEV_devLocation'))}'"""
# Fetch data from CurrentScan skipping ignored devices by IP and MAC
query = f"""SELECT cur_MAC, cur_Name, cur_Vendor, cur_ScanMethod, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type
@@ -238,28 +238,28 @@ def create_new_devices (db):
# Handle NoneType
cur_Name = cur_Name.strip() if cur_Name else '(unknown)'
cur_Type = cur_Type.strip() if cur_Type else get_setting_value("NEWDEV_dev_DeviceType")
cur_Type = cur_Type.strip() if cur_Type else get_setting_value("NEWDEV_devType")
cur_NetworkNodeMAC = cur_NetworkNodeMAC.strip() if cur_NetworkNodeMAC else ''
cur_NetworkNodeMAC = cur_NetworkNodeMAC if cur_NetworkNodeMAC and cur_MAC != "Internet" else (get_setting_value("NEWDEV_dev_Network_Node_MAC_ADDR") if cur_MAC != "Internet" else "null")
cur_NetworkNodeMAC = cur_NetworkNodeMAC if cur_NetworkNodeMAC and cur_MAC != "Internet" else (get_setting_value("NEWDEV_devParentMAC") if cur_MAC != "Internet" else "null")
cur_SyncHubNodeName = cur_SyncHubNodeName if cur_SyncHubNodeName and cur_SyncHubNodeName != "null" else (get_setting_value("SYNC_node_name"))
# Preparing the individual insert statement
sqlQuery = f"""INSERT OR IGNORE INTO Devices
(
dev_MAC,
dev_name,
dev_Vendor,
dev_LastIP,
dev_FirstConnection,
dev_LastConnection,
dev_SyncHubNodeName,
dev_GUID,
dev_Network_Node_MAC_ADDR,
dev_Network_Node_port,
dev_NetworkSite,
dev_SSID,
dev_DeviceType,
dev_SourcePlugin,
devMac,
devName,
devVendor,
devLastIP,
devFirstConnection,
devLastConnection,
devSyncHubNode,
devGUID,
devParentMAC,
devParentPort,
devSite,
devSSID,
devType,
devSourcePlugin,
{newDevColumns}
)
VALUES
@@ -297,140 +297,140 @@ def update_devices_data_from_scan (db):
# Update Last Connection
mylog('debug', '[Update Devices] 1 Last Connection')
sql.execute(f"""UPDATE Devices SET dev_LastConnection = '{startTime}',
dev_PresentLastScan = 1
WHERE dev_PresentLastScan = 0
sql.execute(f"""UPDATE Devices SET devLastConnection = '{startTime}',
devPresentLastScan = 1
WHERE devPresentLastScan = 0
AND EXISTS (SELECT 1 FROM CurrentScan
WHERE dev_MAC = cur_MAC) """)
WHERE devMac = cur_MAC) """)
# Clean no active devices
mylog('debug', '[Update Devices] 2 Clean no active devices')
sql.execute("""UPDATE Devices SET dev_PresentLastScan = 0
sql.execute("""UPDATE Devices SET devPresentLastScan = 0
WHERE NOT EXISTS (SELECT 1 FROM CurrentScan
WHERE dev_MAC = cur_MAC) """)
WHERE devMac = cur_MAC) """)
# Update IP
mylog('debug', '[Update Devices] - cur_IP -> dev_LastIP (always updated)')
mylog('debug', '[Update Devices] - cur_IP -> devLastIP (always updated)')
sql.execute("""UPDATE Devices
SET dev_LastIP = (SELECT cur_IP FROM CurrentScan
WHERE dev_MAC = cur_MAC)
SET devLastIP = (SELECT cur_IP FROM CurrentScan
WHERE devMac = cur_MAC)
WHERE EXISTS (SELECT 1 FROM CurrentScan
WHERE dev_MAC = cur_MAC) """)
WHERE devMac = cur_MAC) """)
# Update only devices with empty or NULL vendors
mylog('debug', '[Update Devices] - cur_Vendor -> (if empty) dev_Vendor')
mylog('debug', '[Update Devices] - cur_Vendor -> (if empty) devVendor')
sql.execute("""UPDATE Devices
SET dev_Vendor = (
SET devVendor = (
SELECT cur_Vendor
FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
WHERE Devices.devMac = CurrentScan.cur_MAC
)
WHERE
(dev_Vendor IS NULL OR dev_Vendor IN ("", "null"))
(devVendor IS NULL OR devVendor IN ("", "null"))
AND EXISTS (
SELECT 1
FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
WHERE Devices.devMac = CurrentScan.cur_MAC
)""")
# Update only devices with empty or NULL dev_Network_Node_port
mylog('debug', '[Update Devices] - (if not empty) cur_Port -> dev_Network_Node_port')
# Update only devices with empty or NULL devParentPort
mylog('debug', '[Update Devices] - (if not empty) cur_Port -> devParentPort')
sql.execute("""UPDATE Devices
SET dev_Network_Node_port = (
SET devParentPort = (
SELECT cur_Port
FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
WHERE Devices.devMac = CurrentScan.cur_MAC
)
WHERE EXISTS (
SELECT 1
FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
WHERE Devices.devMac = CurrentScan.cur_MAC
AND CurrentScan.cur_Port IS NOT NULL AND CurrentScan.cur_Port NOT IN ("", "null")
)""")
# Update only devices with empty or NULL dev_Network_Node_MAC_ADDR
mylog('debug', '[Update Devices] - (if not empty) cur_NetworkNodeMAC -> dev_Network_Node_MAC_ADDR')
# Update only devices with empty or NULL devParentMAC
mylog('debug', '[Update Devices] - (if not empty) cur_NetworkNodeMAC -> devParentMAC')
sql.execute("""UPDATE Devices
SET dev_Network_Node_MAC_ADDR = (
SET devParentMAC = (
SELECT cur_NetworkNodeMAC
FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
WHERE Devices.devMac = CurrentScan.cur_MAC
)
WHERE EXISTS (
SELECT 1
FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
WHERE Devices.devMac = CurrentScan.cur_MAC
AND CurrentScan.cur_NetworkNodeMAC IS NOT NULL AND CurrentScan.cur_NetworkNodeMAC NOT IN ("", "null")
)""")
# Update only devices with empty or NULL dev_NetworkSite
mylog('debug', '[Update Devices] - (if not empty) cur_NetworkSite -> (if empty) dev_NetworkSite')
# Update only devices with empty or NULL devSite
mylog('debug', '[Update Devices] - (if not empty) cur_NetworkSite -> (if empty) devSite')
sql.execute("""UPDATE Devices
SET dev_NetworkSite = (
SET devSite = (
SELECT cur_NetworkSite
FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
WHERE Devices.devMac = CurrentScan.cur_MAC
)
WHERE
(dev_NetworkSite IS NULL OR dev_NetworkSite IN ("", "null"))
(devSite IS NULL OR devSite IN ("", "null"))
AND EXISTS (
SELECT 1
FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
WHERE Devices.devMac = CurrentScan.cur_MAC
AND CurrentScan.cur_NetworkSite IS NOT NULL AND CurrentScan.cur_NetworkSite NOT IN ("", "null")
)""")
# Update only devices with empty or NULL dev_SSID
mylog('debug', '[Update Devices] - (if not empty) cur_SSID -> (if empty) dev_SSID')
# Update only devices with empty or NULL devSSID
mylog('debug', '[Update Devices] - (if not empty) cur_SSID -> (if empty) devSSID')
sql.execute("""UPDATE Devices
SET dev_SSID = (
SET devSSID = (
SELECT cur_SSID
FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
WHERE Devices.devMac = CurrentScan.cur_MAC
)
WHERE
(dev_SSID IS NULL OR dev_SSID IN ("", "null"))
(devSSID IS NULL OR devSSID IN ("", "null"))
AND EXISTS (
SELECT 1
FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
WHERE Devices.devMac = CurrentScan.cur_MAC
AND CurrentScan.cur_SSID IS NOT NULL AND CurrentScan.cur_SSID NOT IN ("", "null")
)""")
# Update only devices with empty or NULL dev_DeviceType
mylog('debug', '[Update Devices] - (if not empty) cur_Type -> (if empty) dev_DeviceType')
# Update only devices with empty or NULL devType
mylog('debug', '[Update Devices] - (if not empty) cur_Type -> (if empty) devType')
sql.execute("""UPDATE Devices
SET dev_DeviceType = (
SET devType = (
SELECT cur_Type
FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
WHERE Devices.devMac = CurrentScan.cur_MAC
)
WHERE
(dev_DeviceType IS NULL OR dev_DeviceType IN ("", "null"))
(devType IS NULL OR devType IN ("", "null"))
AND EXISTS (
SELECT 1
FROM CurrentScan
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
WHERE Devices.devMac = CurrentScan.cur_MAC
AND CurrentScan.cur_Type IS NOT NULL AND CurrentScan.cur_Type NOT IN ("", "null")
)""")
# Update (unknown) or (name not found) Names if available
mylog('debug','[Update Devices] - (if not empty) cur_Name -> (if empty) dev_NAME')
mylog('debug','[Update Devices] - (if not empty) cur_Name -> (if empty) devName')
sql.execute (""" UPDATE Devices
SET dev_NAME = COALESCE((
SET devName = COALESCE((
SELECT cur_Name
FROM CurrentScan
WHERE cur_MAC = dev_MAC
WHERE cur_MAC = devMac
AND cur_Name IS NOT NULL
AND cur_Name <> 'null'
AND cur_Name <> ''
), dev_NAME)
WHERE (dev_NAME IN ('(unknown)', '(name not found)', '')
OR dev_NAME IS NULL)
), devName)
WHERE (devName IN ('(unknown)', '(name not found)', '')
OR devName IS NULL)
AND EXISTS (
SELECT 1
FROM CurrentScan
WHERE cur_MAC = dev_MAC
WHERE cur_MAC = devMac
AND cur_Name IS NOT NULL
AND cur_Name <> 'null'
AND cur_Name <> ''
@@ -439,48 +439,48 @@ def update_devices_data_from_scan (db):
# Update VENDORS
recordsToUpdate = []
query = """SELECT * FROM Devices
WHERE dev_Vendor = '(unknown)' OR dev_Vendor =''
OR dev_Vendor IS NULL"""
WHERE devVendor = '(unknown)' OR devVendor =''
OR devVendor IS NULL"""
for device in sql.execute (query) :
vendor = query_MAC_vendor (device['dev_MAC'])
vendor = query_MAC_vendor (device['devMac'])
if vendor != -1 and vendor != -2 :
recordsToUpdate.append ([vendor, device['dev_MAC']])
recordsToUpdate.append ([vendor, device['devMac']])
if len(recordsToUpdate) > 0:
sql.executemany ("UPDATE Devices SET dev_Vendor = ? WHERE dev_MAC = ? ", recordsToUpdate )
sql.executemany ("UPDATE Devices SET devVendor = ? WHERE devMac = ? ", recordsToUpdate )
# Guess ICONS
recordsToUpdate = []
query = """SELECT * FROM Devices
WHERE dev_Icon in ('', 'null')
OR dev_Icon IS NULL"""
default_icon = get_setting_value('NEWDEV_dev_Icon')
WHERE devIcon in ('', 'null')
OR devIcon IS NULL"""
default_icon = get_setting_value('NEWDEV_devIcon')
for device in sql.execute (query) :
# Conditional logic for dev_Icon guessing
dev_Icon = guess_icon(device['dev_Vendor'], device['dev_MAC'], device['dev_LastIP'], device['dev_Name'], default_icon)
# Conditional logic for devIcon guessing
devIcon = guess_icon(device['devVendor'], device['devMac'], device['devLastIP'], device['devName'], default_icon)
recordsToUpdate.append ([dev_Icon, device['dev_MAC']])
recordsToUpdate.append ([devIcon, device['devMac']])
if len(recordsToUpdate) > 0:
sql.executemany ("UPDATE Devices SET dev_Icon = ? WHERE dev_MAC = ? ", recordsToUpdate )
sql.executemany ("UPDATE Devices SET devIcon = ? WHERE devMac = ? ", recordsToUpdate )
# Guess Type
recordsToUpdate = []
query = """SELECT * FROM Devices
WHERE dev_DeviceType in ('', 'null')
OR dev_DeviceType IS NULL"""
default_type = get_setting_value('NEWDEV_dev_DeviceType')
WHERE devType in ('', 'null')
OR devType IS NULL"""
default_type = get_setting_value('NEWDEV_devType')
for device in sql.execute (query) :
# Conditional logic for dev_Icon guessing
dev_DeviceType = guess_type(device['dev_Vendor'], device['dev_MAC'], device['dev_LastIP'], device['dev_Name'], default_type)
# Conditional logic for devIcon guessing
devType = guess_type(device['devVendor'], device['devMac'], device['devLastIP'], device['devName'], default_type)
recordsToUpdate.append ([dev_DeviceType, device['dev_MAC']])
recordsToUpdate.append ([devType, device['devMac']])
if len(recordsToUpdate) > 0:
sql.executemany ("UPDATE Devices SET dev_DeviceType = ? WHERE dev_MAC = ? ", recordsToUpdate )
sql.executemany ("UPDATE Devices SET devType = ? WHERE devMac = ? ", recordsToUpdate )
mylog('debug','[Update Devices] Update devices end')
@@ -504,7 +504,7 @@ def update_devices_names (db):
foundPholus = 0
# Gen unknown devices
sql.execute ("SELECT * FROM Devices WHERE dev_Name IN ('(unknown)','', '(name not found)') AND dev_LastIP <> '-'")
sql.execute ("SELECT * FROM Devices WHERE devName IN ('(unknown)','', '(name not found)') AND devLastIP <> '-'")
unknownDevices = sql.fetchall()
db.commitDB()
@@ -528,7 +528,7 @@ def update_devices_names (db):
newName = nameNotFound
# Resolve device name with DiG
newName = resolve_device_name_dig (device['dev_MAC'], device['dev_LastIP'])
newName = resolve_device_name_dig (device['devMac'], device['devLastIP'])
# count
if newName != nameNotFound:
@@ -536,21 +536,21 @@ def update_devices_names (db):
# Resolve device name with AVAHISCAN plugin data
if newName == nameNotFound:
newName = get_device_name_mdns(db, device['dev_MAC'], device['dev_LastIP'])
newName = get_device_name_mdns(db, device['devMac'], device['devLastIP'])
if newName != nameNotFound:
foundmDNSLookup += 1
# Resolve device name with NSLOOKUP plugin data
if newName == nameNotFound:
newName = get_device_name_nslookup(db, device['dev_MAC'], device['dev_LastIP'])
newName = get_device_name_nslookup(db, device['devMac'], device['devLastIP'])
if newName != nameNotFound:
foundNsLookup += 1
# Resolve device name with NSLOOKUP plugin data
if newName == nameNotFound:
newName = get_device_name_nbtlookup(db, device['dev_MAC'], device['dev_LastIP'])
newName = get_device_name_nbtlookup(db, device['devMac'], device['devLastIP'])
if newName != nameNotFound:
foundNbtLookup += 1
@@ -560,10 +560,10 @@ def update_devices_names (db):
if newName == nameNotFound:
# Try MAC matching
newName = resolve_device_name_pholus (device['dev_MAC'], device['dev_LastIP'], pholusResults, nameNotFound, False)
newName = resolve_device_name_pholus (device['devMac'], device['devLastIP'], pholusResults, nameNotFound, False)
# Try IP matching
if newName == nameNotFound:
newName = resolve_device_name_pholus (device['dev_MAC'], device['dev_LastIP'], pholusResults, nameNotFound, True)
newName = resolve_device_name_pholus (device['devMac'], device['devLastIP'], pholusResults, nameNotFound, True)
# count
if newName != nameNotFound:
@@ -574,22 +574,22 @@ def update_devices_names (db):
notFound += 1
# if dev_Name is the same as what we will change it to, take no action
# if devName is the same as what we will change it to, take no action
# this mitigates a race condition which would overwrite a users edits that occured since the select earlier
if device['dev_Name'] != nameNotFound:
recordsNotFound.append (["(name not found)", device['dev_MAC']])
if device['devName'] != nameNotFound:
recordsNotFound.append (["(name not found)", device['devMac']])
else:
# name was found with DiG or Pholus
recordsToUpdate.append ([newName, device['dev_MAC']])
recordsToUpdate.append ([newName, device['devMac']])
# Print log
mylog('verbose', [f'[Update Device Name] Names Found (DiG/mDNS/NSLOOKUP/NBTSCAN/Pholus): {len(recordsToUpdate)} ({foundDig}/{foundmDNSLookup}/{foundNsLookup}/{foundNbtLookup}/{foundPholus})'] )
mylog('verbose', [f'[Update Device Name] Names Not Found : {notFound}'] )
# update not found devices with (name not found)
sql.executemany ("UPDATE Devices SET dev_Name = ? WHERE dev_MAC = ? ", recordsNotFound )
sql.executemany ("UPDATE Devices SET devName = ? WHERE devMac = ? ", recordsNotFound )
# update names of devices which we were bale to resolve
sql.executemany ("UPDATE Devices SET dev_Name = ? WHERE dev_MAC = ? ", recordsToUpdate )
sql.executemany ("UPDATE Devices SET devName = ? WHERE devMac = ? ", recordsToUpdate )
db.commitDB()
#-------------------------------------------------------------------------------

View File

@@ -0,0 +1,132 @@
import graphene
from graphene import ObjectType, String, Int, Boolean, Field, List
import json
import sys
# Register NetAlertX directories
INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/server"])
from logger import mylog
from const import apiPath
# Define a base URL with the user's home directory
folder = apiPath
# Load your JSON data
with open(folder + 'table_devices.json', 'r') as f:
devices_data = json.load(f)["data"]
# mylog('none', [f'[graphql_schema] devices_data {devices_data}'])
# Device ObjectType
class Device(ObjectType):
rowid = Int()
devMac = String() # This should match devMac, not devMac
devName = String() # This should match devName, not devName
devOwner = String() # This should match devOwner, not devOwner
devType = String() # This should match devType, not devType
devVendor = String() # This should match devVendor, not devVendor
devFavorite = Int() # This should match devFavorite, not devFavorite
devGroup = String() # This should match devGroup, not devGroup
devComments = String() # This should match devComments, not devComments
devFirstConnection = String() # This should match devFirstConnection, not devFirstConnection
devLastConnection = String() # This should match devLastConnection, not devLastConnection
devLastIP = String() # This should match devLastIP, not devLastIP
devStaticIP = Int() # This should match devStaticIP, not devStaticIP
devScan = Int() # This should match devScan, not devScan
devLogEvents = Int() # This should match devLogEvents, not devLogEvents
devAlertEvents = Int() # This should match devAlertEvents, not devAlertEvents
devAlertDeviceDown = Int() # This should match devAlertDeviceDown, not devAlertDown
devSkipRepeated = Int() # This should match devSkipRepeated, not devSkipRepeated
devLastNotification = String() # This should match devLastNotification, not devLastNotification
devPresentLastScan = Int() # This should match devPresentLastScan, not devPresentLastScan
devNewDevice = Int() # This should match devNewDevice, not devIsNew
devLocation = String() # This should match devLocation, not devLocation
devArchived = Int() # This should match devArchived, not devIsArchived
devNetworkNodeMACADDR = String() # This should match devNetworkNodeMACADDR, not devParentMAC
devNetworkNodePort = String() # This should match devNetworkNodePort, not devParentPort
devIcon = String() # This should match devIcon, not devIcon
devGUID = String() # This should match devGUID, not devGUID
devNetworkSite = String() # This should match devNetworkSite, not devSite
devSSID = String() # This should match devSSID, not devSSID
devSyncHubNodeName = String() # This should match devSyncHubNodeName, not devSyncHubNode
devSourcePlugin = String() # This should match devSourcePlugin, not devSourcePlugin
# Query ObjectType
class Query(ObjectType):
devices = List(Device)
def resolve_devices(self, info):
# Map the data to match the GraphQL schema's camelCase
mapped_devices = []
for device in devices_data:
mapped_device = {
'rowid': device['rowid'],
'devMac': device['devMac'], # Mapping from snake_case to camelCase
'devName': device['devName'],
'devOwner': device['devOwner'],
'devType': device['devType'],
'devVendor': device['devVendor'],
'devFavorite': device['devFavorite'],
'devGroup': device['devGroup'],
'devComments': device['devComments'],
'devFirstConnection': device['devFirstConnection'],
'devLastConnection': device['devLastConnection'],
'devLastIP': device['devLastIP'],
'devStaticIP': device['devStaticIP'],
'devScan': device['devScan'],
'devLogEvents': device['devLogEvents'],
'devAlertEvents': device['devAlertEvents'],
'devAlertDown': device['devAlertDown'],
'devSkipRepeated': device['devSkipRepeated'],
'devLastNotification': device['devLastNotification'],
'devPresentLastScan': device['devPresentLastScan'],
'devIsNew': device['devIsNew'],
'devLocation': device['devLocation'],
'devIsArchived': device['devIsArchived'],
'devParentMAC': device['devParentMAC'],
'devParentPort': device['devParentPort'],
'devIcon': device['devIcon'],
'devGUID': device['devGUID'],
'devSite': device['devSite'],
'devSSID': device['devSSID'],
'devSyncHubNode': device['devSyncHubNode'],
'devSourcePlugin': device['devSourcePlugin']
}
mapped_devices.append(mapped_device)
return mapped_devices
# Schema Definition
devicesSchema = graphene.Schema(query=Query)
# $.ajax({
# url: 'php/server/query_graphql.php', // The PHP endpoint that proxies to the GraphQL server
# type: 'POST',
# contentType: 'application/json', // Send the data as JSON
# data: JSON.stringify({
# query: `
# query {
# devices {
# devMac
# devName
# devLastConnection
# devArchived
# }
# }
# `, // GraphQL query for plugins
# variables: {} // Optional, pass variables if needed
# }),
# success: function(response) {
# console.log('GraphQL Response:', response);
# // Handle the GraphQL response here
# },
# error: function(xhr, status, error) {
# console.error('AJAX Error:', error);
# // Handle errors here
# }
# });

View File

@@ -0,0 +1,47 @@
import threading
from flask import Flask, request, jsonify
from .graphql_schema import devicesSchema
from graphene import Schema
import sys
# Global variable to track the server thread
server_thread = None
# Register NetAlertX directories
INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/server"])
from logger import mylog
from helper import get_setting_value
app = Flask(__name__)
GRAPHQL_PORT = get_setting_value("GRAPHQL_PORT")
API_TOKEN = get_setting_value("API_TOKEN")
@app.route("/graphql", methods=["POST"])
def graphql_endpoint():
# Check for API token in headers
token = request.headers.get("Authorization")
if token != f"Bearer {API_TOKEN}":
mylog('none', [f'[graphql_server] Unauthorized access attempt'])
return jsonify({"error": "Unauthorized"}), 401
data = request.get_json()
mylog('none', [f'[graphql_server] data: {data}'])
# Use the schema to execute the GraphQL query
result = devicesSchema.execute(data.get("query"), variables=data.get("variables"))
mylog('none', [f'[graphql_server] result: {result}'])
# Return the data from the query in JSON format
return jsonify(result.data)
def start_server():
"""Function to start the GraphQL server in a background thread."""
mylog('none', [f'[graphql_server] Started'])
# Start the Flask app in a separate thread
thread = threading.Thread(target=lambda: app.run(host="0.0.0.0", port=GRAPHQL_PORT, debug=True, use_reloader=False))
thread.start()

View File

@@ -15,6 +15,8 @@ from pathlib import Path
import requests
import base64
import hashlib
import random
import string
import conf
@@ -904,6 +906,11 @@ def extract_ip_addresses(text):
ip_addresses = re.findall(ip_pattern, text)
return ip_addresses
def generate_random_string(length):
characters = string.ascii_letters + string.digits
return ''.join(random.choice(characters) for _ in range(length))
#-------------------------------------------------------------------------------
# JSON methods
#-------------------------------------------------------------------------------

View File

@@ -12,7 +12,7 @@ import re
import conf
from const import fullConfPath, applicationPath, fullConfFolder
from helper import collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, updateState, setting_value_to_python_type, timeNowTZ, get_setting_value
from helper import collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, updateState, setting_value_to_python_type, timeNowTZ, get_setting_value, generate_random_string
from logger import mylog
from api import update_api
from scheduler import schedule_class
@@ -148,9 +148,11 @@ def importConfigs (db, all_plugins):
conf.HRS_TO_KEEP_NEWDEV = ccd('HRS_TO_KEEP_NEWDEV', 0 , c_d, 'Keep new devices for', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
conf.HRS_TO_KEEP_OFFDEV = ccd('HRS_TO_KEEP_OFFDEV', 0 , c_d, 'Keep offline devices for', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
conf.CLEAR_NEW_FLAG = ccd('CLEAR_NEW_FLAG', 0 , c_d, 'Clear new flag', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
conf.API_CUSTOM_SQL = ccd('API_CUSTOM_SQL', 'SELECT * FROM Devices WHERE dev_PresentLastScan = 0' , c_d, 'Custom endpoint', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General')
conf.API_CUSTOM_SQL = ccd('API_CUSTOM_SQL', 'SELECT * FROM Devices WHERE devPresentLastScan = 0' , c_d, 'Custom endpoint', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General')
conf.VERSION = ccd('VERSION', '' , c_d, 'Version', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{ "readonly": "true" }] ,"transformers": []}]}', '', 'General')
conf.NETWORK_DEVICE_TYPES = ccd('NETWORK_DEVICE_TYPES', ['AP', 'Gateway', 'Firewall', 'Hypervisor', 'Powerline', 'Switch', 'WLAN', 'PLC', 'Router','USB LAN Adapter', 'USB WIFI Adapter', 'Internet'] , c_d, 'Network device types', '{"dataType":"array","elements":[{"elementType":"input","elementOptions":[{"placeholder":"Enter value"},{"suffix":"_in"},{"cssClasses":"col-sm-10"},{"prefillValue":"null"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":["_in"]},{"separator":""},{"cssClasses":"col-xs-12"},{"onClick":"addList(this,false)"},{"getStringKey":"Gen_Add"}],"transformers":[]},{"elementType":"select", "elementHasInputValue":1,"elementOptions":[{"multiple":"true"},{"readonly":"true"},{"editable":"true"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":[]},{"separator":""},{"cssClasses":"col-xs-6"},{"onClick":"removeAllOptions(this)"},{"getStringKey":"Gen_Remove_All"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":[]},{"separator":""},{"cssClasses":"col-xs-6"},{"onClick":"removeFromList(this)"},{"getStringKey":"Gen_Remove_Last"}],"transformers":[]}]}', '[]', 'General')
conf.GRAPHQL_PORT = ccd('GRAPHQL_PORT', 20212 , c_d, 'GraphQL port', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', '[]', 'General')
conf.API_TOKEN = ccd('API_TOKEN', 't_' + generate_random_string(20) , c_d, 'API token', '{"dataType": "string","elements": [{"elementType": "input","elementHasInputValue": 1,"elementOptions": [{ "cssClasses": "col-xs-12" }],"transformers": []},{"elementType": "button","elementOptions": [{ "getStringKey": "Gen_Generate" },{ "customParams": "API_TOKEN" },{ "onClick": "generateApiToken(this, 20)" },{ "cssClasses": "col-xs-12" }],"transformers": []}]}', '[]', 'General')
# UI
conf.UI_LANG = ccd('UI_LANG', 'English' , c_d, 'Language Interface', '{"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}', "['English', 'German', 'Spanish', 'French', 'Norwegian', 'Russian', 'Italian (it_it)', 'Portuguese (pt_br)', 'Polish (pl_pl)', 'Chinese (zh_cn)', 'Turkish (tr_tr)', 'Czech (cs_cz)', 'Arabic (ar_ar)', 'Catalan (ca_ca)' ]", 'UI')
@@ -399,21 +401,50 @@ def read_config_file(filename):
# 🤔Idea/TODO: Check and compare versions/timestamps amd only perform a replacement if config/version older than...
replacements = {
r'\bREPORT_TO\b': 'SMTP_REPORT_TO',
r'\bSYNC_api_token\b': 'API_TOKEN',
r'\bREPORT_FROM\b': 'SMTP_REPORT_FROM',
r'\bPIALERT_WEB_PROTECTION\b': 'SETPWD_enable_password',
r'\bPIALERT_WEB_PASSWORD\b': 'SETPWD_password',
r'REPORT_MAIL=True': 'SMTP_RUN=\'on_notification\'',
r'REPORT_APPRISE=True': 'APPRISE_RUN=\'on_notification\'',
r'REPORT_NTFY=True': 'NTFY_RUN=\'on_notification\'',
r'REPORT_WEBHOOK=True': 'WEBHOOK_RUN=\'on_notification\'',
r'REPORT_PUSHSAFER=True': 'PUSHSAFER_RUN=\'on_notification\'',
r'REPORT_MQTT=True': 'MQTT_RUN=\'on_notification\'',
r'REPORT_MAIL=True': "SMTP_RUN='on_notification'",
r'REPORT_APPRISE=True': "APPRISE_RUN='on_notification'",
r'REPORT_NTFY=True': "NTFY_RUN='on_notification'",
r'REPORT_WEBHOOK=True': "WEBHOOK_RUN='on_notification'",
r'REPORT_PUSHSAFER=True': "PUSHSAFER_RUN='on_notification'",
r'REPORT_MQTT=True': "MQTT_RUN='on_notification'",
r'PIHOLE_CMD=': 'PIHOLE_CMD_OLD=',
r'\bINCLUDED_SECTIONS\b': 'NTFPRCS_INCLUDED_SECTIONS',
r'\bDIG_GET_IP_ARG\b': 'INTRNT_DIG_GET_IP_ARG',
r'\/home/pi/pialert\b': '/app'
r'dev_MAC': 'devMac',
r'dev_Name': 'devName',
r'dev_Favorite': 'devFavorite',
r'dev_Group': 'devGroup',
r'dev_Comments': 'devComments',
r'dev_FirstConnection': 'devFirstConnection',
r'dev_LastConnection': 'devLastConnection',
r'dev_LastIP': 'devLastIP',
r'dev_StaticIP': 'devStaticIP',
r'dev_ScanCycle': 'devScan',
r'dev_LogEvents': 'devLogEvents',
r'dev_AlertEvents': 'devAlertEvents',
r'dev_AlertDeviceDown': 'devAlertDown',
r'dev_SkipRepeated': 'devSkipRepeated',
r'dev_LastNotification': 'devLastNotification',
r'dev_PresentLastScan': 'devPresentLastScan',
r'dev_NewDevice': 'devIsNew',
r'dev_Location': 'devLocation',
r'dev_Archived': 'devIsArchived',
r'dev_Network_Node_MAC_ADDR': 'devParentMAC',
r'dev_Network_Node_port': 'devParentPort',
r'dev_Icon': 'devIcon',
r'dev_GUID': 'devGUID',
r'dev_NetworkSite': 'devSite',
r'dev_SSID': 'devSSID',
r'dev_SyncHubNodeName': 'devSyncHubNode',
r'dev_SourcePlugin': 'devSourcePlugin',
r'/home/pi/pialert\b': '/app'
}
def renameSettings(config_file):
# Check if the file contains any of the old setting code names
contains_old_settings = False

View File

@@ -85,7 +85,7 @@ def void_ghost_disconnections (db):
AND eve_MAC IN (
SELECT Events.eve_MAC
FROM CurrentScan, Devices, Events
WHERE dev_MAC = cur_MAC
WHERE devMac = cur_MAC
AND eve_MAC = cur_MAC
AND eve_EventType = 'Disconnected'
AND eve_DateTime >= DATETIME(?, '-3 minutes')
@@ -99,7 +99,7 @@ def void_ghost_disconnections (db):
AND eve_PairEventRowid IN (
SELECT Events.RowID
FROM CurrentScan, Devices, Events
WHERE dev_MAC = cur_MAC
WHERE devMac = cur_MAC
AND eve_MAC = cur_MAC
AND eve_EventType = 'Disconnected'
AND eve_DateTime >= DATETIME(?, '-3 minutes')
@@ -114,7 +114,7 @@ def void_ghost_disconnections (db):
AND ROWID IN (
SELECT Events.RowID
FROM CurrentScan, Devices, Events
WHERE dev_MAC = cur_MAC
WHERE devMac = cur_MAC
AND eve_MAC = cur_MAC
AND eve_EventType = 'Disconnected'
AND eve_DateTime >= DATETIME(?, '-3 minutes')
@@ -186,12 +186,12 @@ def insert_events (db):
sql.execute (f"""INSERT INTO Events (eve_MAC, eve_IP, eve_DateTime,
eve_EventType, eve_AdditionalInfo,
eve_PendingAlertEmail)
SELECT dev_MAC, dev_LastIP, '{startTime}', 'Device Down', '', 1
SELECT devMac, devLastIP, '{startTime}', 'Device Down', '', 1
FROM Devices
WHERE dev_AlertDeviceDown != 0
AND dev_PresentLastScan = 1
WHERE devAlertDown != 0
AND devPresentLastScan = 1
AND NOT EXISTS (SELECT 1 FROM CurrentScan
WHERE dev_MAC = cur_MAC
WHERE devMac = cur_MAC
) """)
# Check new Connections or Down Reconnections
@@ -208,7 +208,7 @@ def insert_events (db):
1
FROM CurrentScan AS c
LEFT JOIN LatestEventsPerMAC AS last_event ON c.cur_MAC = last_event.eve_MAC
WHERE last_event.dev_PresentLastScan = 0 OR last_event.eve_MAC IS NULL
WHERE last_event.devPresentLastScan = 0 OR last_event.eve_MAC IS NULL
""")
# Check disconnections
@@ -216,13 +216,13 @@ def insert_events (db):
sql.execute (f"""INSERT INTO Events (eve_MAC, eve_IP, eve_DateTime,
eve_EventType, eve_AdditionalInfo,
eve_PendingAlertEmail)
SELECT dev_MAC, dev_LastIP, '{startTime}', 'Disconnected', '',
dev_AlertEvents
SELECT devMac, devLastIP, '{startTime}', 'Disconnected', '',
devAlertEvents
FROM Devices
WHERE dev_AlertDeviceDown = 0
AND dev_PresentLastScan = 1
WHERE devAlertDown = 0
AND devPresentLastScan = 1
AND NOT EXISTS (SELECT 1 FROM CurrentScan
WHERE dev_MAC = cur_MAC
WHERE devMac = cur_MAC
) """)
# Check IP Changed
@@ -231,10 +231,10 @@ def insert_events (db):
eve_EventType, eve_AdditionalInfo,
eve_PendingAlertEmail)
SELECT cur_MAC, cur_IP, '{startTime}', 'IP Changed',
'Previous IP: '|| dev_LastIP, dev_AlertEvents
'Previous IP: '|| devLastIP, devAlertEvents
FROM Devices, CurrentScan
WHERE dev_MAC = cur_MAC
AND dev_LastIP <> cur_IP """ )
WHERE devMac = cur_MAC
AND devLastIP <> cur_IP """ )
mylog('debug','[Events] - Events end')
@@ -248,9 +248,9 @@ def insertOnlineHistory(db):
query = """
SELECT
COUNT(*) AS allDevics,
SUM(CASE WHEN dev_Archived = 1 THEN 1 ELSE 0 END) AS archivedDevices,
SUM(CASE WHEN dev_PresentLastScan = 1 THEN 1 ELSE 0 END) AS onlineDevices,
SUM(CASE WHEN dev_PresentLastScan = 0 AND dev_AlertDeviceDown = 1 THEN 1 ELSE 0 END) AS downDevices
SUM(CASE WHEN devIsArchived = 1 THEN 1 ELSE 0 END) AS archivedDevices,
SUM(CASE WHEN devPresentLastScan = 1 THEN 1 ELSE 0 END) AS onlineDevices,
SUM(CASE WHEN devPresentLastScan = 0 AND devAlertDown = 1 THEN 1 ELSE 0 END) AS downDevices
FROM Devices
"""

View File

@@ -246,8 +246,8 @@ class Notification_obj:
def clearPendingEmailFlag(self):
# Clean Pending Alert Events
self.db.sql.execute ("""UPDATE Devices SET dev_LastNotification = ?
WHERE dev_MAC IN (
self.db.sql.execute ("""UPDATE Devices SET devLastNotification = ?
WHERE devMac IN (
SELECT eve_MAC FROM Events
WHERE eve_PendingAlertEmail = 1
)

View File

@@ -48,12 +48,12 @@ def get_notifications (db):
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
WHERE eve_PendingAlertEmail = 1 AND eve_EventType not in ('Device Down', 'Down Reconnected', 'New Device' ) AND eve_MAC IN
(
SELECT dev_MAC FROM Devices WHERE dev_AlertEvents = 0
SELECT devMac FROM Devices WHERE devAlertEvents = 0
)""")
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
WHERE eve_PendingAlertEmail = 1 AND eve_EventType in ('Device Down', 'Down Reconnected') AND eve_MAC IN
(
SELECT dev_MAC FROM Devices WHERE dev_AlertDeviceDown = 0
SELECT devMac FROM Devices WHERE devAlertDown = 0
)""")
sections = get_setting_value('NTFPRCS_INCLUDED_SECTIONS')
@@ -62,7 +62,7 @@ def get_notifications (db):
if 'new_devices' in sections:
# Compose New Devices Section (no empty lines in SQL queries!)
sqlQuery = f"""SELECT eve_MAC as MAC, eve_DateTime as Datetime, dev_LastIP as IP, eve_EventType as "Event Type", dev_Name as "Device name", dev_Comments as Comments FROM Events_Devices
sqlQuery = f"""SELECT eve_MAC as MAC, eve_DateTime as Datetime, devLastIP as IP, eve_EventType as "Event Type", devName as "Device name", devComments as Comments FROM Events_Devices
WHERE eve_PendingAlertEmail = 1
AND eve_EventType = 'New Device' {get_setting_value('NTFPRCS_new_dev_condition').replace('{s-quote}',"'")}
ORDER BY eve_DateTime"""
@@ -83,7 +83,7 @@ def get_notifications (db):
# Compose Devices Down Section
# - select only Down Alerts with pending email of devices that didn't reconnect within the specified time window
sqlQuery = f"""
SELECT dev_Name, eve_MAC, dev_Vendor, eve_IP, eve_DateTime, eve_EventType
SELECT devName, eve_MAC, devVendor, eve_IP, eve_DateTime, eve_EventType
FROM Events_Devices AS down_events
WHERE eve_PendingAlertEmail = 1
AND down_events.eve_EventType = 'Device Down'
@@ -113,7 +113,7 @@ def get_notifications (db):
# Compose Reconnected Down Section
# - select only Devices, that were previously down and now are Connected
sqlQuery = f"""
SELECT dev_Name, eve_MAC, dev_Vendor, eve_IP, eve_DateTime, eve_EventType
SELECT devName, eve_MAC, devVendor, eve_IP, eve_DateTime, eve_EventType
FROM Events_Devices AS reconnected_devices
WHERE reconnected_devices.eve_EventType = 'Down Reconnected'
AND reconnected_devices.eve_PendingAlertEmail = 1
@@ -133,7 +133,7 @@ def get_notifications (db):
if 'events' in sections:
# Compose Events Section (no empty lines in SQL queries!)
sqlQuery = f"""SELECT eve_MAC as MAC, eve_DateTime as Datetime, dev_LastIP as IP, eve_EventType as "Event Type", dev_Name as "Device name", dev_Comments as Comments FROM Events_Devices
sqlQuery = f"""SELECT eve_MAC as MAC, eve_DateTime as Datetime, devLastIP as IP, eve_EventType as "Event Type", devName as "Device name", devComments as Comments FROM Events_Devices
WHERE eve_PendingAlertEmail = 1
AND eve_EventType IN ('Connected', 'Down Reconnected', 'Disconnected','IP Changed') {get_setting_value('NTFPRCS_event_condition').replace('{s-quote}',"'")}
ORDER BY eve_DateTime"""
@@ -190,11 +190,11 @@ def skip_repeated_notifications (db):
db.sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
WHERE eve_PendingAlertEmail = 1 AND eve_MAC IN
(
SELECT dev_MAC FROM Devices
WHERE dev_LastNotification IS NOT NULL
AND dev_LastNotification <>""
AND (strftime("%s", dev_LastNotification)/60 +
dev_SkipRepeated * 60) >
SELECT devMac FROM Devices
WHERE devLastNotification IS NOT NULL
AND devLastNotification <>""
AND (strftime("%s", devLastNotification)/60 +
devSkipRepeated * 60) >
(strftime('%s','now','localtime')/60 )
)
""" )