mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
This commit is contained in:
@@ -186,9 +186,15 @@ def main ():
|
|||||||
|
|
||||||
pm.run_plugin_scripts('on_notification')
|
pm.run_plugin_scripts('on_notification')
|
||||||
notification.setAllProcessed()
|
notification.setAllProcessed()
|
||||||
|
|
||||||
|
# clear pending email flag
|
||||||
|
# and the plugin events
|
||||||
notification.clearPendingEmailFlag()
|
notification.clearPendingEmailFlag()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
# If there are no notifications to process,
|
||||||
|
# we still need to clear all plugin events
|
||||||
|
notification.clearPluginEvents()
|
||||||
mylog('verbose', ['[Notification] No changes to report'])
|
mylog('verbose', ['[Notification] No changes to report'])
|
||||||
|
|
||||||
# Commit SQL
|
# Commit SQL
|
||||||
|
|||||||
@@ -1,35 +1,36 @@
|
|||||||
import datetime
|
|
||||||
import os
|
|
||||||
import _io
|
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
import uuid
|
import uuid
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
import requests
|
|
||||||
from yattag import indent
|
from yattag import indent
|
||||||
from json2table import convert
|
from json2table import convert
|
||||||
|
|
||||||
# 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"])
|
||||||
|
|
||||||
# Register NetAlertX modules
|
# Register NetAlertX modules
|
||||||
import conf
|
import conf
|
||||||
from const import applicationPath, logPath, apiPath, confFileName, reportTemplatesPath
|
from const import applicationPath, logPath, apiPath, reportTemplatesPath
|
||||||
from logger import logResult, mylog
|
from logger import 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, \
|
||||||
|
timeNowTZ, \
|
||||||
|
write_file, \
|
||||||
|
get_setting_value, \
|
||||||
|
get_timezone_offset
|
||||||
from messaging.in_app import write_notification
|
from messaging.in_app import write_notification
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Notification object handling
|
# Notification object handling
|
||||||
#-------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
class NotificationInstance:
|
class NotificationInstance:
|
||||||
def __init__(self, db):
|
def __init__(self, db):
|
||||||
self.db = db
|
self.db = db
|
||||||
|
|
||||||
# Create Notifications table if missing
|
# Create Notifications table if missing
|
||||||
self.db.sql.execute("""CREATE TABLE IF NOT EXISTS "Notifications" (
|
self.db.sql.execute("""CREATE TABLE IF NOT EXISTS "Notifications" (
|
||||||
"Index" INTEGER,
|
"Index" INTEGER,
|
||||||
"GUID" TEXT UNIQUE,
|
"GUID" TEXT UNIQUE,
|
||||||
@@ -48,24 +49,23 @@ class NotificationInstance:
|
|||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
# Method to override processing of notifications
|
# Method to override processing of notifications
|
||||||
def on_before_create(self, JSON, Extra):
|
def on_before_create(self, JSON, Extra):
|
||||||
|
|
||||||
return JSON, Extra
|
return JSON, Extra
|
||||||
|
|
||||||
|
|
||||||
# Create a new DB entry if new notifications available, otherwise skip
|
# Create a new DB entry if new notifications available, otherwise skip
|
||||||
def create(self, JSON, Extra=""):
|
def create(self, JSON, Extra=""):
|
||||||
|
|
||||||
JSON, Extra = self.on_before_create(JSON, Extra)
|
JSON, Extra = self.on_before_create(JSON, Extra)
|
||||||
|
|
||||||
# Write output data for debug
|
# 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
|
# 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
|
self.HasNotifications = False
|
||||||
else:
|
else:
|
||||||
self.HasNotifications = True
|
self.HasNotifications = True
|
||||||
|
|
||||||
self.GUID = str(uuid.uuid4())
|
self.GUID = str(uuid.uuid4())
|
||||||
self.DateTimeCreated = timeNowTZ()
|
self.DateTimeCreated = timeNowTZ()
|
||||||
@@ -78,17 +78,14 @@ class NotificationInstance:
|
|||||||
self.Extra = Extra
|
self.Extra = Extra
|
||||||
|
|
||||||
if self.HasNotifications:
|
if self.HasNotifications:
|
||||||
|
|
||||||
|
|
||||||
# if not notiStruc.json['data'] and not notiStruc.text and not notiStruc.html:
|
# if not notiStruc.json['data'] and not notiStruc.text and not notiStruc.html:
|
||||||
# mylog('debug', '[Notification] notiStruc is empty')
|
# mylog('debug', '[Notification] notiStruc is empty')
|
||||||
# else:
|
# else:
|
||||||
# mylog('debug', ['[Notification] notiStruc:', json.dumps(notiStruc.__dict__, indent=4)])
|
# mylog('debug', ['[Notification] notiStruc:', json.dumps(notiStruc.__dict__, indent=4)])
|
||||||
|
|
||||||
Text = ""
|
|
||||||
HTML = ""
|
|
||||||
template_file_path = reportTemplatesPath + 'report_template.html'
|
|
||||||
|
|
||||||
|
Text = ""
|
||||||
|
HTML = ""
|
||||||
|
template_file_path = reportTemplatesPath + 'report_template.html'
|
||||||
|
|
||||||
# Open text Template
|
# Open text Template
|
||||||
mylog('verbose', ['[Notification] Open text Template'])
|
mylog('verbose', ['[Notification] Open text Template'])
|
||||||
@@ -99,44 +96,60 @@ class NotificationInstance:
|
|||||||
# Open html Template
|
# 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()
|
mail_html = template_file.read()
|
||||||
template_file.close()
|
template_file.close()
|
||||||
|
|
||||||
# prepare new version text
|
# prepare new version text
|
||||||
newVersionText = ''
|
newVersionText = ''
|
||||||
if conf.newVersionAvailable :
|
if conf.newVersionAvailable:
|
||||||
newVersionText = '🚀A new version is available.'
|
newVersionText = '🚀A new version is available.'
|
||||||
|
|
||||||
mail_text = mail_text.replace ('<NEW_VERSION>', newVersionText)
|
mail_text = mail_text.replace('<NEW_VERSION>', newVersionText)
|
||||||
mail_html = mail_html.replace ('<NEW_VERSION>', newVersionText)
|
mail_html = mail_html.replace('<NEW_VERSION>', newVersionText)
|
||||||
|
|
||||||
# Report "REPORT_DATE" in Header & footer
|
# Report "REPORT_DATE" in Header & footer
|
||||||
timeFormated = timeNowTZ().strftime ('%Y-%m-%d %H:%M')
|
timeFormated = timeNowTZ().strftime('%Y-%m-%d %H:%M')
|
||||||
mail_text = mail_text.replace ('<REPORT_DATE>', timeFormated)
|
mail_text = mail_text.replace('<REPORT_DATE>', timeFormated)
|
||||||
mail_html = mail_html.replace ('<REPORT_DATE>', timeFormated)
|
mail_html = mail_html.replace('<REPORT_DATE>', timeFormated)
|
||||||
|
|
||||||
# Report "SERVER_NAME" in Header & footer
|
# Report "SERVER_NAME" in Header & footer
|
||||||
mail_text = mail_text.replace ('<SERVER_NAME>', socket.gethostname() )
|
mail_text = mail_text.replace('<SERVER_NAME>', socket.gethostname())
|
||||||
mail_html = mail_html.replace ('<SERVER_NAME>', socket.gethostname() )
|
mail_html = mail_html.replace('<SERVER_NAME>', socket.gethostname())
|
||||||
|
|
||||||
# Report "VERSION" in Header & footer
|
# Report "VERSION" in Header & footer
|
||||||
VERSIONFILE = subprocess.check_output(['php', applicationPath + '/front/php/templates/version.php']).decode('utf-8')
|
try:
|
||||||
mail_text = mail_text.replace ('<BUILD_VERSION>', VERSIONFILE)
|
VERSIONFILE = subprocess.check_output(
|
||||||
mail_html = mail_html.replace ('<BUILD_VERSION>', VERSIONFILE)
|
['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'
|
||||||
|
|
||||||
|
mail_text = mail_text.replace('<BUILD_VERSION>', VERSIONFILE)
|
||||||
|
mail_html = mail_html.replace('<BUILD_VERSION>', VERSIONFILE)
|
||||||
|
|
||||||
# Report "BUILD" in Header & footer
|
# Report "BUILD" in Header & footer
|
||||||
BUILDFILE = subprocess.check_output(['php', applicationPath + '/front/php/templates/build.php']).decode('utf-8')
|
try:
|
||||||
mail_text = mail_text.replace ('<BUILD_DATE>', BUILDFILE)
|
BUILDFILE = subprocess.check_output(
|
||||||
mail_html = mail_html.replace ('<BUILD_DATE>', BUILDFILE)
|
['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'
|
||||||
|
|
||||||
|
mail_text = mail_text.replace('<BUILD_DATE>', BUILDFILE)
|
||||||
|
mail_html = mail_html.replace('<BUILD_DATE>', BUILDFILE)
|
||||||
|
|
||||||
# Start generating the TEXT & HTML notification messages
|
# Start generating the TEXT & HTML notification messages
|
||||||
# new_devices
|
# new_devices
|
||||||
# ---
|
# ---
|
||||||
html, text = construct_notifications(self.JSON, "new_devices")
|
html, text = construct_notifications(self.JSON, "new_devices")
|
||||||
|
|
||||||
mail_text = mail_text.replace ('<NEW_DEVICES_TABLE>', text + '\n')
|
mail_text = mail_text.replace('<NEW_DEVICES_TABLE>', text + '\n')
|
||||||
mail_html = mail_html.replace ('<NEW_DEVICES_TABLE>', html)
|
mail_html = mail_html.replace('<NEW_DEVICES_TABLE>', html)
|
||||||
mylog('verbose', ['[Notification] New Devices sections done.'])
|
mylog('verbose', ['[Notification] New Devices sections done.'])
|
||||||
|
|
||||||
# down_devices
|
# down_devices
|
||||||
@@ -144,56 +157,56 @@ class NotificationInstance:
|
|||||||
html, text = construct_notifications(self.JSON, "down_devices")
|
html, text = construct_notifications(self.JSON, "down_devices")
|
||||||
|
|
||||||
|
|
||||||
mail_text = mail_text.replace ('<DOWN_DEVICES_TABLE>', text + '\n')
|
mail_text = mail_text.replace('<DOWN_DEVICES_TABLE>', text + '\n')
|
||||||
mail_html = mail_html.replace ('<DOWN_DEVICES_TABLE>', html)
|
mail_html = mail_html.replace('<DOWN_DEVICES_TABLE>', html)
|
||||||
mylog('verbose', ['[Notification] Down Devices sections done.'])
|
mylog('verbose', ['[Notification] Down Devices sections done.'])
|
||||||
|
|
||||||
# down_reconnected
|
# down_reconnected
|
||||||
# ---
|
# ---
|
||||||
html, text = construct_notifications(self.JSON, "down_reconnected")
|
html, text = construct_notifications(self.JSON, "down_reconnected")
|
||||||
|
|
||||||
|
|
||||||
mail_text = mail_text.replace ('<DOWN_RECONNECTED_TABLE>', text + '\n')
|
mail_text = mail_text.replace('<DOWN_RECONNECTED_TABLE>', text + '\n')
|
||||||
mail_html = mail_html.replace ('<DOWN_RECONNECTED_TABLE>', html)
|
mail_html = mail_html.replace('<DOWN_RECONNECTED_TABLE>', html)
|
||||||
mylog('verbose', ['[Notification] Reconnected Down Devices sections done.'])
|
mylog('verbose', ['[Notification] Reconnected Down Devices sections done.'])
|
||||||
|
|
||||||
|
|
||||||
# events
|
# events
|
||||||
# ---
|
# ---
|
||||||
html, text = construct_notifications(self.JSON, "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)
|
mail_text = mail_text.replace('<EVENTS_TABLE>', text + '\n')
|
||||||
mylog('verbose', ['[Notification] Events sections done.'])
|
mail_html = mail_html.replace('<EVENTS_TABLE>', html)
|
||||||
|
mylog('verbose', ['[Notification] Events sections done.'])
|
||||||
|
|
||||||
|
|
||||||
# plugins
|
# plugins
|
||||||
# ---
|
# ---
|
||||||
html, text = construct_notifications(self.JSON, "plugins")
|
html, text = construct_notifications(self.JSON, "plugins")
|
||||||
|
|
||||||
mail_text = mail_text.replace ('<PLUGINS_TABLE>', text + '\n')
|
mail_text = mail_text.replace('<PLUGINS_TABLE>', text + '\n')
|
||||||
mail_html = mail_html.replace ('<PLUGINS_TABLE>', html)
|
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)
|
final_text = removeDuplicateNewLines(mail_text)
|
||||||
|
|
||||||
# Create clickable MAC links
|
# 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(
|
final_html = indent(
|
||||||
mail_html,
|
mail_html,
|
||||||
indentation = ' ',
|
indentation=' ',
|
||||||
newline = '\r\n',
|
newline='\r\n',
|
||||||
indent_text = True
|
indent_text=True
|
||||||
)
|
)
|
||||||
|
|
||||||
send_api(self.JSON, final_text, final_html)
|
send_api(self.JSON, final_text, final_html)
|
||||||
|
|
||||||
# Write output data for debug
|
# Write output data for debug
|
||||||
write_file (logPath + '/report_output.txt', final_text)
|
write_file(logPath + '/report_output.txt', final_text)
|
||||||
write_file (logPath + '/report_output.html', final_html)
|
write_file(logPath + '/report_output.html', final_html)
|
||||||
|
|
||||||
mylog('minimal', ['[Notification] Udating API files'])
|
mylog('minimal', ['[Notification] Udating API files'])
|
||||||
|
|
||||||
@@ -201,10 +214,10 @@ class NotificationInstance:
|
|||||||
self.HTML = final_html
|
self.HTML = final_html
|
||||||
|
|
||||||
# Notify frontend
|
# Notify frontend
|
||||||
write_notification(f'Report:{self.GUID}', "alert", self.DateTimeCreated )
|
write_notification(f'Report:{self.GUID}', "alert", self.DateTimeCreated)
|
||||||
|
|
||||||
self.upsert()
|
self.upsert()
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
# Only updates the status
|
# Only updates the status
|
||||||
@@ -216,9 +229,9 @@ class NotificationInstance:
|
|||||||
def updatePublishedVia(self, newPublishedVia):
|
def updatePublishedVia(self, newPublishedVia):
|
||||||
self.PublishedVia = newPublishedVia
|
self.PublishedVia = newPublishedVia
|
||||||
self.DateTimePushed = timeNowTZ()
|
self.DateTimePushed = timeNowTZ()
|
||||||
self.upsert()
|
self.upsert()
|
||||||
|
|
||||||
# create or update a notification
|
# create or update a notification
|
||||||
def upsert(self):
|
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)
|
INSERT OR REPLACE INTO Notifications (GUID, DateTimeCreated, DateTimePushed, Status, JSON, Text, HTML, PublishedVia, Extra)
|
||||||
@@ -256,57 +269,63 @@ class NotificationInstance:
|
|||||||
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
# Clear the Pending Email flag from all events and devices
|
||||||
|
|
||||||
|
|
||||||
def clearPendingEmailFlag(self):
|
def clearPendingEmailFlag(self):
|
||||||
|
|
||||||
# Clean Pending Alert Events
|
# Clean Pending Alert Events
|
||||||
self.db.sql.execute ("""UPDATE Devices SET devLastNotification = ?
|
self.db.sql.execute("""
|
||||||
WHERE devMac IN (
|
UPDATE Devices SET devLastNotification = ?
|
||||||
SELECT eve_MAC FROM Events
|
WHERE devMac IN (
|
||||||
WHERE eve_PendingAlertEmail = 1
|
SELECT eve_MAC FROM Events
|
||||||
)
|
WHERE eve_PendingAlertEmail = 1
|
||||||
""", (timeNowTZ(),) )
|
)
|
||||||
|
""", (timeNowTZ(),))
|
||||||
|
|
||||||
self.db.sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
|
self.db.sql.execute("""
|
||||||
WHERE eve_PendingAlertEmail = 1
|
UPDATE Events SET eve_PendingAlertEmail = 0
|
||||||
AND eve_EventType !='Device Down' """)
|
WHERE eve_PendingAlertEmail = 1
|
||||||
|
AND eve_EventType !='Device Down' """)
|
||||||
|
|
||||||
# Clear down events flag after the reporting window passed
|
# Clear down events flag after the reporting window passed
|
||||||
self.db.sql.execute (f"""UPDATE Events SET eve_PendingAlertEmail = 0
|
minutes = int(get_setting_value('NTFPRCS_alert_down_time') or 0)
|
||||||
WHERE eve_PendingAlertEmail = 1
|
tz_offset = get_timezone_offset()
|
||||||
AND eve_EventType =='Device Down'
|
self.db.sql.execute("""
|
||||||
AND eve_DateTime < datetime('now', '-{get_setting_value('NTFPRCS_alert_down_time')} minutes', '{get_timezone_offset()}')
|
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))
|
||||||
|
|
||||||
|
mylog('minimal', ['[Notification] Notifications changes: ',
|
||||||
|
self.db.sql.rowcount])
|
||||||
|
|
||||||
# clear plugin events
|
# clear plugin events
|
||||||
self.db.sql.execute ("DELETE FROM Plugins_Events")
|
self.clearPluginEvents()
|
||||||
|
|
||||||
# DEBUG - print number of rows updated
|
|
||||||
mylog('minimal', ['[Notification] Notifications changes: ', self.db.sql.rowcount])
|
|
||||||
|
|
||||||
|
def clearPluginEvents(self):
|
||||||
|
# clear plugin events table
|
||||||
|
self.db.sql.execute("DELETE FROM Plugins_Events")
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
# Commit changes
|
# Commit changes
|
||||||
self.db.commitDB()
|
self.db.commitDB()
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
# Reporting
|
# Reporting
|
||||||
#-------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
def construct_notifications(JSON, section):
|
def construct_notifications(JSON, section):
|
||||||
|
|
||||||
jsn = JSON[section]
|
jsn = JSON[section]
|
||||||
|
|
||||||
# Return if empty
|
# Return if empty
|
||||||
if jsn == []:
|
if jsn == []:
|
||||||
return '',''
|
return '', ''
|
||||||
|
|
||||||
tableTitle = JSON[section + "_meta"]["title"]
|
tableTitle = JSON[section + "_meta"]["title"]
|
||||||
headers = JSON[section + "_meta"]["columnNames"]
|
headers = JSON[section + "_meta"]["columnNames"]
|
||||||
@@ -314,22 +333,34 @@ def construct_notifications(JSON, section):
|
|||||||
html = ''
|
html = ''
|
||||||
text = ''
|
text = ''
|
||||||
|
|
||||||
table_attributes = {"style" : "border-collapse: collapse; font-size: 12px; color:#70707", "width" : "100%", "cellspacing" : 0, "cellpadding" : "3px", "bordercolor" : "#C0C0C0", "border":"1"}
|
table_attributes = {
|
||||||
|
"style": "border-collapse: collapse; font-size: 12px; color:#70707",
|
||||||
|
"width": "100%",
|
||||||
|
"cellspacing": 0,
|
||||||
|
"cellpadding": "3px",
|
||||||
|
"bordercolor": "#C0C0C0",
|
||||||
|
"border": "1"
|
||||||
|
}
|
||||||
headerProps = "width='120px' style='color:white; font-size: 16px;' bgcolor='#64a0d6' "
|
headerProps = "width='120px' style='color:white; font-size: 16px;' bgcolor='#64a0d6' "
|
||||||
thProps = "width='120px' style='color:#F0F0F0' bgcolor='#64a0d6' "
|
thProps = "width='120px' style='color:#F0F0F0' bgcolor='#64a0d6' "
|
||||||
|
|
||||||
build_direction = "TOP_TO_BOTTOM"
|
build_direction = "TOP_TO_BOTTOM"
|
||||||
text_line = '{}\t{}\n'
|
text_line = '{}\t{}\n'
|
||||||
|
|
||||||
|
|
||||||
if len(jsn) > 0:
|
if len(jsn) > 0:
|
||||||
text = tableTitle + "\n---------\n"
|
text = tableTitle + "\n---------\n"
|
||||||
|
|
||||||
# Convert a JSON into an HTML table
|
# 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
|
# 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
|
# prepare text-only message
|
||||||
for device in jsn:
|
for device in jsn:
|
||||||
@@ -337,7 +368,7 @@ def construct_notifications(JSON, section):
|
|||||||
padding = ""
|
padding = ""
|
||||||
if len(header) < 4:
|
if len(header) < 4:
|
||||||
padding = "\t"
|
padding = "\t"
|
||||||
text += text_line.format ( header + ': ' + padding, device[header])
|
text += text_line.format(header + ': ' + padding, device[header])
|
||||||
text += '\n'
|
text += '\n'
|
||||||
|
|
||||||
# Format HTML table headers
|
# Format HTML table headers
|
||||||
@@ -346,24 +377,21 @@ def construct_notifications(JSON, section):
|
|||||||
|
|
||||||
return html, text
|
return html, text
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
def send_api(json_final, mail_text, mail_html):
|
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.txt', mail_text)
|
||||||
write_file(apiPath + 'notification_text.html' , mail_html)
|
write_file(apiPath + 'notification_text.html', mail_html)
|
||||||
write_file(apiPath + 'notification_json_final.json' , json.dumps(json_final))
|
write_file(apiPath + 'notification_json_final.json', json.dumps(json_final))
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# Replacing table headers
|
# Replacing table headers
|
||||||
def format_table (html, thValue, props, newThValue = ''):
|
def format_table(html, thValue, props, newThValue=''):
|
||||||
|
|
||||||
if newThValue == '':
|
if newThValue == '':
|
||||||
newThValue = thValue
|
newThValue = thValue
|
||||||
|
|
||||||
return html.replace("<th>"+thValue+"</th>", "<th "+props+" >"+newThValue+"</th>" )
|
return html.replace("<th>"+thValue+"</th>", "<th "+props+" >"+newThValue+"</th>")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user