mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-06 17:15:38 -08:00
/data and /tmp standarization
This commit is contained in:
@@ -1,14 +1,9 @@
|
||||
import sys
|
||||
|
||||
# Register NetAlertX directories
|
||||
INSTALL_PATH="/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/server"])
|
||||
|
||||
from logger import mylog
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
# Device object handling (WIP)
|
||||
#-------------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------------
|
||||
class DeviceInstance:
|
||||
def __init__(self, db):
|
||||
self.db = db
|
||||
@@ -19,7 +14,7 @@ class DeviceInstance:
|
||||
SELECT * FROM Devices
|
||||
""")
|
||||
return self.db.sql.fetchall()
|
||||
|
||||
|
||||
# Get all with unknown names
|
||||
def getUnknown(self):
|
||||
self.db.sql.execute("""
|
||||
@@ -29,7 +24,6 @@ class DeviceInstance:
|
||||
|
||||
# Get specific column value based on devMac
|
||||
def getValueWithMac(self, column_name, devMac):
|
||||
|
||||
query = f"SELECT {column_name} FROM Devices WHERE devMac = ?"
|
||||
self.db.sql.execute(query, (devMac,))
|
||||
result = self.db.sql.fetchone()
|
||||
@@ -41,7 +35,7 @@ class DeviceInstance:
|
||||
SELECT * FROM Devices WHERE devAlertDown = 1 and devPresentLastScan = 0
|
||||
""")
|
||||
return self.db.sql.fetchall()
|
||||
|
||||
|
||||
# Get all down
|
||||
def getOffline(self):
|
||||
self.db.sql.execute("""
|
||||
@@ -57,7 +51,9 @@ class DeviceInstance:
|
||||
|
||||
# Check if a device exists by devGUID
|
||||
def exists(self, devGUID):
|
||||
self.db.sql.execute("SELECT COUNT(*) AS count FROM Devices WHERE devGUID = ?", (devGUID,))
|
||||
self.db.sql.execute(
|
||||
"SELECT COUNT(*) AS count FROM Devices WHERE devGUID = ?", (devGUID,)
|
||||
)
|
||||
result = self.db.sql.fetchone()
|
||||
return result["count"] > 0
|
||||
|
||||
@@ -65,20 +61,23 @@ class DeviceInstance:
|
||||
def updateField(self, devGUID, field, value):
|
||||
if not self.exists(devGUID):
|
||||
m = f"[Device] In 'updateField': GUID {devGUID} not found."
|
||||
mylog('none', m)
|
||||
mylog("none", m)
|
||||
raise ValueError(m)
|
||||
|
||||
self.db.sql.execute(f"""
|
||||
self.db.sql.execute(
|
||||
f"""
|
||||
UPDATE Devices SET {field} = ? WHERE devGUID = ?
|
||||
""", (value, devGUID))
|
||||
""",
|
||||
(value, devGUID),
|
||||
)
|
||||
self.db.commitDB()
|
||||
|
||||
# Delete a device by devGUID
|
||||
def delete(self, devGUID):
|
||||
if not self.exists(devGUID):
|
||||
m = f"[Device] In 'delete': GUID {devGUID} not found."
|
||||
mylog('none', m)
|
||||
mylog("none", m)
|
||||
raise ValueError(m)
|
||||
|
||||
self.db.sql.execute("DELETE FROM Devices WHERE devGUID = ?", (devGUID,))
|
||||
self.db.commitDB()
|
||||
self.db.commitDB()
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
import json
|
||||
import sys
|
||||
import uuid
|
||||
import socket
|
||||
import subprocess
|
||||
from yattag import indent
|
||||
from json2table import convert
|
||||
|
||||
# Register NetAlertX directories
|
||||
INSTALL_PATH = "/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/server"])
|
||||
|
||||
# Register NetAlertX modules
|
||||
import conf
|
||||
from const import applicationPath, logPath, apiPath, reportTemplatesPath
|
||||
from logger import mylog, Logger
|
||||
from helper import generate_mac_links, \
|
||||
removeDuplicateNewLines, \
|
||||
timeNowTZ, \
|
||||
write_file, \
|
||||
get_setting_value, \
|
||||
get_timezone_offset
|
||||
from helper import (
|
||||
generate_mac_links,
|
||||
removeDuplicateNewLines,
|
||||
timeNowTZ,
|
||||
write_file,
|
||||
get_setting_value,
|
||||
get_timezone_offset,
|
||||
)
|
||||
from messaging.in_app import write_notification
|
||||
|
||||
|
||||
@@ -47,38 +44,42 @@ class NotificationInstance:
|
||||
""")
|
||||
|
||||
# Make sure log level is initialized correctly
|
||||
Logger(get_setting_value('LOG_LEVEL'))
|
||||
Logger(get_setting_value("LOG_LEVEL"))
|
||||
|
||||
self.save()
|
||||
|
||||
# Method to override processing of notifications
|
||||
def on_before_create(self, JSON, Extra):
|
||||
|
||||
return JSON, Extra
|
||||
|
||||
# Create a new DB entry if new notifications available, otherwise skip
|
||||
def create(self, JSON, Extra=""):
|
||||
|
||||
JSON, Extra = self.on_before_create(JSON, Extra)
|
||||
|
||||
# Write output data for debug
|
||||
write_file(logPath + '/report_output.json', json.dumps(JSON))
|
||||
write_file(logPath + "/report_output.json", json.dumps(JSON))
|
||||
|
||||
# Check if nothing to report, end
|
||||
if JSON["new_devices"] == [] and JSON["down_devices"] == [] and JSON["events"] == [] and JSON["plugins"] == [] and JSON["down_reconnected"] == []:
|
||||
if (
|
||||
JSON["new_devices"] == []
|
||||
and JSON["down_devices"] == []
|
||||
and JSON["events"] == []
|
||||
and JSON["plugins"] == []
|
||||
and JSON["down_reconnected"] == []
|
||||
):
|
||||
self.HasNotifications = False
|
||||
else:
|
||||
self.HasNotifications = True
|
||||
|
||||
self.GUID = str(uuid.uuid4())
|
||||
self.DateTimeCreated = timeNowTZ()
|
||||
self.DateTimePushed = ""
|
||||
self.Status = "new"
|
||||
self.JSON = JSON
|
||||
self.Text = ""
|
||||
self.HTML = ""
|
||||
self.PublishedVia = ""
|
||||
self.Extra = Extra
|
||||
self.GUID = str(uuid.uuid4())
|
||||
self.DateTimeCreated = timeNowTZ()
|
||||
self.DateTimePushed = ""
|
||||
self.Status = "new"
|
||||
self.JSON = JSON
|
||||
self.Text = ""
|
||||
self.HTML = ""
|
||||
self.PublishedVia = ""
|
||||
self.Extra = Extra
|
||||
|
||||
if self.HasNotifications:
|
||||
# if not notiStruc.json['data'] and not notiStruc.text and not notiStruc.html:
|
||||
@@ -88,136 +89,130 @@ class NotificationInstance:
|
||||
|
||||
Text = ""
|
||||
HTML = ""
|
||||
template_file_path = reportTemplatesPath + 'report_template.html'
|
||||
template_file_path = reportTemplatesPath + "report_template.html"
|
||||
|
||||
# Open text Template
|
||||
mylog('verbose', ['[Notification] Open text Template'])
|
||||
template_file = open(reportTemplatesPath + 'report_template.txt', 'r')
|
||||
mylog("verbose", ["[Notification] Open text Template"])
|
||||
template_file = open(reportTemplatesPath + "report_template.txt", "r")
|
||||
mail_text = template_file.read()
|
||||
template_file.close()
|
||||
|
||||
# Open html Template
|
||||
mylog('verbose', ['[Notification] Open html Template'])
|
||||
mylog("verbose", ["[Notification] Open html Template"])
|
||||
|
||||
template_file = open(template_file_path, 'r')
|
||||
template_file = open(template_file_path, "r")
|
||||
mail_html = template_file.read()
|
||||
template_file.close()
|
||||
|
||||
# prepare new version text
|
||||
newVersionText = ''
|
||||
newVersionText = ""
|
||||
if conf.newVersionAvailable:
|
||||
newVersionText = '🚀A new version is available.'
|
||||
newVersionText = "🚀A new version is available."
|
||||
|
||||
mail_text = mail_text.replace('<NEW_VERSION>', newVersionText)
|
||||
mail_html = mail_html.replace('<NEW_VERSION>', newVersionText)
|
||||
mail_text = mail_text.replace("<NEW_VERSION>", newVersionText)
|
||||
mail_html = mail_html.replace("<NEW_VERSION>", newVersionText)
|
||||
|
||||
# Report "REPORT_DATE" in Header & footer
|
||||
timeFormated = timeNowTZ().strftime('%Y-%m-%d %H:%M')
|
||||
mail_text = mail_text.replace('<REPORT_DATE>', timeFormated)
|
||||
mail_html = mail_html.replace('<REPORT_DATE>', timeFormated)
|
||||
timeFormated = timeNowTZ().strftime("%Y-%m-%d %H:%M")
|
||||
mail_text = mail_text.replace("<REPORT_DATE>", timeFormated)
|
||||
mail_html = mail_html.replace("<REPORT_DATE>", timeFormated)
|
||||
|
||||
# Report "SERVER_NAME" in Header & footer
|
||||
mail_text = mail_text.replace('<SERVER_NAME>', socket.gethostname())
|
||||
mail_html = mail_html.replace('<SERVER_NAME>', socket.gethostname())
|
||||
mail_text = mail_text.replace("<SERVER_NAME>", socket.gethostname())
|
||||
mail_html = mail_html.replace("<SERVER_NAME>", socket.gethostname())
|
||||
|
||||
# Report "VERSION" in Header & footer
|
||||
try:
|
||||
VERSIONFILE = subprocess.check_output(
|
||||
['php', applicationPath + '/front/php/templates/version.php'],
|
||||
timeout=5
|
||||
).decode('utf-8')
|
||||
["php", applicationPath + "/front/php/templates/version.php"],
|
||||
timeout=5,
|
||||
).decode("utf-8")
|
||||
except Exception as e:
|
||||
mylog('debug', [f'[Notification] Unable to read version.php: {e}'])
|
||||
VERSIONFILE = 'unknown'
|
||||
mylog("debug", [f"[Notification] Unable to read version.php: {e}"])
|
||||
VERSIONFILE = "unknown"
|
||||
|
||||
mail_text = mail_text.replace('<BUILD_VERSION>', VERSIONFILE)
|
||||
mail_html = mail_html.replace('<BUILD_VERSION>', VERSIONFILE)
|
||||
mail_text = mail_text.replace("<BUILD_VERSION>", VERSIONFILE)
|
||||
mail_html = mail_html.replace("<BUILD_VERSION>", VERSIONFILE)
|
||||
|
||||
# Report "BUILD" in Header & footer
|
||||
try:
|
||||
BUILDFILE = subprocess.check_output(
|
||||
['php', applicationPath + '/front/php/templates/build.php'],
|
||||
timeout=5
|
||||
).decode('utf-8')
|
||||
["php", applicationPath + "/front/php/templates/build.php"],
|
||||
timeout=5,
|
||||
).decode("utf-8")
|
||||
except Exception as e:
|
||||
mylog('debug', [f'[Notification] Unable to read build.php: {e}'])
|
||||
BUILDFILE = 'unknown'
|
||||
mylog("debug", [f"[Notification] Unable to read build.php: {e}"])
|
||||
BUILDFILE = "unknown"
|
||||
|
||||
mail_text = mail_text.replace('<BUILD_DATE>', BUILDFILE)
|
||||
mail_html = mail_html.replace('<BUILD_DATE>', BUILDFILE)
|
||||
mail_text = mail_text.replace("<BUILD_DATE>", BUILDFILE)
|
||||
mail_html = mail_html.replace("<BUILD_DATE>", BUILDFILE)
|
||||
|
||||
# Start generating the TEXT & HTML notification messages
|
||||
# new_devices
|
||||
# ---
|
||||
html, text = construct_notifications(self.JSON, "new_devices")
|
||||
|
||||
mail_text = mail_text.replace('<NEW_DEVICES_TABLE>', text + '\n')
|
||||
mail_html = mail_html.replace('<NEW_DEVICES_TABLE>', html)
|
||||
mylog('verbose', ['[Notification] New Devices sections done.'])
|
||||
mail_text = mail_text.replace("<NEW_DEVICES_TABLE>", text + "\n")
|
||||
mail_html = mail_html.replace("<NEW_DEVICES_TABLE>", html)
|
||||
mylog("verbose", ["[Notification] New Devices sections done."])
|
||||
|
||||
# down_devices
|
||||
# ---
|
||||
html, text = construct_notifications(self.JSON, "down_devices")
|
||||
|
||||
|
||||
mail_text = mail_text.replace('<DOWN_DEVICES_TABLE>', text + '\n')
|
||||
mail_html = mail_html.replace('<DOWN_DEVICES_TABLE>', html)
|
||||
mylog('verbose', ['[Notification] Down Devices sections done.'])
|
||||
mail_text = mail_text.replace("<DOWN_DEVICES_TABLE>", text + "\n")
|
||||
mail_html = mail_html.replace("<DOWN_DEVICES_TABLE>", html)
|
||||
mylog("verbose", ["[Notification] Down Devices sections done."])
|
||||
|
||||
# down_reconnected
|
||||
# ---
|
||||
html, text = construct_notifications(self.JSON, "down_reconnected")
|
||||
|
||||
|
||||
mail_text = mail_text.replace('<DOWN_RECONNECTED_TABLE>', text + '\n')
|
||||
mail_html = mail_html.replace('<DOWN_RECONNECTED_TABLE>', html)
|
||||
mylog('verbose', ['[Notification] Reconnected Down Devices sections done.'])
|
||||
|
||||
mail_text = mail_text.replace("<DOWN_RECONNECTED_TABLE>", text + "\n")
|
||||
mail_html = mail_html.replace("<DOWN_RECONNECTED_TABLE>", html)
|
||||
mylog("verbose", ["[Notification] Reconnected Down Devices sections done."])
|
||||
|
||||
# events
|
||||
# ---
|
||||
html, text = construct_notifications(self.JSON, "events")
|
||||
|
||||
|
||||
mail_text = mail_text.replace('<EVENTS_TABLE>', text + '\n')
|
||||
mail_html = mail_html.replace('<EVENTS_TABLE>', html)
|
||||
mylog('verbose', ['[Notification] Events sections done.'])
|
||||
|
||||
mail_text = mail_text.replace("<EVENTS_TABLE>", text + "\n")
|
||||
mail_html = mail_html.replace("<EVENTS_TABLE>", html)
|
||||
mylog("verbose", ["[Notification] Events sections done."])
|
||||
|
||||
# plugins
|
||||
# ---
|
||||
html, text = construct_notifications(self.JSON, "plugins")
|
||||
|
||||
mail_text = mail_text.replace('<PLUGINS_TABLE>', text + '\n')
|
||||
mail_html = mail_html.replace('<PLUGINS_TABLE>', html)
|
||||
mail_text = mail_text.replace("<PLUGINS_TABLE>", text + "\n")
|
||||
mail_html = mail_html.replace("<PLUGINS_TABLE>", html)
|
||||
|
||||
mylog('verbose', ['[Notification] Plugins sections done.'])
|
||||
mylog("verbose", ["[Notification] Plugins sections done."])
|
||||
|
||||
final_text = removeDuplicateNewLines(mail_text)
|
||||
|
||||
# Create clickable MAC links
|
||||
mail_html = generate_mac_links(mail_html, conf.REPORT_DASHBOARD_URL + '/deviceDetails.php?mac=')
|
||||
mail_html = generate_mac_links(
|
||||
mail_html, conf.REPORT_DASHBOARD_URL + "/deviceDetails.php?mac="
|
||||
)
|
||||
|
||||
final_html = indent(
|
||||
mail_html,
|
||||
indentation=' ',
|
||||
newline='\r\n',
|
||||
indent_text=True
|
||||
mail_html, indentation=" ", newline="\r\n", indent_text=True
|
||||
)
|
||||
|
||||
send_api(self.JSON, final_text, final_html)
|
||||
|
||||
# Write output data for debug
|
||||
write_file(logPath + '/report_output.txt', final_text)
|
||||
write_file(logPath + '/report_output.html', final_html)
|
||||
write_file(logPath + "/report_output.txt", final_text)
|
||||
write_file(logPath + "/report_output.html", final_html)
|
||||
|
||||
mylog('minimal', ['[Notification] Udating API files'])
|
||||
mylog("minimal", ["[Notification] Udating API files"])
|
||||
|
||||
self.Text = final_text
|
||||
self.HTML = final_html
|
||||
self.Text = final_text
|
||||
self.HTML = final_html
|
||||
|
||||
# Notify frontend
|
||||
write_notification(f'Report:{self.GUID}', "alert", self.DateTimeCreated)
|
||||
write_notification(f"Report:{self.GUID}", "alert", self.DateTimeCreated)
|
||||
|
||||
self.upsert()
|
||||
|
||||
@@ -236,20 +231,36 @@ class NotificationInstance:
|
||||
|
||||
# create or update a notification
|
||||
def upsert(self):
|
||||
self.db.sql.execute("""
|
||||
self.db.sql.execute(
|
||||
"""
|
||||
INSERT OR REPLACE INTO Notifications (GUID, DateTimeCreated, DateTimePushed, Status, JSON, Text, HTML, PublishedVia, Extra)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""", (self.GUID, self.DateTimeCreated, self.DateTimePushed, self.Status, json.dumps(self.JSON), self.Text, self.HTML, self.PublishedVia, self.Extra))
|
||||
""",
|
||||
(
|
||||
self.GUID,
|
||||
self.DateTimeCreated,
|
||||
self.DateTimePushed,
|
||||
self.Status,
|
||||
json.dumps(self.JSON),
|
||||
self.Text,
|
||||
self.HTML,
|
||||
self.PublishedVia,
|
||||
self.Extra,
|
||||
),
|
||||
)
|
||||
|
||||
self.save()
|
||||
|
||||
# Remove notification object by GUID
|
||||
def remove(self, GUID):
|
||||
# Execute an SQL query to delete the notification with the specified GUID
|
||||
self.db.sql.execute("""
|
||||
self.db.sql.execute(
|
||||
"""
|
||||
DELETE FROM Notifications
|
||||
WHERE GUID = ?
|
||||
""", (GUID,))
|
||||
""",
|
||||
(GUID,),
|
||||
)
|
||||
self.save()
|
||||
|
||||
# Get all with the "new" status
|
||||
@@ -262,7 +273,6 @@ class NotificationInstance:
|
||||
|
||||
# Set all to "processed" status
|
||||
def setAllProcessed(self):
|
||||
|
||||
# Execute an SQL query to update the status of all notifications
|
||||
self.db.sql.execute("""
|
||||
UPDATE Notifications
|
||||
@@ -274,15 +284,17 @@ class NotificationInstance:
|
||||
|
||||
# Clear the Pending Email flag from all events and devices
|
||||
def clearPendingEmailFlag(self):
|
||||
|
||||
# Clean Pending Alert Events
|
||||
self.db.sql.execute("""
|
||||
self.db.sql.execute(
|
||||
"""
|
||||
UPDATE Devices SET devLastNotification = ?
|
||||
WHERE devMac IN (
|
||||
SELECT eve_MAC FROM Events
|
||||
WHERE eve_PendingAlertEmail = 1
|
||||
)
|
||||
""", (timeNowTZ(),))
|
||||
""",
|
||||
(timeNowTZ(),),
|
||||
)
|
||||
|
||||
self.db.sql.execute("""
|
||||
UPDATE Events SET eve_PendingAlertEmail = 0
|
||||
@@ -290,23 +302,26 @@ class NotificationInstance:
|
||||
AND eve_EventType !='Device Down' """)
|
||||
|
||||
# Clear down events flag after the reporting window passed
|
||||
minutes = int(get_setting_value('NTFPRCS_alert_down_time') or 0)
|
||||
minutes = int(get_setting_value("NTFPRCS_alert_down_time") or 0)
|
||||
tz_offset = get_timezone_offset()
|
||||
self.db.sql.execute("""
|
||||
self.db.sql.execute(
|
||||
"""
|
||||
UPDATE Events
|
||||
SET eve_PendingAlertEmail = 0
|
||||
WHERE eve_PendingAlertEmail = 1
|
||||
AND eve_EventType = 'Device Down'
|
||||
AND eve_DateTime < datetime('now', ?, ?)
|
||||
""", (f"-{minutes} minutes", tz_offset))
|
||||
""",
|
||||
(f"-{minutes} minutes", tz_offset),
|
||||
)
|
||||
|
||||
mylog('minimal', ['[Notification] Notifications changes: ',
|
||||
self.db.sql.rowcount])
|
||||
mylog(
|
||||
"minimal", ["[Notification] Notifications changes: ", self.db.sql.rowcount]
|
||||
)
|
||||
|
||||
# clear plugin events
|
||||
self.clearPluginEvents()
|
||||
|
||||
|
||||
def clearPluginEvents(self):
|
||||
# clear plugin events table
|
||||
self.db.sql.execute("DELETE FROM Plugins_Events")
|
||||
@@ -321,20 +336,20 @@ class NotificationInstance:
|
||||
# Reporting
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def construct_notifications(JSON, section):
|
||||
|
||||
jsn = JSON[section]
|
||||
|
||||
# Return if empty
|
||||
if jsn == []:
|
||||
return '', ''
|
||||
return "", ""
|
||||
|
||||
tableTitle = JSON[section + "_meta"]["title"]
|
||||
headers = JSON[section + "_meta"]["columnNames"]
|
||||
tableTitle = JSON[section + "_meta"]["title"]
|
||||
headers = JSON[section + "_meta"]["columnNames"]
|
||||
|
||||
html = ''
|
||||
text = ''
|
||||
html = ""
|
||||
text = ""
|
||||
|
||||
table_attributes = {
|
||||
"style": "border-collapse: collapse; font-size: 12px; color:#70707",
|
||||
@@ -342,28 +357,32 @@ def construct_notifications(JSON, section):
|
||||
"cellspacing": 0,
|
||||
"cellpadding": "3px",
|
||||
"bordercolor": "#C0C0C0",
|
||||
"border": "1"
|
||||
}
|
||||
headerProps = "width='120px' style='color:white; font-size: 16px;' bgcolor='#64a0d6' "
|
||||
"border": "1",
|
||||
}
|
||||
headerProps = (
|
||||
"width='120px' style='color:white; font-size: 16px;' bgcolor='#64a0d6' "
|
||||
)
|
||||
thProps = "width='120px' style='color:#F0F0F0' bgcolor='#64a0d6' "
|
||||
|
||||
build_direction = "TOP_TO_BOTTOM"
|
||||
text_line = '{}\t{}\n'
|
||||
text_line = "{}\t{}\n"
|
||||
|
||||
if len(jsn) > 0:
|
||||
text = tableTitle + "\n---------\n"
|
||||
|
||||
# Convert a JSON into an HTML table
|
||||
html = convert({"data": jsn}, build_direction=build_direction, table_attributes=table_attributes)
|
||||
html = convert(
|
||||
{"data": jsn},
|
||||
build_direction=build_direction,
|
||||
table_attributes=table_attributes,
|
||||
)
|
||||
|
||||
# Cleanup the generated HTML table notification
|
||||
html = format_table(html,
|
||||
"data",
|
||||
headerProps,
|
||||
tableTitle).replace('<ul>',
|
||||
'<ul style="list-style:none;padding-left:0">'
|
||||
).replace("<td>null</td>",
|
||||
"<td></td>")
|
||||
html = (
|
||||
format_table(html, "data", headerProps, tableTitle)
|
||||
.replace("<ul>", '<ul style="list-style:none;padding-left:0">')
|
||||
.replace("<td>null</td>", "<td></td>")
|
||||
)
|
||||
|
||||
# prepare text-only message
|
||||
for device in jsn:
|
||||
@@ -371,8 +390,8 @@ def construct_notifications(JSON, section):
|
||||
padding = ""
|
||||
if len(header) < 4:
|
||||
padding = "\t"
|
||||
text += text_line.format(header + ': ' + padding, device[header])
|
||||
text += '\n'
|
||||
text += text_line.format(header + ": " + padding, device[header])
|
||||
text += "\n"
|
||||
|
||||
# Format HTML table headers
|
||||
for header in headers:
|
||||
@@ -383,18 +402,19 @@ def construct_notifications(JSON, section):
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def send_api(json_final, mail_text, mail_html):
|
||||
mylog('verbose', ['[Send API] Updating notification_* files in ', apiPath])
|
||||
mylog("verbose", ["[Send API] Updating notification_* files in ", apiPath])
|
||||
|
||||
write_file(apiPath + 'notification_text.txt', mail_text)
|
||||
write_file(apiPath + 'notification_text.html', mail_html)
|
||||
write_file(apiPath + 'notification_json_final.json', json.dumps(json_final))
|
||||
write_file(apiPath + "notification_text.txt", mail_text)
|
||||
write_file(apiPath + "notification_text.html", mail_html)
|
||||
write_file(apiPath + "notification_json_final.json", json.dumps(json_final))
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Replacing table headers
|
||||
def format_table(html, thValue, props, newThValue=''):
|
||||
|
||||
if newThValue == '':
|
||||
def format_table(html, thValue, props, newThValue=""):
|
||||
if newThValue == "":
|
||||
newThValue = thValue
|
||||
|
||||
return html.replace("<th>"+thValue+"</th>", "<th "+props+" >"+newThValue+"</th>")
|
||||
return html.replace(
|
||||
"<th>" + thValue + "</th>", "<th " + props + " >" + newThValue + "</th>"
|
||||
)
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import sys
|
||||
|
||||
# Register NetAlertX directories
|
||||
INSTALL_PATH="/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/server"])
|
||||
|
||||
from logger import mylog
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
# Plugin object handling (WIP)
|
||||
#-------------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------------
|
||||
class PluginObjectInstance:
|
||||
def __init__(self, db):
|
||||
self.db = db
|
||||
@@ -19,16 +14,21 @@ class PluginObjectInstance:
|
||||
SELECT * FROM Plugins_Objects
|
||||
""")
|
||||
return self.db.sql.fetchall()
|
||||
|
||||
|
||||
# Get plugin object by ObjectGUID
|
||||
def getByGUID(self, ObjectGUID):
|
||||
self.db.sql.execute("SELECT * FROM Plugins_Objects WHERE ObjectGUID = ?", (ObjectGUID,))
|
||||
self.db.sql.execute(
|
||||
"SELECT * FROM Plugins_Objects WHERE ObjectGUID = ?", (ObjectGUID,)
|
||||
)
|
||||
result = self.db.sql.fetchone()
|
||||
return dict(result) if result else None
|
||||
|
||||
# Check if a plugin object exists by ObjectGUID
|
||||
def exists(self, ObjectGUID):
|
||||
self.db.sql.execute("SELECT COUNT(*) AS count FROM Plugins_Objects WHERE ObjectGUID = ?", (ObjectGUID,))
|
||||
self.db.sql.execute(
|
||||
"SELECT COUNT(*) AS count FROM Plugins_Objects WHERE ObjectGUID = ?",
|
||||
(ObjectGUID,),
|
||||
)
|
||||
result = self.db.sql.fetchone()
|
||||
return result["count"] > 0
|
||||
|
||||
@@ -36,30 +36,35 @@ class PluginObjectInstance:
|
||||
def getByPlugin(self, plugin):
|
||||
self.db.sql.execute("SELECT * FROM Plugins_Objects WHERE Plugin = ?", (plugin,))
|
||||
return self.db.sql.fetchall()
|
||||
|
||||
|
||||
# Get objects by status
|
||||
def getByStatus(self, status):
|
||||
self.db.sql.execute("SELECT * FROM Plugins_Objects WHERE Status = ?", (status,))
|
||||
return self.db.sql.fetchall()
|
||||
|
||||
|
||||
# Update a specific field for a plugin object
|
||||
def updateField(self, ObjectGUID, field, value):
|
||||
if not self.exists(ObjectGUID):
|
||||
m = f"[PluginObject] In 'updateField': GUID {ObjectGUID} not found."
|
||||
mylog('none', m)
|
||||
mylog("none", m)
|
||||
raise ValueError(m)
|
||||
|
||||
self.db.sql.execute(f"""
|
||||
self.db.sql.execute(
|
||||
f"""
|
||||
UPDATE Plugins_Objects SET {field} = ? WHERE ObjectGUID = ?
|
||||
""", (value, ObjectGUID))
|
||||
""",
|
||||
(value, ObjectGUID),
|
||||
)
|
||||
self.db.commitDB()
|
||||
|
||||
|
||||
# Delete a plugin object by ObjectGUID
|
||||
def delete(self, ObjectGUID):
|
||||
if not self.exists(ObjectGUID):
|
||||
m = f"[PluginObject] In 'delete': GUID {ObjectGUID} not found."
|
||||
mylog('none', m)
|
||||
mylog("none", m)
|
||||
raise ValueError(m)
|
||||
|
||||
self.db.sql.execute("DELETE FROM Plugins_Objects WHERE ObjectGUID = ?", (ObjectGUID,))
|
||||
self.db.sql.execute(
|
||||
"DELETE FROM Plugins_Objects WHERE ObjectGUID = ?", (ObjectGUID,)
|
||||
)
|
||||
self.db.commitDB()
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Register NetAlertX directories
|
||||
INSTALL_PATH="/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/server"])
|
||||
|
||||
# Register NetAlertX modules
|
||||
from const import pluginsPath, logPath, applicationPath, reportTemplatesPath
|
||||
from const import logPath
|
||||
from logger import mylog
|
||||
|
||||
|
||||
class UserEventsQueueInstance:
|
||||
"""
|
||||
Handles the execution queue log file, allowing reading, writing,
|
||||
@@ -19,12 +14,11 @@ class UserEventsQueueInstance:
|
||||
self.log_path = logPath
|
||||
self.log_file = os.path.join(self.log_path, "execution_queue.log")
|
||||
|
||||
|
||||
def has_update_devices(self):
|
||||
lines = self.read_log()
|
||||
|
||||
for line in lines:
|
||||
if 'update_api|devices' in line:
|
||||
if "update_api|devices" in line:
|
||||
return True
|
||||
|
||||
return False
|
||||
@@ -35,7 +29,10 @@ class UserEventsQueueInstance:
|
||||
Returns an empty list if the file doesn't exist.
|
||||
"""
|
||||
if not os.path.exists(self.log_file):
|
||||
mylog('none', ['[UserEventsQueueInstance] Log file not found: ', self.log_file])
|
||||
mylog(
|
||||
"none",
|
||||
["[UserEventsQueueInstance] Log file not found: ", self.log_file],
|
||||
)
|
||||
return [] # No log file, return empty list
|
||||
with open(self.log_file, "r") as file:
|
||||
return file.readlines()
|
||||
@@ -64,7 +61,9 @@ class UserEventsQueueInstance:
|
||||
# Process the log file line by line
|
||||
with open(self.log_file, "r") as file:
|
||||
for line in file:
|
||||
columns = line.strip().split('|')[2:4] # Extract event and param columns
|
||||
columns = line.strip().split("|")[
|
||||
2:4
|
||||
] # Extract event and param columns
|
||||
if len(columns) == 2:
|
||||
event_name, _ = columns
|
||||
if event_name == event and not removed:
|
||||
@@ -76,10 +75,6 @@ class UserEventsQueueInstance:
|
||||
# Write back the remaining lines
|
||||
self.write_log(updated_lines)
|
||||
|
||||
|
||||
mylog('minimal', ['[UserEventsQueueInstance] Processed event: ', event])
|
||||
mylog("minimal", ["[UserEventsQueueInstance] Processed event: ", event])
|
||||
|
||||
return removed
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user