mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-04-04 17:21:23 -07:00
BE: added stateUpdated #1251
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
This commit is contained in:
@@ -107,8 +107,12 @@ class app_state_class:
|
|||||||
if pluginsStates is not None:
|
if pluginsStates is not None:
|
||||||
for plugin, state in pluginsStates.items():
|
for plugin, state in pluginsStates.items():
|
||||||
if plugin in self.pluginsStates:
|
if plugin in self.pluginsStates:
|
||||||
# Only update existing keys
|
# Only update existing keys if both are dicts
|
||||||
self.pluginsStates[plugin].update(state)
|
if isinstance(self.pluginsStates[plugin], dict) and isinstance(state, dict):
|
||||||
|
self.pluginsStates[plugin].update(state)
|
||||||
|
else:
|
||||||
|
# Replace if types don't match
|
||||||
|
self.pluginsStates[plugin] = state
|
||||||
else:
|
else:
|
||||||
# Optionally ignore or add new plugin entries
|
# Optionally ignore or add new plugin entries
|
||||||
# To ignore new plugins, comment out the next line
|
# To ignore new plugins, comment out the next line
|
||||||
|
|||||||
@@ -212,7 +212,8 @@ class plugin_manager:
|
|||||||
"lastChanged": str,
|
"lastChanged": str,
|
||||||
"totalObjects": int,
|
"totalObjects": int,
|
||||||
"newObjects": int,
|
"newObjects": int,
|
||||||
"changedObjects": int
|
"changedObjects": int,
|
||||||
|
"stateUpdated": str
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
sql = self.db.sql
|
sql = self.db.sql
|
||||||
@@ -222,12 +223,13 @@ class plugin_manager:
|
|||||||
sql.execute("""
|
sql.execute("""
|
||||||
SELECT MAX(DateTimeChanged) AS last_changed,
|
SELECT MAX(DateTimeChanged) AS last_changed,
|
||||||
COUNT(*) AS total_objects,
|
COUNT(*) AS total_objects,
|
||||||
SUM(CASE WHEN DateTimeCreated = DateTimeChanged THEN 1 ELSE 0 END) AS new_objects
|
SUM(CASE WHEN DateTimeCreated = DateTimeChanged THEN 1 ELSE 0 END) AS new_objects,
|
||||||
|
CURRENT_TIMESTAMP AS state_updated
|
||||||
FROM Plugins_Objects
|
FROM Plugins_Objects
|
||||||
WHERE Plugin = ?
|
WHERE Plugin = ?
|
||||||
""", (plugin_name,))
|
""", (plugin_name,))
|
||||||
row = sql.fetchone()
|
row = sql.fetchone()
|
||||||
last_changed, total_objects, new_objects = row if row else ("", 0, 0)
|
last_changed, total_objects, new_objects, state_updated = row if row else ("", 0, 0)
|
||||||
new_objects = new_objects or 0 # ensure it's int
|
new_objects = new_objects or 0 # ensure it's int
|
||||||
changed_objects = total_objects - new_objects
|
changed_objects = total_objects - new_objects
|
||||||
|
|
||||||
@@ -235,7 +237,8 @@ class plugin_manager:
|
|||||||
"lastChanged": last_changed or "",
|
"lastChanged": last_changed or "",
|
||||||
"totalObjects": total_objects or 0,
|
"totalObjects": total_objects or 0,
|
||||||
"newObjects": new_objects or 0,
|
"newObjects": new_objects or 0,
|
||||||
"changedObjects": changed_objects or 0
|
"changedObjects": changed_objects or 0,
|
||||||
|
"stateUpdated": state_updated or ""
|
||||||
}
|
}
|
||||||
|
|
||||||
# Save in memory
|
# Save in memory
|
||||||
@@ -246,18 +249,20 @@ class plugin_manager:
|
|||||||
SELECT Plugin,
|
SELECT Plugin,
|
||||||
MAX(DateTimeChanged) AS last_changed,
|
MAX(DateTimeChanged) AS last_changed,
|
||||||
COUNT(*) AS total_objects,
|
COUNT(*) AS total_objects,
|
||||||
SUM(CASE WHEN DateTimeCreated = DateTimeChanged THEN 1 ELSE 0 END) AS new_objects
|
SUM(CASE WHEN DateTimeCreated = DateTimeChanged THEN 1 ELSE 0 END) AS new_objects,
|
||||||
|
CURRENT_TIMESTAMP AS state_updated
|
||||||
FROM Plugins_Objects
|
FROM Plugins_Objects
|
||||||
GROUP BY Plugin
|
GROUP BY Plugin
|
||||||
""")
|
""")
|
||||||
for plugin, last_changed, total_objects, new_objects in sql.fetchall():
|
for plugin, last_changed, total_objects, new_objects, state_updated in sql.fetchall():
|
||||||
new_objects = new_objects or 0 # ensure it's int
|
new_objects = new_objects or 0 # ensure it's int
|
||||||
changed_objects = total_objects - new_objects
|
changed_objects = total_objects - new_objects
|
||||||
plugin_states[plugin] = {
|
plugin_states[plugin] = {
|
||||||
"lastChanged": last_changed or "",
|
"lastChanged": last_changed or "",
|
||||||
"totalObjects": total_objects or 0,
|
"totalObjects": total_objects or 0,
|
||||||
"newObjects": new_objects or 0,
|
"newObjects": new_objects or 0,
|
||||||
"changedObjects": changed_objects or 0
|
"changedObjects": changed_objects or 0,
|
||||||
|
"stateUpdated": state_updated or ""
|
||||||
}
|
}
|
||||||
|
|
||||||
# Save in memory
|
# Save in memory
|
||||||
|
|||||||
@@ -3,19 +3,23 @@ import subprocess
|
|||||||
import conf
|
import conf
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
from dateutil import parser
|
||||||
|
|
||||||
# Register NetAlertX directories
|
# Register NetAlertX directories
|
||||||
INSTALL_PATH="/app"
|
INSTALL_PATH="/app"
|
||||||
sys.path.extend([f"{INSTALL_PATH}/server"])
|
sys.path.extend([f"{INSTALL_PATH}/server"])
|
||||||
|
|
||||||
from helper import timeNowTZ, get_setting_value, check_IP_format
|
from helper import timeNowTZ, get_setting_value, check_IP_format
|
||||||
from logger import mylog
|
from logger import mylog, Logger
|
||||||
from const import vendorsPath, vendorsPathNewest, sql_generateGuid
|
from const import vendorsPath, vendorsPathNewest, sql_generateGuid
|
||||||
from models.device_instance import DeviceInstance
|
from models.device_instance import DeviceInstance
|
||||||
from scan.name_resolution import NameResolver
|
from scan.name_resolution import NameResolver
|
||||||
from scan.device_heuristics import guess_icon, guess_type
|
from scan.device_heuristics import guess_icon, guess_type
|
||||||
from db.db_helper import sanitize_SQL_input, list_to_where
|
from db.db_helper import sanitize_SQL_input, list_to_where
|
||||||
|
|
||||||
|
# Make sure log level is initialized correctly
|
||||||
|
Logger(get_setting_value('LOG_LEVEL'))
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# Removing devices from the CurrentScan DB table which the user chose to ignore by MAC or IP
|
# Removing devices from the CurrentScan DB table which the user chose to ignore by MAC or IP
|
||||||
def exclude_ignored_devices(db):
|
def exclude_ignored_devices(db):
|
||||||
@@ -521,25 +525,25 @@ def update_devices_names(pm):
|
|||||||
resolver = NameResolver(pm.db)
|
resolver = NameResolver(pm.db)
|
||||||
device_handler = DeviceInstance(pm.db)
|
device_handler = DeviceInstance(pm.db)
|
||||||
|
|
||||||
# --- Short-circuit if no plugin that resolves names changed ---
|
# --- Short-circuit if no name-resolution plugin has changed ---
|
||||||
name_plugins = ["DIGSCAN", "NSLOOKUP", "NBTSCAN", "AVAHISCAN"]
|
name_plugins = ["DIGSCAN", "NSLOOKUP", "NBTSCAN", "AVAHISCAN"]
|
||||||
|
|
||||||
# Get last check timestamp from plugin manager
|
|
||||||
last_checked = pm.name_plugins_checked
|
|
||||||
|
|
||||||
# Determine the latest 'lastChanged' timestamp among name plugins
|
# Retrieve last time name resolution was checked (string or datetime)
|
||||||
latest_change = max(
|
last_checked_str = pm.name_plugins_checked
|
||||||
[pm.plugin_states.get(p, {}).get("lastChanged") for p in name_plugins if pm.plugin_states.get(p)],
|
last_checked_dt = parser.parse(last_checked_str) if isinstance(last_checked_str, str) else last_checked_str
|
||||||
default=None
|
|
||||||
)
|
|
||||||
|
|
||||||
# Convert to comparable datetime if needed
|
# Find the most recent plugin update time among name-related plugins
|
||||||
from dateutil import parser
|
state_times = [
|
||||||
latest_change_dt = parser.parse(latest_change) if latest_change else None
|
pm.plugin_states.get(p, {}).get("stateUpdated")
|
||||||
|
for p in name_plugins
|
||||||
|
if pm.plugin_states.get(p)
|
||||||
|
]
|
||||||
|
latest_state_str = max(state_times, default=None)
|
||||||
|
latest_state_dt = parser.parse(latest_state_str) if latest_state_str else None
|
||||||
|
|
||||||
# Skip if nothing changed since last check
|
# Skip if no plugin state changed since last check
|
||||||
if last_checked and latest_change_dt and latest_change_dt <= last_checked:
|
if last_checked_dt and latest_state_dt and latest_state_dt <= last_checked_dt:
|
||||||
mylog('debug', '[Update Device Name] No relevant plugin changes since last check, skipping.')
|
mylog('debug', '[Update Device Name] No relevant name plugin changes since last check — skipping update.')
|
||||||
return
|
return
|
||||||
|
|
||||||
nameNotFound = "(name not found)"
|
nameNotFound = "(name not found)"
|
||||||
@@ -639,7 +643,10 @@ def update_devices_names(pm):
|
|||||||
|
|
||||||
# --- Step 3: Log last checked time ---
|
# --- Step 3: Log last checked time ---
|
||||||
# After resolving names, update last checked
|
# After resolving names, update last checked
|
||||||
pm.name_plugins_checked = timeNowTZ()
|
sql = pm.db.sql
|
||||||
|
sql.execute("SELECT CURRENT_TIMESTAMP")
|
||||||
|
row = sql.fetchone()
|
||||||
|
pm.name_plugins_checked = row[0] if row else None
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# Updates devPresentLastScan for parent devices based on the presence of their NICs
|
# Updates devPresentLastScan for parent devices based on the presence of their NICs
|
||||||
|
|||||||
Reference in New Issue
Block a user