mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-04-13 05:31:28 -07:00
317
back/pialert.py
317
back/pialert.py
@@ -69,7 +69,7 @@ piholeDhcpleases = '/etc/pihole/dhcp.leases'
|
|||||||
debug_force_notification = False
|
debug_force_notification = False
|
||||||
|
|
||||||
userSubnets = []
|
userSubnets = []
|
||||||
changedPorts = []
|
changedPorts_json_struc = None
|
||||||
time_started = datetime.datetime.now()
|
time_started = datetime.datetime.now()
|
||||||
cron_instance = Cron()
|
cron_instance = Cron()
|
||||||
log_timestamp = time_started
|
log_timestamp = time_started
|
||||||
@@ -275,7 +275,7 @@ def importConfig ():
|
|||||||
# Webhooks
|
# Webhooks
|
||||||
global REPORT_WEBHOOK, WEBHOOK_URL, WEBHOOK_PAYLOAD, WEBHOOK_REQUEST_METHOD
|
global REPORT_WEBHOOK, WEBHOOK_URL, WEBHOOK_PAYLOAD, WEBHOOK_REQUEST_METHOD
|
||||||
# Apprise
|
# Apprise
|
||||||
global REPORT_APPRISE, APPRISE_HOST, APPRISE_URL
|
global REPORT_APPRISE, APPRISE_HOST, APPRISE_URL, APPRISE_PAYLOAD
|
||||||
# NTFY
|
# NTFY
|
||||||
global REPORT_NTFY, NTFY_HOST, NTFY_TOPIC, NTFY_USER, NTFY_PASSWORD
|
global REPORT_NTFY, NTFY_HOST, NTFY_TOPIC, NTFY_USER, NTFY_PASSWORD
|
||||||
# PUSHSAFER
|
# PUSHSAFER
|
||||||
@@ -343,6 +343,7 @@ def importConfig ():
|
|||||||
REPORT_APPRISE = ccd('REPORT_APPRISE', False , c_d, 'Enable Apprise', 'boolean', '', 'Apprise', ['test'])
|
REPORT_APPRISE = ccd('REPORT_APPRISE', False , c_d, 'Enable Apprise', 'boolean', '', 'Apprise', ['test'])
|
||||||
APPRISE_HOST = ccd('APPRISE_HOST', '' , c_d, 'Apprise host URL', 'text', '', 'Apprise')
|
APPRISE_HOST = ccd('APPRISE_HOST', '' , c_d, 'Apprise host URL', 'text', '', 'Apprise')
|
||||||
APPRISE_URL = ccd('APPRISE_URL', '' , c_d, 'Apprise notification URL', 'text', '', 'Apprise')
|
APPRISE_URL = ccd('APPRISE_URL', '' , c_d, 'Apprise notification URL', 'text', '', 'Apprise')
|
||||||
|
APPRISE_PAYLOAD = ccd('APPRISE_PAYLOAD', 'html' , c_d, 'Payload type', 'selecttext', "['html', 'text']", 'Apprise')
|
||||||
|
|
||||||
# NTFY
|
# NTFY
|
||||||
REPORT_NTFY = ccd('REPORT_NTFY', False , c_d, 'Enable NTFY', 'boolean', '', 'NTFY', ['test'])
|
REPORT_NTFY = ccd('REPORT_NTFY', False , c_d, 'Enable NTFY', 'boolean', '', 'NTFY', ['test'])
|
||||||
@@ -452,7 +453,7 @@ last_internet_IP_scan = now_minus_24h
|
|||||||
last_API_update = now_minus_24h
|
last_API_update = now_minus_24h
|
||||||
last_run = now_minus_24h
|
last_run = now_minus_24h
|
||||||
last_cleanup = now_minus_24h
|
last_cleanup = now_minus_24h
|
||||||
last_update_vendors = time_started - datetime.timedelta(days = 6) # update vendors 24h after first run and than once a week
|
last_update_vendors = time_started - datetime.timedelta(days = 6) # update vendors 24h after first run and then once a week
|
||||||
|
|
||||||
# indicates, if a new version is available
|
# indicates, if a new version is available
|
||||||
newVersionAvailable = False
|
newVersionAvailable = False
|
||||||
@@ -1625,7 +1626,9 @@ def update_devices_names ():
|
|||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
def performNmapScan(devicesToScan):
|
def performNmapScan(devicesToScan):
|
||||||
|
|
||||||
global changedPorts
|
global changedPorts_json_struc
|
||||||
|
|
||||||
|
changedPortsTmp = []
|
||||||
|
|
||||||
if len(devicesToScan) > 0:
|
if len(devicesToScan) > 0:
|
||||||
|
|
||||||
@@ -1736,40 +1739,38 @@ def performNmapScan(devicesToScan):
|
|||||||
|
|
||||||
foundEntry = oldEntry
|
foundEntry = oldEntry
|
||||||
|
|
||||||
|
columnNames = ["Name", "MAC", "Port", "State", "Service", "Extra", "NewOrOld" ]
|
||||||
if foundEntry is not None:
|
if foundEntry is not None:
|
||||||
changedPorts.append(
|
changedPortsTmp.append({
|
||||||
{
|
"Name" : foundEntry.name,
|
||||||
'new' : {
|
"MAC" : newEntry.mac,
|
||||||
"Name" : foundEntry.name,
|
"Port" : newEntry.port,
|
||||||
"MAC" : newEntry.mac,
|
"State" : newEntry.state,
|
||||||
"Port" : newEntry.port,
|
"Service" : newEntry.service,
|
||||||
"State" : newEntry.state,
|
"Extra" : foundEntry.extra,
|
||||||
"Service": newEntry.service,
|
"NewOrOld" : "New values"
|
||||||
"Extra" : foundEntry.extra
|
})
|
||||||
},
|
changedPortsTmp.append({
|
||||||
'old' : {
|
"Name" : foundEntry.name,
|
||||||
"Name" : foundEntry.name,
|
"MAC" : foundEntry.mac,
|
||||||
"MAC" : foundEntry.mac,
|
"Port" : foundEntry.port,
|
||||||
"Port" : foundEntry.port,
|
"State" : foundEntry.state,
|
||||||
"State" : foundEntry.state,
|
"Service" : foundEntry.service,
|
||||||
"Service": foundEntry.service,
|
"Extra" : foundEntry.extra,
|
||||||
"Extra" : foundEntry.extra
|
"NewOrOld" : "Old values"
|
||||||
}
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
changedPorts.append(
|
changedPortsTmp.append({
|
||||||
{
|
"Name" : "New device",
|
||||||
'new' : {
|
"MAC" : newEntry.mac,
|
||||||
"Name" : "New device",
|
"Port" : newEntry.port,
|
||||||
"MAC" : newEntry.mac,
|
"State" : newEntry.state,
|
||||||
"Port" : newEntry.port,
|
"Service" : newEntry.service,
|
||||||
"State" : newEntry.state,
|
"Extra" : "",
|
||||||
"Service": newEntry.service,
|
"NewOrOld" : "New device"
|
||||||
"Extra" : ""
|
})
|
||||||
}
|
|
||||||
}
|
changedPorts_json_struc = json_struc({ "data" : changedPortsTmp}, columnNames)
|
||||||
)
|
|
||||||
|
|
||||||
# Delete old entries if available
|
# Delete old entries if available
|
||||||
if len(indexesToDelete) > 0:
|
if len(indexesToDelete) > 0:
|
||||||
@@ -2135,14 +2136,9 @@ def skip_repeated_notifications ():
|
|||||||
json_final = []
|
json_final = []
|
||||||
|
|
||||||
def send_notifications ():
|
def send_notifications ():
|
||||||
global mail_text, mail_html, json_final, changedPorts
|
global mail_text, mail_html, json_final, changedPorts_json_struc, partial_html, partial_txt, partial_json
|
||||||
|
|
||||||
deviceUrl = REPORT_DASHBOARD_URL + '/deviceDetails.php?mac='
|
deviceUrl = REPORT_DASHBOARD_URL + '/deviceDetails.php?mac='
|
||||||
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:blue; font-size: 12px;' bgcolor='#909090' "
|
|
||||||
thProps = "width='120px' style='color:#F0F0F0' bgcolor='#909090' "
|
|
||||||
|
|
||||||
build_direction = "TOP_TO_BOTTOM"
|
|
||||||
|
|
||||||
# Reporting section
|
# Reporting section
|
||||||
file_print(' Check if something to report')
|
file_print(' Check if something to report')
|
||||||
@@ -2154,7 +2150,6 @@ def send_notifications ():
|
|||||||
json_events = []
|
json_events = []
|
||||||
json_ports = []
|
json_ports = []
|
||||||
|
|
||||||
|
|
||||||
# Disable reporting on events for devices where reporting is disabled based on the MAC address
|
# Disable reporting on events for devices where reporting is disabled based on the MAC address
|
||||||
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
|
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
|
||||||
WHERE eve_PendingAlertEmail = 1 AND eve_EventType != 'Device Down' AND eve_MAC IN
|
WHERE eve_PendingAlertEmail = 1 AND eve_EventType != 'Device Down' AND eve_MAC IN
|
||||||
@@ -2190,160 +2185,74 @@ def send_notifications ():
|
|||||||
|
|
||||||
if 'internet' in INCLUDED_SECTIONS:
|
if 'internet' in INCLUDED_SECTIONS:
|
||||||
# Compose Internet Section
|
# Compose Internet Section
|
||||||
text = ""
|
sqlQuery = """SELECT eve_MAC as MAC, eve_IP as IP, eve_DateTime as Datetime, eve_EventType as "Event Type", eve_AdditionalInfo as "More info" FROM Events
|
||||||
|
|
||||||
json_string = get_table_as_json("""SELECT eve_MAC as MAC, eve_IP as IP, eve_DateTime as Datetime, eve_EventType as "Event Type", eve_AdditionalInfo as "Additional info" FROM Events
|
|
||||||
WHERE eve_PendingAlertEmail = 1 AND eve_MAC = 'Internet'
|
WHERE eve_PendingAlertEmail = 1 AND eve_MAC = 'Internet'
|
||||||
ORDER BY eve_DateTime""")
|
ORDER BY eve_DateTime"""
|
||||||
|
|
||||||
if json_string["data"] == []:
|
notiStruc = construct_notifications(sqlQuery, "Internet IP change")
|
||||||
html = ""
|
|
||||||
else:
|
|
||||||
html = convert(json_string, build_direction=build_direction, table_attributes=table_attributes)
|
|
||||||
|
|
||||||
html = format_table(html, "data", headerProps, "Internet IP change")
|
|
||||||
|
|
||||||
headers = ["MAC", "Datetime", "IP", "Event Type", "Additional info"]
|
|
||||||
|
|
||||||
# prepare text-only message
|
|
||||||
text_line = '{}\t{}\n'
|
|
||||||
|
|
||||||
for device in json_string["data"]:
|
|
||||||
for header in headers:
|
|
||||||
text += text_line.format ( header + ': ', device[header])
|
|
||||||
|
|
||||||
# Format HTML table headers
|
|
||||||
for header in headers:
|
|
||||||
html = format_table(html, header, thProps)
|
|
||||||
|
|
||||||
mail_text = mail_text.replace ('<SECTION_INTERNET>', text + '\n')
|
|
||||||
mail_html = mail_html.replace ('<INTERNET_TABLE>', html)
|
|
||||||
|
|
||||||
# collect "internet" (IP changes) for the webhook json
|
# collect "internet" (IP changes) for the webhook json
|
||||||
json_internet = json_string["data"]
|
json_internet = notiStruc.json["data"]
|
||||||
|
|
||||||
|
mail_text = mail_text.replace ('<SECTION_INTERNET>', notiStruc.text + '\n')
|
||||||
|
mail_html = mail_html.replace ('<INTERNET_TABLE>', notiStruc.html)
|
||||||
|
|
||||||
if 'new_devices' in INCLUDED_SECTIONS:
|
if 'new_devices' in INCLUDED_SECTIONS:
|
||||||
# Compose New Devices Section
|
# Compose New Devices Section
|
||||||
text = ""
|
sqlQuery = """SELECT eve_MAC as MAC, eve_DateTime as Datetime, dev_LastIP as IP, eve_EventType as "Event Type", dev_Name as "Device name", dev_Comments as Comments FROM Events_Devices
|
||||||
|
|
||||||
json_string = get_table_as_json("""SELECT eve_MAC as MAC, eve_DateTime as Datetime, dev_LastIP as IP, eve_EventType as "Event Type", dev_Name as "Device name", dev_Comments as Comments FROM Events_Devices
|
|
||||||
WHERE eve_PendingAlertEmail = 1
|
WHERE eve_PendingAlertEmail = 1
|
||||||
AND eve_EventType = 'New Device'
|
AND eve_EventType = 'New Device'
|
||||||
ORDER BY eve_DateTime""")
|
ORDER BY eve_DateTime"""
|
||||||
if json_string["data"] == []:
|
|
||||||
html = ""
|
|
||||||
else:
|
|
||||||
html = convert(json_string, build_direction=build_direction, table_attributes=table_attributes)
|
|
||||||
|
|
||||||
html = format_table(html, "data", headerProps, "New devices")
|
notiStruc = construct_notifications(sqlQuery, "New devices")
|
||||||
|
|
||||||
headers = ["MAC", "Datetime", "IP", "Event Type", "Device name", "Comments"]
|
|
||||||
|
|
||||||
# prepare text-only message
|
|
||||||
text_line = '{}\t{}\n'
|
|
||||||
text = ""
|
|
||||||
for device in json_string["data"]:
|
|
||||||
for header in headers:
|
|
||||||
text += text_line.format ( header + ': ', device[header])
|
|
||||||
|
|
||||||
# Format HTML table headers
|
|
||||||
for header in headers:
|
|
||||||
html = format_table(html, header, thProps)
|
|
||||||
|
|
||||||
mail_text = mail_text.replace ('<SECTION_NEW_DEVICES>', text + '\n')
|
|
||||||
mail_html = mail_html.replace ('<NEW_DEVICES_TABLE>', html)
|
|
||||||
|
|
||||||
# collect "new_devices" for the webhook json
|
# collect "new_devices" for the webhook json
|
||||||
json_new_devices = json_string["data"]
|
json_new_devices = notiStruc.json["data"]
|
||||||
|
|
||||||
|
mail_text = mail_text.replace ('<SECTION_NEW_DEVICES>', notiStruc.text + '\n')
|
||||||
|
mail_html = mail_html.replace ('<NEW_DEVICES_TABLE>', notiStruc.html)
|
||||||
|
|
||||||
if 'down_devices' in INCLUDED_SECTIONS:
|
if 'down_devices' in INCLUDED_SECTIONS:
|
||||||
# Compose Devices Down Section
|
# Compose Devices Down Section
|
||||||
text = ""
|
sqlQuery = """SELECT eve_MAC as MAC, eve_DateTime as Datetime, dev_LastIP as IP, eve_EventType as "Event Type", dev_Name as "Device name", dev_Comments as Comments FROM Events_Devices
|
||||||
|
|
||||||
json_string = get_table_as_json("""SELECT eve_MAC as MAC, eve_DateTime as Datetime, dev_LastIP as IP, eve_EventType as "Event Type", dev_Name as "Device name", dev_Comments as Comments FROM Events_Devices
|
|
||||||
WHERE eve_PendingAlertEmail = 1
|
WHERE eve_PendingAlertEmail = 1
|
||||||
AND eve_EventType = 'Device Down'
|
AND eve_EventType = 'Device Down'
|
||||||
ORDER BY eve_DateTime""")
|
ORDER BY eve_DateTime"""
|
||||||
if json_string["data"] == []:
|
|
||||||
html = ""
|
|
||||||
else:
|
|
||||||
html = convert(json_string, build_direction=build_direction, table_attributes=table_attributes)
|
|
||||||
|
|
||||||
html = format_table(html, "data", headerProps, "Down devices")
|
notiStruc = construct_notifications(sqlQuery, "Down devices")
|
||||||
|
|
||||||
headers = ["MAC", "Datetime", "IP", "Event Type", "Device name", "Comments"]
|
# collect "new_devices" for the webhook json
|
||||||
|
json_down_devices = notiStruc.json["data"]
|
||||||
|
|
||||||
# prepare text-only message
|
mail_text = mail_text.replace ('<SECTION_DEVICES_DOWN>', notiStruc.text + '\n')
|
||||||
text_line = '{}\t{}\n'
|
mail_html = mail_html.replace ('<DOWN_DEVICES_TABLE>', notiStruc.html)
|
||||||
text = ""
|
|
||||||
for device in json_string["data"]:
|
|
||||||
for header in headers:
|
|
||||||
text += text_line.format ( header + ': ', device[header])
|
|
||||||
|
|
||||||
# Format HTML table headers
|
|
||||||
for header in headers:
|
|
||||||
html = format_table(html, header, thProps)
|
|
||||||
|
|
||||||
mail_text = mail_text.replace ('<SECTION_DEVICES_DOWN>', text + '\n')
|
|
||||||
mail_html = mail_html.replace ('<DOWN_DEVICES_TABLE>', html)
|
|
||||||
|
|
||||||
# collect "down_devices" for the webhook json
|
|
||||||
json_down_devices = json_string["data"]
|
|
||||||
|
|
||||||
if 'events' in INCLUDED_SECTIONS:
|
if 'events' in INCLUDED_SECTIONS:
|
||||||
# Compose Events Section
|
# Compose Events Section
|
||||||
text = ""
|
sqlQuery = """SELECT eve_MAC as MAC, eve_DateTime as Datetime, dev_LastIP as IP, eve_EventType as "Event Type", dev_Name as "Device name", dev_Comments as Comments FROM Events_Devices
|
||||||
|
|
||||||
json_string = get_table_as_json("""SELECT eve_MAC as MAC, eve_DateTime as Datetime, dev_LastIP as IP, eve_EventType as "Event Type", dev_Name as "Device name", dev_Comments as Comments FROM Events_Devices
|
|
||||||
WHERE eve_PendingAlertEmail = 1
|
WHERE eve_PendingAlertEmail = 1
|
||||||
AND eve_EventType IN ('Connected','Disconnected',
|
AND eve_EventType IN ('Connected','Disconnected',
|
||||||
'IP Changed')
|
'IP Changed')
|
||||||
ORDER BY eve_DateTime""")
|
ORDER BY eve_DateTime"""
|
||||||
if json_string["data"] == []:
|
|
||||||
html = ""
|
|
||||||
else:
|
|
||||||
html = convert(json_string, build_direction=build_direction, table_attributes=table_attributes)
|
|
||||||
|
|
||||||
html = format_table(html, "data", headerProps, "Events")
|
notiStruc = construct_notifications(sqlQuery, "Events")
|
||||||
|
|
||||||
headers = ["MAC", "Datetime", "IP", "Event Type", "Device name", "Comments"]
|
|
||||||
|
|
||||||
# prepare text-only message
|
|
||||||
text_line = '{}\t{}\n'
|
|
||||||
text = ""
|
|
||||||
for device in json_string["data"]:
|
|
||||||
for header in headers:
|
|
||||||
text += text_line.format ( header + ': ', device[header])
|
|
||||||
|
|
||||||
# Format HTML table headers
|
|
||||||
for header in headers:
|
|
||||||
html = format_table(html, header, thProps)
|
|
||||||
|
|
||||||
mail_text = mail_text.replace ('<SECTION_EVENTS>', text + '\n')
|
|
||||||
mail_html = mail_html.replace ('<EVENTS_TABLE>', html)
|
|
||||||
|
|
||||||
# collect "events" for the webhook json
|
# collect "events" for the webhook json
|
||||||
json_events = json_string["data"]
|
json_events = notiStruc.json["data"]
|
||||||
|
|
||||||
|
mail_text = mail_text.replace ('<SECTION_EVENTS>', notiStruc.text + '\n')
|
||||||
|
mail_html = mail_html.replace ('<EVENTS_TABLE>', notiStruc.html)
|
||||||
|
|
||||||
if 'ports' in INCLUDED_SECTIONS:
|
if 'ports' in INCLUDED_SECTIONS:
|
||||||
json_ports = changedPorts
|
# collect "ports" for the webhook json
|
||||||
|
if changedPorts_json_struc is not None:
|
||||||
|
json_ports = changedPorts_json_struc.json["data"]
|
||||||
|
|
||||||
json_string = { "data" : changedPorts }
|
notiStruc = construct_notifications("", "Ports", True, changedPorts_json_struc)
|
||||||
|
|
||||||
if json_string["data"] == []:
|
mail_html = mail_html.replace ('<PORTS_TABLE>', notiStruc.html)
|
||||||
html = ""
|
# mail_text = mail_text.replace ('<PORTS_TABLE>', notiStruc.text + '\n')
|
||||||
else:
|
mail_text = mail_text.replace ('<PORTS_TABLE>', "Ports changed! Check PiAlert for details!" + '\n')
|
||||||
html = convert(json_string, build_direction=build_direction, table_attributes=table_attributes)
|
|
||||||
|
|
||||||
html = format_table(html, "data", headerProps, "Changed or new ports")
|
|
||||||
|
|
||||||
headers = ["Name", "MAC", "Port", "State", "Service", "Extra"]
|
|
||||||
|
|
||||||
for header in headers:
|
|
||||||
html = format_table(html, header, thProps)
|
|
||||||
|
|
||||||
mail_html = mail_html.replace ('<PORTS_TABLE>', html)
|
|
||||||
|
|
||||||
json_final = {
|
json_final = {
|
||||||
"internet": json_internet,
|
"internet": json_internet,
|
||||||
@@ -2376,7 +2285,7 @@ def send_notifications ():
|
|||||||
if REPORT_APPRISE and check_config('apprise'):
|
if REPORT_APPRISE and check_config('apprise'):
|
||||||
updateState("Send: Apprise")
|
updateState("Send: Apprise")
|
||||||
file_print(' Sending report by Apprise')
|
file_print(' Sending report by Apprise')
|
||||||
send_apprise (mail_html)
|
send_apprise (mail_html, mail_text)
|
||||||
else :
|
else :
|
||||||
file_print(' Skip Apprise')
|
file_print(' Skip Apprise')
|
||||||
if REPORT_WEBHOOK and check_config('webhook'):
|
if REPORT_WEBHOOK and check_config('webhook'):
|
||||||
@@ -2415,7 +2324,7 @@ def send_notifications ():
|
|||||||
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
|
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
|
||||||
WHERE eve_PendingAlertEmail = 1""")
|
WHERE eve_PendingAlertEmail = 1""")
|
||||||
|
|
||||||
changedPorts = []
|
changedPorts = None
|
||||||
|
|
||||||
# DEBUG - print number of rows updated
|
# DEBUG - print number of rows updated
|
||||||
file_print(' Notifications: ', sql.rowcount)
|
file_print(' Notifications: ', sql.rowcount)
|
||||||
@@ -2423,6 +2332,59 @@ def send_notifications ():
|
|||||||
# Commit changes
|
# Commit changes
|
||||||
commitDB()
|
commitDB()
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
def construct_notifications(sqlQuery, tableTitle, skipText = False, suppliedJsonStruct = None):
|
||||||
|
|
||||||
|
if suppliedJsonStruct is None and sqlQuery == "":
|
||||||
|
return noti_struc("", "", "")
|
||||||
|
|
||||||
|
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:blue; font-size: 16px;' bgcolor='#909090' "
|
||||||
|
thProps = "width='120px' style='color:#F0F0F0' bgcolor='#909090' "
|
||||||
|
|
||||||
|
build_direction = "TOP_TO_BOTTOM"
|
||||||
|
text_line = '{}\t{}\n'
|
||||||
|
|
||||||
|
if suppliedJsonStruct is None:
|
||||||
|
json_struc = get_table_as_json(sqlQuery)
|
||||||
|
else:
|
||||||
|
json_struc = suppliedJsonStruct
|
||||||
|
|
||||||
|
json = json_struc.json
|
||||||
|
html = ""
|
||||||
|
text = ""
|
||||||
|
|
||||||
|
if json["data"] != []:
|
||||||
|
|
||||||
|
html = convert(json, build_direction=build_direction, table_attributes=table_attributes)
|
||||||
|
|
||||||
|
html = format_table(html, "data", headerProps, tableTitle)
|
||||||
|
|
||||||
|
headers = json_struc.columnNames
|
||||||
|
|
||||||
|
# prepare text-only message
|
||||||
|
if skipText == False:
|
||||||
|
for device in json["data"]:
|
||||||
|
for header in headers:
|
||||||
|
padding = ""
|
||||||
|
if len(header) < 4:
|
||||||
|
padding = "\t"
|
||||||
|
text += text_line.format ( header + ': ' + padding, device[header])
|
||||||
|
text += '\n'
|
||||||
|
|
||||||
|
# Format HTML table headers
|
||||||
|
for header in headers:
|
||||||
|
html = format_table(html, header, thProps)
|
||||||
|
|
||||||
|
return noti_struc(json, text, html)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
class noti_struc:
|
||||||
|
def __init__(self, json, text, html):
|
||||||
|
self.json = json
|
||||||
|
self.text = text
|
||||||
|
self.html = html
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
def check_config(service):
|
def check_config(service):
|
||||||
|
|
||||||
@@ -2680,13 +2642,18 @@ def send_webhook (_json, _html):
|
|||||||
file_print(e.output)
|
file_print(e.output)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
def send_apprise (html):
|
def send_apprise (html, text):
|
||||||
#Define Apprise compatible payload (https://github.com/caronc/apprise-api#stateless-solution)
|
#Define Apprise compatible payload (https://github.com/caronc/apprise-api#stateless-solution)
|
||||||
|
payload = html
|
||||||
|
|
||||||
|
if APPRISE_PAYLOAD == 'text':
|
||||||
|
payload = text
|
||||||
|
|
||||||
_json_payload={
|
_json_payload={
|
||||||
"urls": APPRISE_URL,
|
"urls": APPRISE_URL,
|
||||||
"title": "Pi.Alert Notifications",
|
"title": "Pi.Alert Notifications",
|
||||||
"format": "html",
|
"format": APPRISE_PAYLOAD,
|
||||||
"body": html
|
"body": payload
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -3139,7 +3106,7 @@ def update_api(isNotification = False):
|
|||||||
# Save selected database tables
|
# Save selected database tables
|
||||||
for dsSQL in dataSourcesSQLs:
|
for dsSQL in dataSourcesSQLs:
|
||||||
|
|
||||||
json_string = get_table_as_json(dsSQL[1])
|
json_string = get_table_as_json(dsSQL[1]).json
|
||||||
|
|
||||||
write_file(folder + 'table_' + dsSQL[0] + '.json' , json.dumps(json_string))
|
write_file(folder + 'table_' + dsSQL[0] + '.json' , json.dumps(json_string))
|
||||||
|
|
||||||
@@ -3158,7 +3125,13 @@ def get_table_as_json(sqlQuery):
|
|||||||
tmp = fill_row(columnNames, row)
|
tmp = fill_row(columnNames, row)
|
||||||
|
|
||||||
result["data"].append(tmp)
|
result["data"].append(tmp)
|
||||||
return result
|
return json_struc(result, columnNames)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
class json_struc:
|
||||||
|
def __init__(self, json, columnNames):
|
||||||
|
self.json = json
|
||||||
|
self.columnNames = columnNames
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
def fill_row(names, row):
|
def fill_row(names, row):
|
||||||
@@ -3380,7 +3353,7 @@ def handle_test(testType):
|
|||||||
if testType == 'REPORT_WEBHOOK':
|
if testType == 'REPORT_WEBHOOK':
|
||||||
send_webhook (sample_json_payload, sample_txt)
|
send_webhook (sample_json_payload, sample_txt)
|
||||||
if testType == 'REPORT_APPRISE':
|
if testType == 'REPORT_APPRISE':
|
||||||
send_apprise (sample_html)
|
send_apprise (sample_html, sample_txt)
|
||||||
if testType == 'REPORT_NTFY':
|
if testType == 'REPORT_NTFY':
|
||||||
send_ntfy (sample_txt)
|
send_ntfy (sample_txt)
|
||||||
if testType == 'REPORT_PUSHSAFER':
|
if testType == 'REPORT_PUSHSAFER':
|
||||||
@@ -3461,8 +3434,6 @@ class serviceSchedule:
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# print("Hello my name is " + self.scheduleObject)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# BEGIN
|
# BEGIN
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
|
|||||||
@@ -32,74 +32,16 @@
|
|||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td bgcolor=#F5F5F5 height=200 valign=top style="padding: 10px">
|
<td bgcolor=#F5F5F5 height=200 valign=top style="padding: 10px">
|
||||||
<SECTION_INTERNET>
|
|
||||||
<p style="font-size: 24px; font-weight: bold; color:#C04040"> Internet: </p>
|
|
||||||
|
|
||||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070">
|
<INTERNET_TABLE>
|
||||||
<tr bgcolor=#909090 style="color:#f0f0f0">
|
|
||||||
<th width=140> Event Type </th>
|
|
||||||
<th width=130> Datetime </th>
|
|
||||||
<th width=100> IP </th>
|
|
||||||
<th> Additional Info </th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<TABLE_INTERNET>
|
<NEW_DEVICES_TABLE>
|
||||||
</table>
|
|
||||||
|
|
||||||
<br>
|
<DOWN_DEVICES_TABLE>
|
||||||
</SECTION_INTERNET>
|
|
||||||
|
|
||||||
<SECTION_NEW_DEVICES>
|
<EVENTS_TABLE>
|
||||||
<p style="font-size: 14px; font-weight: bold; color:#C04040"> New Devices: </p>
|
|
||||||
|
|
||||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070">
|
<PORTS_TABLE>
|
||||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
|
||||||
<th width=150> MAC </th>
|
|
||||||
<th width=130> Datetime </th>
|
|
||||||
<th width=100> IP </th>
|
|
||||||
<th width=140> Device Name </th>
|
|
||||||
<th> Vendor </th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<TABLE_NEW_DEVICES>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
</SECTION_NEW_DEVICES>
|
|
||||||
|
|
||||||
<SECTION_DEVICES_DOWN>
|
|
||||||
<p style="font-size: 14px; font-weight: bold; color:#C04040"> Devices Down: </p>
|
|
||||||
|
|
||||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070">
|
|
||||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
|
||||||
<th width=140> MAC </th>
|
|
||||||
<th width=130> Datetime </th>
|
|
||||||
<th width=100> IP </th>
|
|
||||||
<th> Device Name </th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<TABLE_DEVICES_DOWN>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
</SECTION_DEVICES_DOWN>
|
|
||||||
|
|
||||||
<SECTION_EVENTS>
|
|
||||||
<p style="font-size: 14px; font-weight: bold; color:#409040"> Events: </p>
|
|
||||||
|
|
||||||
<table width=100% border=1 bordercolor=#C0C0C0 cellpadding=3px cellspacing=0 style="border-collapse: collapse; font-size: 12px; color:#707070">
|
|
||||||
<tr bgcolor=#909090 style="color:#F0F0F0">
|
|
||||||
<th width=140> MAC </th>
|
|
||||||
<th width=130> Datetime </th>
|
|
||||||
<th width=100> IP </th>
|
|
||||||
<th width=100> Event Type </th>
|
|
||||||
<th width=140> Device Name </th>
|
|
||||||
<th> Additional Info </th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<TABLE_EVENTS>
|
|
||||||
</table>
|
|
||||||
</SECTION_EVENTS>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|||||||
@@ -13,3 +13,6 @@ Events
|
|||||||
Internet
|
Internet
|
||||||
----------------------
|
----------------------
|
||||||
<SECTION_INTERNET>
|
<SECTION_INTERNET>
|
||||||
|
Ports
|
||||||
|
----------------------
|
||||||
|
<PORTS_TABLE>
|
||||||
|
|||||||
@@ -13,9 +13,7 @@ services:
|
|||||||
# (optional) useful for debugging if you have issues setting up the container
|
# (optional) useful for debugging if you have issues setting up the container
|
||||||
- ${LOGS_LOCATION}:/home/pi/pialert/front/log
|
- ${LOGS_LOCATION}:/home/pi/pialert/front/log
|
||||||
# DELETE START anyone trying to use this file: comment out / delete BELOW lines, they are only for development purposes
|
# DELETE START anyone trying to use this file: comment out / delete BELOW lines, they are only for development purposes
|
||||||
- ${DEV_LOCATION}/back/pialert.py:/home/pi/pialert/back/pialert.py
|
- ${DEV_LOCATION}/back:/home/pi/pialert/back
|
||||||
- ${DEV_LOCATION}/back/update_vendors.sh:/home/pi/pialert/back/update_vendors.sh
|
|
||||||
- ${DEV_LOCATION}/back/report_template_new_version.html:/home/pi/pialert/back/report_template_new_version.html
|
|
||||||
- ${DEV_LOCATION}/pholus:/home/pi/pialert/pholus
|
- ${DEV_LOCATION}/pholus:/home/pi/pialert/pholus
|
||||||
- ${DEV_LOCATION}/dockerfiles:/home/pi/pialert/dockerfiles
|
- ${DEV_LOCATION}/dockerfiles:/home/pi/pialert/dockerfiles
|
||||||
- ${APP_DATA_LOCATION}/pialert/php.ini:/etc/php/7.4/fpm/php.ini
|
- ${APP_DATA_LOCATION}/pialert/php.ini:/etc/php/7.4/fpm/php.ini
|
||||||
|
|||||||
0
front/php/server/init.php
Normal file → Executable file
0
front/php/server/init.php
Normal file → Executable file
@@ -175,7 +175,7 @@ $lang['en_us'] = array(
|
|||||||
'DevDetail_MainInfo_Owner' => 'Owner',
|
'DevDetail_MainInfo_Owner' => 'Owner',
|
||||||
'DevDetail_MainInfo_Type' => 'Type',
|
'DevDetail_MainInfo_Type' => 'Type',
|
||||||
'DevDetail_Icon' => 'Icon',
|
'DevDetail_Icon' => 'Icon',
|
||||||
'DevDetail_Icon_Descr' => 'Enter a font awesome icon name without the fa- prefix.',
|
'DevDetail_Icon_Descr' => 'Enter a font awesome icon name without the fa- prefix or with complete class, e.g.: fa fa-brands fa-apple.',
|
||||||
'DevDetail_MainInfo_Vendor' => 'Vendor',
|
'DevDetail_MainInfo_Vendor' => 'Vendor',
|
||||||
'DevDetail_MainInfo_Favorite' => 'Favorite',
|
'DevDetail_MainInfo_Favorite' => 'Favorite',
|
||||||
'DevDetail_MainInfo_Group' => 'Group',
|
'DevDetail_MainInfo_Group' => 'Group',
|
||||||
@@ -513,8 +513,8 @@ the arp-scan will take hours to complete instead of seconds.
|
|||||||
'REPORT_DASHBOARD_URL_description' => 'This URL is used as the base for generating links in the emails. Enter full URL starting with <code>http://</code> including the port number (no trailig slash <code>/</code>).',
|
'REPORT_DASHBOARD_URL_description' => 'This URL is used as the base for generating links in the emails. Enter full URL starting with <code>http://</code> including the port number (no trailig slash <code>/</code>).',
|
||||||
'DIG_GET_IP_ARG_name' => 'Internet IP discovery',
|
'DIG_GET_IP_ARG_name' => 'Internet IP discovery',
|
||||||
'DIG_GET_IP_ARG_description' => 'Change the <a href="https://linux.die.net/man/1/dig" target="_blank">dig utility</a> arguments if you have issues resolving your Internet IP. Arguments are added at the end of the following command: <code>dig +short </code>.',
|
'DIG_GET_IP_ARG_description' => 'Change the <a href="https://linux.die.net/man/1/dig" target="_blank">dig utility</a> arguments if you have issues resolving your Internet IP. Arguments are added at the end of the following command: <code>dig +short </code>.',
|
||||||
'UI_LANG_name' => 'Select Language',
|
'UI_LANG_name' => 'UI Language',
|
||||||
'UI_LANG_description' => '',
|
'UI_LANG_description' => 'Select the preferred UI language.',
|
||||||
|
|
||||||
//Email
|
//Email
|
||||||
'Email_settings_group' => '<i class="fa fa-at"></i> Email',
|
'Email_settings_group' => '<i class="fa fa-at"></i> Email',
|
||||||
@@ -557,7 +557,7 @@ the arp-scan will take hours to complete instead of seconds.
|
|||||||
'APPRISE_HOST_name' => 'Apprise host URL',
|
'APPRISE_HOST_name' => 'Apprise host URL',
|
||||||
'APPRISE_HOST_description' => 'Apprise host URL starting with <code>http://</code> or <code>https://</code>. (don\'t forget to include <code>/notify</code> at the end)',
|
'APPRISE_HOST_description' => 'Apprise host URL starting with <code>http://</code> or <code>https://</code>. (don\'t forget to include <code>/notify</code> at the end)',
|
||||||
'APPRISE_URL_name' => 'Apprise notification URL',
|
'APPRISE_URL_name' => 'Apprise notification URL',
|
||||||
'APPRISE_URL_description' => 'Apprise notification target URL.',
|
'APPRISE_URL_description' => 'Apprise notification target URL. For example for Telegram it would be <code>tgram://{bot_token}/{chat_id}</code>.',
|
||||||
|
|
||||||
// NTFY
|
// NTFY
|
||||||
'NTFY_settings_group' => '<i class="fa fa-terminal"></i> NTFY',
|
'NTFY_settings_group' => '<i class="fa fa-terminal"></i> NTFY',
|
||||||
@@ -578,6 +578,8 @@ the arp-scan will take hours to complete instead of seconds.
|
|||||||
'REPORT_PUSHSAFER_description' => 'Enable sending notifications via <a target="_blank" href="https://www.pushsafer.com/">Pushsafer</a>.',
|
'REPORT_PUSHSAFER_description' => 'Enable sending notifications via <a target="_blank" href="https://www.pushsafer.com/">Pushsafer</a>.',
|
||||||
'PUSHSAFER_TOKEN_name' => 'Pushsafer token',
|
'PUSHSAFER_TOKEN_name' => 'Pushsafer token',
|
||||||
'PUSHSAFER_TOKEN_description' => 'Your secret Pushsafer API key (token).',
|
'PUSHSAFER_TOKEN_description' => 'Your secret Pushsafer API key (token).',
|
||||||
|
'APPRISE_PAYLOAD_name' => 'Payload type',
|
||||||
|
'APPRISE_PAYLOAD_description' => 'Select the payoad type sent to Apprise. For example <code>html</code> works well with emails, <code>text</code> with chat apps, such as Telegram.',
|
||||||
|
|
||||||
|
|
||||||
// MQTT
|
// MQTT
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
|||||||
<script>
|
<script>
|
||||||
|
|
||||||
// number of settings has to be equal to
|
// number of settings has to be equal to
|
||||||
var settingsNumber = 67;
|
var settingsNumber = 68;
|
||||||
|
|
||||||
// Wrong number of settings processing
|
// Wrong number of settings processing
|
||||||
if(<?php echo count($settings)?> != settingsNumber)
|
if(<?php echo count($settings)?> != settingsNumber)
|
||||||
|
|||||||
Reference in New Issue
Block a user