BE/PLG: TZ timestamp work #1251

Signed-off-by: jokob-sk <jokob.sk@gmail.com>
This commit is contained in:
jokob-sk
2025-11-04 19:24:13 +11:00
parent 6dd7251c84
commit 59477e7b38
67 changed files with 164 additions and 133 deletions

View File

@@ -15,7 +15,7 @@ from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from plugin_utils import get_plugins_configs
from logger import mylog, Logger
from const import pluginsPath, fullDbPath, logPath
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from messaging.in_app import write_notification
import conf

View File

@@ -23,7 +23,7 @@ from const import apiPath, confFileName, logPath
from plugin_utils import getPluginObject
from plugin_helper import Plugin_Objects
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value, bytes_to_string, sanitize_string, cleanDeviceName
from helper import get_setting_value, bytes_to_string, sanitize_string, cleanDeviceName
from models.notification_instance import NotificationInstance
from database import DB, get_device_stats

View File

@@ -16,7 +16,7 @@ import conf
from const import confFileName, logPath
from plugin_helper import Plugin_Objects
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import timeNowDB, get_setting_value
from models.notification_instance import NotificationInstance
from database import DB
from pytz import timezone
@@ -65,7 +65,7 @@ def main():
# Log result
plugin_objects.add_object(
primaryId = pluginName,
secondaryId = timeNowTZ(),
secondaryId = timeNowDB(),
watched1 = notification["GUID"],
watched2 = result,
watched3 = 'null',

View File

@@ -25,7 +25,7 @@ import conf
from const import confFileName, logPath
from plugin_helper import Plugin_Objects
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value, hide_email
from helper import timeNowDB, get_setting_value, hide_email
from models.notification_instance import NotificationInstance
from database import DB
from pytz import timezone
@@ -86,7 +86,7 @@ def main():
# Log result
plugin_objects.add_object(
primaryId = pluginName,
secondaryId = timeNowTZ(),
secondaryId = timeNowDB(),
watched1 = notification["GUID"],
watched2 = result,
watched3 = 'null',

View File

@@ -23,7 +23,7 @@ from const import confFileName, logPath
from plugin_utils import getPluginObject
from plugin_helper import Plugin_Objects
from logger import mylog, Logger
from helper import timeNowTZ, get_setting_value, bytes_to_string, \
from helper import timeNowDB, get_setting_value, bytes_to_string, \
sanitize_string, normalize_string
from database import DB, get_device_stats
@@ -567,7 +567,7 @@ def prepTimeStamp(datetime_str):
except ValueError:
mylog('verbose', [f"[{pluginName}] Timestamp conversion failed of string '{datetime_str}'"])
# Use the current time if the input format is invalid
parsed_datetime = timeNowTZ() # Assuming this function returns the current time with timezone
parsed_datetime = timeNowDB()
# Convert to the required format with 'T' between date and time and ensure the timezone is included
return parsed_datetime.isoformat() # This will include the timezone offset

View File

@@ -19,7 +19,7 @@ import conf
from const import confFileName, logPath
from plugin_helper import Plugin_Objects, handleEmpty
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import timeNowDB, get_setting_value
from models.notification_instance import NotificationInstance
from database import DB
from pytz import timezone
@@ -68,7 +68,7 @@ def main():
# Log result
plugin_objects.add_object(
primaryId = pluginName,
secondaryId = timeNowTZ(),
secondaryId = timeNowDB(),
watched1 = notification["GUID"],
watched2 = handleEmpty(response_text),
watched3 = response_status_code,

View File

@@ -11,7 +11,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Objects, handleEmpty # noqa: E402
from logger import mylog, Logger # noqa: E402
from helper import timeNowTZ, get_setting_value, hide_string # noqa: E402
from helper import timeNowDB, get_setting_value, hide_string # noqa: E402
from models.notification_instance import NotificationInstance # noqa: E402
from database import DB # noqa: E402
import conf
@@ -63,7 +63,7 @@ def main():
# Log result
plugin_objects.add_object(
primaryId=pluginName,
secondaryId=timeNowTZ(),
secondaryId=timeNowDB(),
watched1=notification["GUID"],
watched2=handleEmpty(response_text),
watched3=response_status_code,

View File

@@ -19,7 +19,7 @@ import conf
from const import confFileName, logPath
from plugin_helper import Plugin_Objects, handleEmpty
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value, hide_string
from helper import timeNowDB, get_setting_value, hide_string
from models.notification_instance import NotificationInstance
from database import DB
from pytz import timezone
@@ -68,7 +68,7 @@ def main():
# Log result
plugin_objects.add_object(
primaryId = pluginName,
secondaryId = timeNowTZ(),
secondaryId = timeNowDB(),
watched1 = notification["GUID"],
watched2 = handleEmpty(response_text),
watched3 = response_status_code,

View File

@@ -16,7 +16,7 @@ import conf
from const import confFileName, logPath
from plugin_helper import Plugin_Objects
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import timeNowDB, get_setting_value
from models.notification_instance import NotificationInstance
from database import DB
from pytz import timezone
@@ -65,7 +65,7 @@ def main():
# Log result
plugin_objects.add_object(
primaryId=pluginName,
secondaryId=timeNowTZ(),
secondaryId=timeNowDB(),
watched1=notification["GUID"],
watched2=result,
watched3='null',

View File

@@ -22,7 +22,7 @@ import conf
from const import logPath, confFileName
from plugin_helper import Plugin_Objects, handleEmpty
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value, hide_string, write_file
from helper import timeNowDB, get_setting_value, hide_string, write_file
from models.notification_instance import NotificationInstance
from database import DB
from pytz import timezone
@@ -71,7 +71,7 @@ def main():
# Log result
plugin_objects.add_object(
primaryId = pluginName,
secondaryId = timeNowTZ(),
secondaryId = timeNowDB(),
watched1 = notification["GUID"],
watched2 = handleEmpty(response_stdout),
watched3 = handleEmpty(response_stderr),

View File

@@ -16,7 +16,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from database import DB
from plugin_helper import Plugin_Object, Plugin_Objects, handleEmpty
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from const import logPath, applicationPath
import conf
from pytz import timezone

View File

@@ -16,7 +16,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from const import logPath, applicationPath, fullDbPath
import conf
from pytz import timezone

View File

@@ -16,7 +16,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from const import logPath, applicationPath, fullDbPath
import conf
from pytz import timezone

View File

@@ -19,7 +19,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value, check_IP_format
from helper import get_setting_value, check_IP_format
from const import logPath, applicationPath, fullDbPath
import conf
from pytz import timezone

View File

@@ -15,7 +15,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, handleEmpty, is_mac
from logger import mylog, Logger
from dhcp_leases import DhcpLeases
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
import conf
from const import logPath
from pytz import timezone

View File

@@ -13,7 +13,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Objects, Plugin_Object
from logger import mylog, Logger
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
import conf
from pytz import timezone
from const import logPath

View File

@@ -15,7 +15,7 @@ from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from plugin_utils import get_plugins_configs
from logger import mylog, Logger
from const import pluginsPath, fullDbPath, logPath
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from messaging.in_app import write_notification
from database import DB
from models.device_instance import DeviceInstance

View File

@@ -24,7 +24,7 @@ from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from plugin_utils import get_plugins_configs
from logger import mylog, Logger
from const import pluginsPath, fullDbPath, logPath
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from messaging.in_app import write_notification
import conf

View File

@@ -20,7 +20,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from const import logPath, applicationPath, fullDbPath
from database import DB
from models.device_instance import DeviceInstance

View File

@@ -20,7 +20,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, check_IP_format, get_setting_value
from helper import timeNowDB, check_IP_format, get_setting_value
from const import logPath, applicationPath, fullDbPath
import conf
from pytz import timezone
@@ -80,7 +80,7 @@ def main():
mylog('verbose', [f'[{pluginName}] Curl Fallback (new_internet_IP|cmd_output): {new_internet_IP} | {cmd_output}'])
# logging
append_line_to_file (logPath + '/IP_changes.log', '['+str(timeNowTZ()) +']\t'+ new_internet_IP +'\n')
append_line_to_file (logPath + '/IP_changes.log', '['+str(timeNowDB()) +']\t'+ new_internet_IP +'\n')
plugin_objects = Plugin_Objects(RESULT_FILE)

View File

@@ -13,7 +13,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Objects
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import timeNowDB, get_setting_value
import conf
from pytz import timezone
from const import logPath
@@ -40,7 +40,7 @@ def main():
speedtest_result = run_speedtest()
plugin_objects.add_object(
primaryId = 'Speedtest',
secondaryId = timeNowTZ(),
secondaryId = timeNowDB(),
watched1 = speedtest_result['download_speed'],
watched2 = speedtest_result['upload_speed'],
watched3 = 'null',

View File

@@ -18,7 +18,7 @@ from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64, handleEmp
from plugin_utils import get_plugins_configs
from logger import mylog, Logger
from const import pluginsPath, fullDbPath, logPath
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from messaging.in_app import write_notification
import conf

View File

@@ -9,7 +9,7 @@ pluginName = 'LUCIRPC'
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from const import logPath, applicationPath
import conf
from pytz import timezone

View File

@@ -17,7 +17,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from const import logPath, applicationPath
from messaging.in_app import remove_old
import conf

View File

@@ -15,7 +15,7 @@ from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from plugin_utils import get_plugins_configs
from logger import mylog, Logger
from const import pluginsPath, fullDbPath, logPath
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from messaging.in_app import write_notification
from database import DB
from models.device_instance import DeviceInstance

View File

@@ -21,7 +21,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value, extract_between_strings, extract_ip_addresses, extract_mac_addresses
from helper import get_setting_value, extract_between_strings, extract_ip_addresses, extract_mac_addresses
from const import logPath, applicationPath, fullDbPath
from database import DB
from models.device_instance import DeviceInstance

View File

@@ -14,7 +14,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import timeNowDB, get_setting_value
from const import logPath, applicationPath
import conf
from pytz import timezone
@@ -158,7 +158,7 @@ def performNmapScan(deviceIPs, deviceMACs, timeoutSec, args):
elif 'PORT' in line and 'STATE' in line and 'SERVICE' in line:
startCollecting = False # end reached
elif startCollecting and len(line.split()) == 3:
newEntriesTmp.append(nmap_entry(ip, deviceMACs[devIndex], timeNowTZ(), line.split()[0], line.split()[1], line.split()[2]))
newEntriesTmp.append(nmap_entry(ip, deviceMACs[devIndex], timeNowDB(), line.split()[0], line.split()[1], line.split()[2]))
newPortsPerDevice += 1
elif 'Nmap done' in line:
duration = line.split('scanned in ')[1]

View File

@@ -20,7 +20,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from const import logPath, applicationPath, fullDbPath
from database import DB
from models.device_instance import DeviceInstance

View File

@@ -44,7 +44,7 @@ from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from plugin_utils import get_plugins_configs
from logger import mylog, Logger
from const import pluginsPath, fullDbPath, logPath
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from messaging.in_app import write_notification
from pytz import timezone
import conf

View File

@@ -11,7 +11,7 @@ INSTALL_PATH = "/app"
sys.path.append(f"{INSTALL_PATH}/front/plugins")
sys.path.append(f'{INSTALL_PATH}/server')
from logger import mylog, Logger
from logger import mylog, Logger, timeNowDB
from const import confFileName, default_tz
#-------------------------------------------------------------------------------
@@ -204,7 +204,7 @@ class Plugin_Object:
self.pluginPref = ""
self.primaryId = primaryId
self.secondaryId = secondaryId
self.created = datetime.now().astimezone().isoformat()
self.created = timeNowDB()
self.changed = ""
self.watched1 = watched1
self.watched2 = watched2

View File

@@ -13,7 +13,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64, handleEmpty, normalize_mac
from logger import mylog, Logger
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from const import logPath, applicationPath
import conf
from pytz import timezone

View File

@@ -18,7 +18,7 @@ from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from plugin_utils import get_plugins_configs, decode_and_rename_files
from logger import mylog, Logger
from const import pluginsPath, fullDbPath, logPath
from helper import timeNowTZ, get_setting_value
from helper import timeNowDB, get_setting_value
from crypto_utils import encrypt_data
from messaging.in_app import write_notification
import conf
@@ -149,7 +149,7 @@ def main():
message = f'[{pluginName}] Device data from node "{node_name}" written to {log_file_name}'
mylog('verbose', [message])
if lggr.isAbove('verbose'):
write_notification(message, 'info', timeNowTZ())
write_notification(message, 'info', timeNowDB())
# Process any received data for the Device DB table (ONLY JSON)
@@ -255,7 +255,7 @@ def main():
message = f'[{pluginName}] Inserted "{len(new_devices)}" new devices'
mylog('verbose', [message])
write_notification(message, 'info', timeNowTZ())
write_notification(message, 'info', timeNowDB())
# Commit and close the connection
@@ -299,7 +299,7 @@ def send_data(api_token, file_content, encryption_key, file_path, node_name, pre
if response.status_code == 200:
message = f'[{pluginName}] Data for "{file_path}" sent successfully via {final_endpoint}'
mylog('verbose', [message])
write_notification(message, 'info', timeNowTZ())
write_notification(message, 'info', timeNowDB())
return True
except requests.RequestException as e:
@@ -308,7 +308,7 @@ def send_data(api_token, file_content, encryption_key, file_path, node_name, pre
# If all endpoints fail
message = f'[{pluginName}] Failed to send data for "{file_path}" via all endpoints'
mylog('verbose', [message])
write_notification(message, 'alert', timeNowTZ())
write_notification(message, 'alert', timeNowDB())
return False
@@ -332,7 +332,7 @@ def get_data(api_token, node_url):
except json.JSONDecodeError:
message = f'[{pluginName}] Failed to parse JSON from {final_endpoint}'
mylog('verbose', [message])
write_notification(message, 'alert', timeNowTZ())
write_notification(message, 'alert', timeNowDB())
return ""
except requests.RequestException as e:
mylog('verbose', [f'[{pluginName}] Error calling {final_endpoint}: {e}'])
@@ -340,7 +340,7 @@ def get_data(api_token, node_url):
# If all endpoints fail
message = f'[{pluginName}] Failed to get data from "{node_url}" via all endpoints'
mylog('verbose', [message])
write_notification(message, 'alert', timeNowTZ())
write_notification(message, 'alert', timeNowDB())
return ""

View File

@@ -16,7 +16,7 @@ from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64, decode_se
from plugin_utils import get_plugins_configs
from logger import mylog, Logger
from const import pluginsPath, fullDbPath, logPath
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from messaging.in_app import write_notification
import conf

View File

@@ -21,7 +21,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, rmBadChars, is_typical_router_ip, is_mac
from logger import mylog, Logger
from helper import timeNowTZ, get_setting_value, normalize_string
from helper import get_setting_value, normalize_string
import conf
from pytz import timezone
from const import logPath

View File

@@ -17,7 +17,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64, handleEmpty
from logger import mylog, Logger, append_line_to_file
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from const import logPath, applicationPath, fullDbPath
from scan.device_handling import query_MAC_vendor
import conf

View File

@@ -16,7 +16,7 @@ from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
from plugin_utils import get_plugins_configs
from logger import mylog, Logger
from const import pluginsPath, fullDbPath, logPath
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from messaging.in_app import write_notification
from database import DB
from models.device_instance import DeviceInstance

View File

@@ -16,7 +16,7 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from plugin_helper import Plugin_Objects
from datetime import datetime
from const import logPath
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
import conf
from pytz import timezone
from logger import mylog, Logger

View File

@@ -9,7 +9,7 @@ INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/server"])
from logger import mylog
from helper import get_setting_value, timeNowTZ
from helper import get_setting_value
from db.db_helper import get_date_from_period
from app_state import updateState

View File

@@ -14,7 +14,7 @@ INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from database import get_temp_db_connection
from helper import is_random_mac, format_date, get_setting_value, timeNowTZ
from helper import is_random_mac, format_date, get_setting_value, timeNowDB
from db.db_helper import row_to_json, get_date_from_period
# --------------------------
@@ -28,7 +28,7 @@ def get_device_data(mac):
conn = get_temp_db_connection()
cur = conn.cursor()
now = timeNowTZ().astimezone().isoformat()
now = timeNowDB()
# Special case for new device
if mac.lower() == "new":
@@ -187,8 +187,8 @@ def set_device_data(mac, data):
data.get("devSkipRepeated", 0),
data.get("devIsNew", 0),
data.get("devIsArchived", 0),
data.get("devLastConnection", timeNowTZ().astimezone().isoformat()),
data.get("devFirstConnection", timeNowTZ().astimezone().isoformat()),
data.get("devLastConnection", timeNowDB()),
data.get("devFirstConnection", timeNowDB()),
data.get("devLastIP", ""),
data.get("devGUID", ""),
data.get("devCustomProps", ""),

View File

@@ -14,7 +14,7 @@ INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from database import get_temp_db_connection
from helper import is_random_mac, format_date, get_setting_value, format_date_iso, format_event_date, timeNowTZ, mylog, ensure_datetime
from helper import is_random_mac, format_date, get_setting_value, format_date_iso, format_event_date, mylog, ensure_datetime
from db.db_helper import row_to_json, get_date_from_period

View File

@@ -16,7 +16,7 @@ INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from database import get_temp_db_connection
from helper import is_random_mac, format_date, get_setting_value, format_date_iso, format_event_date, mylog, timeNowTZ, format_date_diff, format_ip_long, parse_datetime
from helper import is_random_mac, format_date, get_setting_value, format_date_iso, format_event_date, mylog, format_date_diff, format_ip_long, parse_datetime
from db.db_helper import row_to_json, get_date_from_period

View File

@@ -2,7 +2,7 @@ import os
import base64
from flask import jsonify, request
from logger import mylog
from helper import get_setting_value, timeNowTZ
from helper import get_setting_value, timeNowDB
from messaging.in_app import write_notification
INSTALL_PATH = "/app"
@@ -16,19 +16,19 @@ def handle_sync_get():
raw_data = f.read()
except FileNotFoundError:
msg = f"[Plugin: SYNC] Data file not found: {file_path}"
write_notification(msg, "alert", timeNowTZ())
write_notification(msg, "alert", timeNowDB())
mylog("verbose", [msg])
return jsonify({"error": msg}), 500
response_data = base64.b64encode(raw_data).decode("utf-8")
write_notification("[Plugin: SYNC] Data sent", "info", timeNowTZ())
write_notification("[Plugin: SYNC] Data sent", "info", timeNowDB())
return jsonify({
"node_name": get_setting_value("SYNC_node_name"),
"status": 200,
"message": "OK",
"data_base64": response_data,
"timestamp": timeNowTZ()
"timestamp": timeNowDB()
}), 200
@@ -61,11 +61,11 @@ def handle_sync_post():
f.write(data)
except Exception as e:
msg = f"[Plugin: SYNC] Failed to store data: {e}"
write_notification(msg, "alert", timeNowTZ())
write_notification(msg, "alert", timeNowDB())
mylog("verbose", [msg])
return jsonify({"error": msg}), 500
msg = f"[Plugin: SYNC] Data received ({file_path_new})"
write_notification(msg, "info", timeNowTZ())
write_notification(msg, "info", timeNowDB())
mylog("verbose", [msg])
return jsonify({"message": "Data received and stored successfully"}), 200

View File

@@ -4,7 +4,7 @@ import json
import conf
from const import *
from logger import mylog, logResult
from helper import timeNowTZ, timeNow, checkNewVersion
from helper import timeNowDB, timeNow, checkNewVersion
# Register NetAlertX directories
INSTALL_PATH="/app"
@@ -59,7 +59,7 @@ class app_state_class:
previousState = ""
# Update self
self.lastUpdated = str(timeNowTZ().astimezone().isoformat())
self.lastUpdated = str(timeNowDB())
if os.path.exists(stateFile):
try:

View File

@@ -31,18 +31,11 @@ INSTALL_PATH="/app"
#-------------------------------------------------------------------------------
# DateTime
#-------------------------------------------------------------------------------
# Get the current time in the current TimeZone
def timeNowTZ():
if conf.tz:
return datetime.datetime.now(conf.tz).replace(microsecond=0)
else:
return datetime.datetime.now().replace(microsecond=0)
# if isinstance(conf.TIMEZONE, str):
# tz = pytz.timezone(conf.TIMEZONE)
# else:
# tz = conf.TIMEZONE
# return datetime.datetime.now(tz).replace(microsecond=0)
def timeNow():
return datetime.datetime.now().replace(microsecond=0)
@@ -53,6 +46,23 @@ def get_timezone_offset():
offset_formatted = "{:+03d}:{:02d}".format(int(offset_hours), int((offset_hours % 1) * 60))
return offset_formatted
def timeNowDB(local=True):
"""
Return the current time (local or UTC) as ISO 8601 for DB storage.
Safe for SQLite, PostgreSQL, etc.
Example local: '2025-11-04 18:09:11'
Example UTC: '2025-11-04 07:09:11'
"""
if local:
try:
tz = ZoneInfo(conf.tz) if conf.tz else None
except Exception:
tz = None
return datetime.datetime.now(tz).strftime('%Y-%m-%d %H:%M:%S')
else:
return datetime.datetime.now(datetime.UTC).strftime('%Y-%m-%d %H:%M:%S')
#-------------------------------------------------------------------------------
# Date and time methods
@@ -79,7 +89,7 @@ def format_event_date(date_str: str, event_type: str) -> str:
# -------------------------------------------------------------------------------------------
def ensure_datetime(dt: Union[str, datetime.datetime, None]) -> datetime.datetime:
if dt is None:
return timeNowTZ()
return timeNowDB()
if isinstance(dt, str):
return datetime.datetime.fromisoformat(dt)
return dt

View File

@@ -12,7 +12,7 @@ import re
# Register NetAlertX libraries
import conf
from const import fullConfPath, applicationPath, fullConfFolder, default_tz
from helper import getBuildTimeStamp, fixPermissions, collect_lang_strings, updateSubnets, isJsonObject, setting_value_to_python_type, timeNowTZ, get_setting_value, generate_random_string
from helper import getBuildTimeStamp, fixPermissions, collect_lang_strings, updateSubnets, isJsonObject, setting_value_to_python_type, timeNowDB, get_setting_value, generate_random_string
from app_state import updateState
from logger import mylog
from api import update_api
@@ -392,7 +392,7 @@ def importConfigs (pm, db, all_plugins):
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
ccd('VERSION', buildTimestamp , c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", None, None, True)
write_notification(f'[Upgrade] : App upgraded 🚀 Please clear the cache: <ol> <li>Click OK below</li> <li>Clear the browser cache (shift + browser refresh button)</li> <li> Clear app cache with the <i class="fa-solid fa-rotate"></i> (reload) button in the header</li><li>Go to Settings and click Save</li> </ol> Check out new features and what has changed in the <a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.', 'interrupt', timeNowTZ())
write_notification(f'[Upgrade] : App upgraded 🚀 Please clear the cache: <ol> <li>Click OK below</li> <li>Clear the browser cache (shift + browser refresh button)</li> <li> Clear app cache with the <i class="fa-solid fa-rotate"></i> (reload) button in the header</li><li>Go to Settings and click Save</li> </ol> Check out new features and what has changed in the <a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.', 'interrupt', timeNowDB())
@@ -429,7 +429,7 @@ def importConfigs (pm, db, all_plugins):
mylog('minimal', msg)
# front end app log loggging
write_notification(msg, 'info', timeNowTZ())
write_notification(msg, 'info', timeNowDB())
return pm, all_plugins, True

View File

@@ -19,6 +19,23 @@ def timeNowTZ():
else:
return datetime.datetime.now().replace(microsecond=0)
def timeNowDB(local=True):
"""
Return the current time (local or UTC) as ISO 8601 for DB storage.
Safe for SQLite, PostgreSQL, etc.
Example local: '2025-11-04 18:09:11'
Example UTC: '2025-11-04 07:09:11'
"""
if local:
try:
tz = ZoneInfo(conf.tz) if conf.tz else None
except Exception:
tz = None
return datetime.datetime.now(tz).strftime('%Y-%m-%d %H:%M:%S')
else:
return datetime.datetime.now(datetime.UTC).strftime('%Y-%m-%d %H:%M:%S')
#-------------------------------------------------------------------------------
# Map custom debug levels to Python logging levels
custom_to_logging_levels = {

View File

@@ -20,7 +20,7 @@ sys.path.extend([f"{INSTALL_PATH}/server"])
import conf
from const import applicationPath, logPath, apiPath, confFileName, reportTemplatesPath
from logger import logResult, mylog
from helper import generate_mac_links, removeDuplicateNewLines, timeNowTZ, get_file_content, write_file, get_setting_value, get_timezone_offset
from helper import generate_mac_links, removeDuplicateNewLines, timeNowDB, get_file_content, write_file, get_setting_value, get_timezone_offset
NOTIFICATION_API_FILE = apiPath + 'user_notifications.json'
@@ -39,7 +39,7 @@ def write_notification(content, level='alert', timestamp=None):
None
"""
if timestamp is None:
timestamp = timeNowTZ()
timestamp = timeNowDB()
# Generate GUID
guid = str(uuid.uuid4())

View File

@@ -20,7 +20,7 @@ sys.path.extend([f"{INSTALL_PATH}/server"])
import conf
from const import applicationPath, logPath, apiPath, confFileName
from helper import timeNowTZ, get_file_content, write_file, get_timezone_offset, get_setting_value
from helper import get_file_content, write_file, get_timezone_offset, get_setting_value
from logger import logResult, mylog
from db.sql_safe_builder import create_safe_condition_builder
@@ -123,6 +123,9 @@ def get_notifications (db):
)
ORDER BY down_events.eve_DateTime;
"""
mylog("none", sqlQuery)
# Get the events as JSON
json_obj = db.get_table_as_json(sqlQuery)

View File

@@ -16,6 +16,7 @@ from const import applicationPath, logPath, apiPath, reportTemplatesPath
from logger import mylog, Logger
from helper import generate_mac_links, \
removeDuplicateNewLines, \
timeNowDB, \
timeNowTZ, \
write_file, \
get_setting_value, \
@@ -71,7 +72,7 @@ class NotificationInstance:
self.HasNotifications = True
self.GUID = str(uuid.uuid4())
self.DateTimeCreated = timeNowTZ()
self.DateTimeCreated = timeNowDB()
self.DateTimePushed = ""
self.Status = "new"
self.JSON = JSON
@@ -112,7 +113,7 @@ class NotificationInstance:
mail_html = mail_html.replace('<NEW_VERSION>', newVersionText)
# Report "REPORT_DATE" in Header & footer
timeFormated = timeNowTZ().strftime('%Y-%m-%d %H:%M')
timeFormated = timeNowDB()
mail_text = mail_text.replace('<REPORT_DATE>', timeFormated)
mail_html = mail_html.replace('<REPORT_DATE>', timeFormated)
@@ -231,7 +232,7 @@ class NotificationInstance:
# Updates the Published properties
def updatePublishedVia(self, newPublishedVia):
self.PublishedVia = newPublishedVia
self.DateTimePushed = timeNowTZ()
self.DateTimePushed = timeNowDB()
self.upsert()
# create or update a notification
@@ -282,7 +283,7 @@ class NotificationInstance:
SELECT eve_MAC FROM Events
WHERE eve_PendingAlertEmail = 1
)
""", (timeNowTZ(),))
""", (timeNowDB(),))
self.db.sql.execute("""
UPDATE Events SET eve_PendingAlertEmail = 0

View File

@@ -12,7 +12,7 @@ from collections import namedtuple
import conf
from const import pluginsPath, logPath, applicationPath, reportTemplatesPath
from logger import mylog, Logger
from helper import timeNowTZ, get_file_content, write_file, get_setting, get_setting_value
from helper import timeNowDB, timeNowTZ, get_file_content, write_file, get_setting, get_setting_value
from app_state import updateState
from api import update_api
from plugin_utils import logEventStatusCounts, get_plugin_string, get_plugin_setting_obj, print_plugin_info, list_to_csv, combine_plugin_objects, resolve_wildcards_arr, handle_empty, custom_plugin_decoder, decode_and_rename_files
@@ -154,7 +154,7 @@ class plugin_manager:
if len(executed_events) > 0 and executed_events:
executed_events_message = ', '.join(executed_events)
mylog('minimal', ['[check_and_run_user_event] INFO: Executed events: ', executed_events_message])
write_notification(f"[Ad-hoc events] Events executed: {executed_events_message}", "interrupt", timeNowTZ())
write_notification(f"[Ad-hoc events] Events executed: {executed_events_message}", "interrupt", timeNowDB())
return
@@ -163,7 +163,7 @@ class plugin_manager:
#-------------------------------------------------------------------------------
def handle_run(self, runType):
mylog('minimal', ['[', timeNowTZ(), '] START Run: ', runType])
mylog('minimal', ['[', timeNowDB(), '] START Run: ', runType])
# run the plugin
for plugin in self.all_plugins:
@@ -177,7 +177,7 @@ class plugin_manager:
current_plugin_state = self.get_plugin_states(pluginName) # get latest plugin state
updateState(pluginsStates={pluginName: current_plugin_state.get(pluginName, {})})
mylog('minimal', ['[', timeNowTZ(), '] END Run: ', runType])
mylog('minimal', ['[', timeNowDB(), '] END Run: ', runType])
return
@@ -186,7 +186,7 @@ class plugin_manager:
#-------------------------------------------------------------------------------
def handle_test(self, runType):
mylog('minimal', ['[', timeNowTZ(), '] [Test] START Test: ', runType])
mylog('minimal', ['[', timeNowDB(), '] [Test] START Test: ', runType])
# Prepare test samples
sample_json = json.loads(get_file_content(reportTemplatesPath + 'webhook_json_sample.json'))[0]["body"]["attachments"][0]["text"]
@@ -221,7 +221,7 @@ class plugin_manager:
"""
sql = self.db.sql
plugin_states = {}
now_str = timeNowTZ().isoformat()
now_str = timeNowDB()
if plugin_name: # Only compute for single plugin
sql.execute("""
@@ -759,7 +759,7 @@ def process_plugin_events(db, plugin, plugEventsArr):
if isMissing:
# if wasn't missing before, mark as changed
if tmpObj.status != "missing-in-last-scan":
tmpObj.changed = timeNowTZ().astimezone().isoformat()
tmpObj.changed = timeNowDB()
tmpObj.status = "missing-in-last-scan"
# mylog('debug', [f'[Plugins] Missing from last scan (PrimaryID | SecondaryID): {tmpObj.primaryId} | {tmpObj.secondaryId}'])

View File

@@ -4,7 +4,7 @@ import json
import conf
from logger import mylog
from const import pluginsPath, logPath, apiPath
from helper import timeNowTZ, get_file_content, write_file, get_setting, get_setting_value, setting_value_to_python_type
from helper import get_file_content, write_file, get_setting, get_setting_value, setting_value_to_python_type
from app_state import updateState
from crypto_utils import decrypt_data, generate_deterministic_guid

View File

@@ -10,7 +10,7 @@ from dateutil import parser
INSTALL_PATH="/app"
sys.path.extend([f"{INSTALL_PATH}/server"])
from helper import timeNowTZ, get_setting_value, check_IP_format
from helper import timeNowDB, timeNowTZ, get_setting_value, check_IP_format
from logger import mylog, Logger
from const import vendorsPath, vendorsPathNewest, sql_generateGuid
from models.device_instance import DeviceInstance
@@ -56,7 +56,7 @@ def exclude_ignored_devices(db):
#-------------------------------------------------------------------------------
def update_devices_data_from_scan (db):
sql = db.sql #TO-DO
startTime = timeNowTZ().astimezone().isoformat()
startTime = timeNowDB()
# Update Last Connection
mylog('debug', '[Update Devices] 1 Last Connection')
@@ -371,7 +371,7 @@ def print_scan_stats(db):
#-------------------------------------------------------------------------------
def create_new_devices (db):
sql = db.sql # TO-DO
startTime = timeNowTZ()
startTime = timeNowDB()
# Insert events for new devices from CurrentScan (not yet in Devices)
@@ -536,7 +536,7 @@ def update_devices_names(pm):
if isinstance(last_checked, str):
try:
last_checked = parser.parse(last_checked)
except Exception as e:
except (ValueError, TypeError) as e:
mylog('none', f'[Update Device Name] Could not parse last_checked timestamp: {last_checked!r} ({e})')
last_checked = None
elif not isinstance(last_checked, datetime.datetime):
@@ -544,7 +544,6 @@ def update_devices_names(pm):
# Collect and normalize valid state update timestamps for name-related plugins
state_times = []
latest_state = None
for p in name_plugins:
state_updated = pm.plugin_states.get(p, {}).get("stateUpdated")
@@ -561,13 +560,15 @@ def update_devices_names(pm):
mylog('none', f'[Update Device Name] Failed to parse timestamp for {p}: {state_updated!r} ({e})')
else:
mylog('none', f'[Update Device Name] Unexpected timestamp type for {p}: {type(state_updated)}')
# Determine the latest valid timestamp safely
try:
if state_times:
latest_state = max(state_times)
except Exception as e:
mylog('none', f'[Update Device Name] Failed to determine latest timestamp, using fallback ({e})')
latest_state = state_times[-1] if state_times else None
# Determine the latest valid timestamp safely (after collecting all timestamps)
latest_state = None
try:
if state_times:
latest_state = max(state_times)
except (ValueError, TypeError) as e:
mylog('none', f'[Update Device Name] Failed to determine latest timestamp, using fallback ({e})')
latest_state = state_times[-1] if state_times else None
# Skip if no plugin state changed since last check
@@ -672,7 +673,7 @@ def update_devices_names(pm):
# --- Step 3: Log last checked time ---
# After resolving names, update last checked
pm.name_plugins_checked = timeNowTZ().astimezone().isoformat()
pm.name_plugins_checked = timeNowDB()
#-------------------------------------------------------------------------------
# Updates devPresentLastScan for parent devices based on the presence of their NICs

View File

@@ -12,7 +12,7 @@ sys.path.extend([f"{INSTALL_PATH}/server"])
import conf
from const import *
from logger import mylog
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
# Load MAC/device-type/icon rules from external file
MAC_TYPE_ICON_PATH = Path(f"{INSTALL_PATH}/back/device_heuristics_rules.json")

View File

@@ -6,7 +6,7 @@ sys.path.extend([f"{INSTALL_PATH}/server"])
import conf
from scan.device_handling import create_new_devices, print_scan_stats, save_scanned_devices, exclude_ignored_devices, update_devices_data_from_scan
from helper import timeNowTZ, get_setting_value
from helper import timeNowDB, get_setting_value
from db.db_helper import print_table_schema
from logger import mylog, Logger
from messaging.reporting import skip_repeated_notifications
@@ -128,7 +128,7 @@ def create_sessions_snapshot (db):
#-------------------------------------------------------------------------------
def insert_events (db):
sql = db.sql #TO-DO
startTime = timeNowTZ()
startTime = timeNowDB()
# Check device down
mylog('debug','[Events] - 1 - Devices down')
@@ -191,7 +191,7 @@ def insert_events (db):
def insertOnlineHistory(db):
sql = db.sql # TO-DO: Implement sql object
scanTimestamp = timeNowTZ()
scanTimestamp = timeNowDB()
# Query to fetch all relevant device counts in one go
query = """

View File

@@ -7,7 +7,7 @@ sys.path.extend([f"{INSTALL_PATH}/server"])
import conf
from logger import mylog, Logger
from helper import get_setting_value, timeNowTZ
from helper import get_setting_value
from models.device_instance import DeviceInstance
from models.plugin_object_instance import PluginObjectInstance

View File

@@ -10,7 +10,7 @@ sys.path.extend([f"{INSTALL_PATH}/server"])
# Register NetAlertX modules
import conf
from helper import get_setting_value, timeNowTZ
from helper import get_setting_value
# Make sure the TIMEZONE for logging is correct
# conf.tz = pytz.timezone(get_setting_value('TIMEZONE'))
@@ -20,7 +20,6 @@ from logger import mylog, Logger, logResult
Logger(get_setting_value('LOG_LEVEL'))
from const import applicationPath, logPath, apiPath, confFileName, sql_generateGuid
from helper import timeNowTZ
class AppEvent_obj:
def __init__(self, db):

View File

@@ -8,7 +8,7 @@ sys.path.extend([f"{INSTALL_PATH}/server"])
import conf
from logger import mylog, Logger
from helper import get_setting_value, timeNowTZ
from helper import get_setting_value
# Make sure log level is initialized correctly
Logger(get_setting_value('LOG_LEVEL'))

View File

@@ -9,7 +9,7 @@ import conf
from const import fullConfFolder
import workflows.actions
from logger import mylog, Logger
from helper import get_setting_value, timeNowTZ
from helper import get_setting_value
# Make sure log level is initialized correctly
Logger(get_setting_value('LOG_LEVEL'))

View File

@@ -7,7 +7,7 @@ sys.path.extend([f"{INSTALL_PATH}/server"])
import conf
from logger import mylog, Logger
from helper import get_setting_value, timeNowTZ
from helper import get_setting_value
from database import get_array_from_sql_rows
# Make sure log level is initialized correctly

View File

@@ -6,7 +6,7 @@ import pytest
INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from helper import get_setting_value, timeNowTZ
from helper import get_setting_value, timeNowDB
from api_server.api_server_start import app
@@ -41,7 +41,7 @@ def b64(sql: str) -> str:
# -----------------------------
def test_dbquery_create_device(client, api_token, test_mac):
now = timeNowTZ().astimezone().isoformat()
now = timeNowDB()
sql = f"""
INSERT INTO Devices (devMac, devName, devVendor, devOwner, devFirstConnection, devLastConnection, devLastIP)

View File

@@ -9,7 +9,7 @@ import pytest
INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from api_server.api_server_start import app
@pytest.fixture(scope="session")

View File

@@ -10,7 +10,7 @@ import pytest
INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from api_server.api_server_start import app
@pytest.fixture(scope="session")

View File

@@ -10,7 +10,7 @@ from datetime import datetime, timedelta
INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from api_server.api_server_start import app
@pytest.fixture(scope="session")

View File

@@ -9,7 +9,7 @@ import pytest
INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from api_server.api_server_start import app
@pytest.fixture(scope="session")

View File

@@ -10,7 +10,7 @@ import pytest
INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from api_server.api_server_start import app
@pytest.fixture(scope="session")

View File

@@ -10,7 +10,7 @@ from datetime import datetime, timedelta
INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from helper import timeNowTZ, get_setting_value
from helper import timeNowDB, get_setting_value
from api_server.api_server_start import app
@pytest.fixture(scope="session")
@@ -48,7 +48,7 @@ def test_create_session(client, api_token, test_mac):
payload = {
"mac": test_mac,
"ip": "192.168.1.100",
"start_time": timeNowTZ(),
"start_time": timeNowDB(),
"event_type_conn": "Connected",
"event_type_disc": "Disconnected"
}
@@ -63,7 +63,7 @@ def test_list_sessions(client, api_token, test_mac):
payload = {
"mac": test_mac,
"ip": "192.168.1.100",
"start_time": timeNowTZ()
"start_time": timeNowDB()
}
client.post("/sessions/create", json=payload, headers=auth_headers(api_token))
@@ -80,7 +80,7 @@ def test_device_sessions_by_period(client, api_token, test_mac):
payload = {
"mac": test_mac,
"ip": "192.168.1.200",
"start_time": timeNowTZ()
"start_time": timeNowDB()
}
resp_create = client.post("/sessions/create", json=payload, headers=auth_headers(api_token))
assert resp_create.status_code == 200
@@ -115,7 +115,7 @@ def test_device_session_events(client, api_token, test_mac):
payload = {
"mac": test_mac,
"ip": "192.168.1.250",
"start_time": timeNowTZ()
"start_time": timeNowDB()
}
resp_create = client.post(
"/sessions/create",
@@ -163,7 +163,7 @@ def test_delete_session(client, api_token, test_mac):
payload = {
"mac": test_mac,
"ip": "192.168.1.100",
"start_time": timeNowTZ()
"start_time": timeNowDB()
}
client.post("/sessions/create", json=payload, headers=auth_headers(api_token))

View File

@@ -10,7 +10,7 @@ from datetime import datetime, timedelta
INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
from helper import timeNowTZ, get_setting_value
from helper import get_setting_value
from api_server.api_server_start import app
@pytest.fixture(scope="session")