Compare commits

..

18 Commits

Author SHA1 Message Date
Jokob-sk
ecc4920b04 New screenshots 2023-01-22 16:35:33 +11:00
Jokob-sk
1f3e28fe83 Fix new version template + Firewall type 2023-01-22 12:47:38 +11:00
Jokob-sk
a9132d7b46 Network tree 0.3 2023-01-22 12:02:06 +11:00
Jokob-sk
f54929c6cb Network tree 0.2 2023-01-22 11:59:35 +11:00
Jokob-sk
1a181d08b9 Network tree 0.1 2023-01-22 11:45:08 +11:00
Jokob-sk
94b32f0f73 Devices Columns 0.4 - backup 2023-01-21 12:45:25 +11:00
Jokob-sk
ab98382984 Devices Columns 0.3 2023-01-20 23:44:33 +11:00
Jokob-sk
5498035ca9 Devices Columns 0.2 2023-01-18 23:06:06 +11:00
Jokob-sk
a1444659ea Devices Columns 0.1 2023-01-17 23:42:00 +11:00
Jokob-sk
b9d65ea0e2 Refactor Toggle Dark mode 0.2 2023-01-17 19:17:23 +11:00
Jokob-sk
aac35294b5 PHP error fix 2023-01-17 00:03:50 +11:00
Jokob-sk
fef33d652d Refactor Toggle Dark mode 2023-01-16 23:56:19 +11:00
Jokob-sk
8ef6f420e4 Device Icons 0.3 2023-01-16 21:18:35 +11:00
Jokob-sk
7675ebc7d3 Device Icons 0.2 2023-01-15 21:34:10 +11:00
Jokob-sk
90e4b36106 Attempt at CI/CD warning fix 0.1 2023-01-15 18:44:25 +11:00
Jokob-sk
e7ac2321f2 Device Icons 0.1 2023-01-15 17:27:23 +11:00
Jokob-sk
e0d8ade2d0 Show name instead of MAC in drp 2023-01-15 16:23:14 +11:00
Jokob-sk
f5546b6a49 Network page improvements 2023-01-15 14:23:32 +11:00
46 changed files with 1720 additions and 425 deletions

0
.github/ISSUE_TEMPLATE/feature_request.md vendored Normal file → Executable file
View File

0
.github/ISSUE_TEMPLATE/i-have-an-issue.md vendored Normal file → Executable file
View File

View File

@@ -31,7 +31,7 @@ jobs:
- name: Docker meta
id: meta
uses: docker/metadata-action@v3
uses: docker/metadata-action@v4
with:
# list of Docker images to use as base name for tags
images: |

2
.github/workflows/docker_prod.yml vendored Normal file → Executable file
View File

@@ -32,7 +32,7 @@ jobs:
- name: Docker meta
id: meta
uses: docker/metadata-action@v3
uses: docker/metadata-action@v4
with:
# list of Docker images to use as base name for tags
images: |

0
CONTRIBUTING Normal file → Executable file
View File

0
FUNDING.yml Normal file → Executable file
View File

View File

@@ -9,13 +9,13 @@ Scans for devices connected to your WIFI / LAN and alerts you if new and unknown
# 🐳 Docker image
[![Docker](https://img.shields.io/github/actions/workflow/status/jokob-sk/Pi.Alert/docker_prod.yml?branch=main&label=Build&logo=GitHub)](https://github.com/jokob-sk/Pi.Alert/actions/workflows/docker_prod.yml)
[![Docker](https://img.shields.io/github/actions/workflow/status/jokob-sk/Pi.Alert/docker_prod.yml?label=Build&logo=GitHub)](https://github.com/jokob-sk/Pi.Alert/actions/workflows/docker_prod.yml)
[![GitHub Committed](https://img.shields.io/github/last-commit/jokob-sk/Pi.Alert?color=40ba12&label=Committed&logo=GitHub&logoColor=fff)](https://github.com/jokob-sk/Pi.Alert)
[![Docker Size](https://img.shields.io/docker/image-size/jokobsk/pi.alert?label=Size&logo=Docker&color=0aa8d2&logoColor=fff)](https://hub.docker.com/r/jokobsk/pi.alert)
[![Docker Pulls](https://img.shields.io/docker/pulls/jokobsk/pi.alert?label=Pulls&logo=docker&color=0aa8d2&logoColor=fff)](https://hub.docker.com/r/jokobsk/pi.alert)
[![Docker Pushed](https://img.shields.io/badge/dynamic/json?color=0aa8d2&logoColor=fff&label=Pushed&query=last_updated&url=https%3A%2F%2Fhub.docker.com%2Fv2%2Frepositories%2Fjokobsk%2Fpi.alert%2F&logo=docker&link=http://left&link=https://hub.docker.com/repository/docker/jokobsk/pi.alert)](https://hub.docker.com/r/jokobsk/pi.alert)
🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/pi.alert) | 📄 [Dockerfile](https://github.com/jokob-sk/Pi.Alert/blob/main/Dockerfile) | 📚 [Docker instructions](https://github.com/jokob-sk/Pi.Alert/blob/main//dockerfiles/README.md) | 🆕 [Release notes](https://github.com/jokob-sk/Pi.Alert/issues/138)
🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/pi.alert) | 📄 [Dockerfile](https://github.com/jokob-sk/Pi.Alert/blob/main/Dockerfile) | 📚 [Docker instructions](https://github.com/jokob-sk/Pi.Alert/blob/main//dockerfiles/README.md) | 🆕 [Release notes](https://github.com/jokob-sk/Pi.Alert/releases)
## 🔍 Scan Methods
The system continuously scans the network for, **New devices**, **New connections** (re-connections), **Disconnections**, **"Always Connected" devices down**, Devices **IP changes** and **Internet IP address changes**. Scanning methods are:

View File

@@ -20,6 +20,7 @@ from email.mime.text import MIMEText
import sys
import subprocess
import os
import tempfile
import re
import time
import decimal
@@ -112,6 +113,8 @@ def print_log (pText):
# Save current time to calculate elapsed time until next log
log_timestamp = log_timestamp2
return pText
#-------------------------------------------------------------------------------
# check RW access of DB and config file
@@ -255,7 +258,7 @@ def importConfig ():
# General
global ENABLE_ARPSCAN, SCAN_SUBNETS, PRINT_LOG, TIMEZONE, PIALERT_WEB_PROTECTION, PIALERT_WEB_PASSWORD, INCLUDED_SECTIONS, SCAN_CYCLE_MINUTES, DAYS_TO_KEEP_EVENTS, REPORT_DASHBOARD_URL, DIG_GET_IP_ARG
# Email
global REPORT_MAIL, SMTP_SERVER, SMTP_PORT, REPORT_TO, REPORT_FROM, SMTP_SKIP_LOGIN, SMTP_USER, SMTP_PASS, SMTP_SKIP_TLS
global REPORT_MAIL, SMTP_SERVER, SMTP_PORT, REPORT_TO, REPORT_FROM, SMTP_SKIP_LOGIN, SMTP_USER, SMTP_PASS, SMTP_SKIP_TLS, SMTP_FORCE_SSL
# Webhooks
global REPORT_WEBHOOK, WEBHOOK_URL, WEBHOOK_PAYLOAD, WEBHOOK_REQUEST_METHOD
# Apprise
@@ -312,6 +315,7 @@ def importConfig ():
SMTP_USER = ccd('SMTP_USER', '' , c_d, 'SMTP user', 'text', '', 'Email')
SMTP_PASS = ccd('SMTP_PASS', '' , c_d, 'SMTP password', 'password', '', 'Email')
SMTP_SKIP_TLS = ccd('SMTP_SKIP_TLS', False , c_d, 'SMTP skip TLS', 'boolean', '', 'Email')
SMTP_FORCE_SSL = ccd('SMTP_FORCE_SSL', False , c_d, 'Force SSL', 'boolean', '', 'Email')
# Webhooks
REPORT_WEBHOOK = ccd('REPORT_WEBHOOK', False , c_d, 'Enable Webhooks', 'boolean', '', 'Webhooks', ['test'])
@@ -2383,21 +2387,58 @@ def send_email (pText, pHTML):
msg.attach (MIMEText (pText, 'plain'))
msg.attach (MIMEText (pHTML, 'html'))
# Send mail
smtp_connection = smtplib.SMTP (SMTP_SERVER, SMTP_PORT)
smtp_connection.ehlo()
failedAt = ''
try:
if not SMTP_SKIP_TLS:
failedAt = print_log ('SMTP try')
try:
# Send mail
failedAt = print_log('Trying to open connection to ' + str(SMTP_SERVER) + ':' + str(SMTP_PORT))
if SMTP_FORCE_SSL:
failedAt = print_log('SMTP_FORCE_SSL == True so using .SMTP_SSL()')
if SMTP_PORT == 0:
failedAt = print_log('SMTP_PORT == 0 so sending .SMTP_SSL(SMTP_SERVER)')
smtp_connection = smtplib.SMTP_SSL(SMTP_SERVER)
else:
failedAt = print_log('SMTP_PORT == 0 so sending .SMTP_SSL(SMTP_SERVER, SMTP_PORT)')
smtp_connection = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT)
else:
failedAt = print_log('SMTP_FORCE_SSL == False so using .SMTP()')
if SMTP_PORT == 0:
failedAt = print_log('SMTP_PORT == 0 so sending .SMTP(SMTP_SERVER)')
smtp_connection = smtplib.SMTP (SMTP_SERVER)
else:
failedAt = print_log('SMTP_PORT == 0 so sending .SMTP(SMTP_SERVER, SMTP_PORT)')
smtp_connection = smtplib.SMTP (SMTP_SERVER, SMTP_PORT)
failedAt = print_log('Setting SMTP debug level')
smtp_connection.set_debuglevel(1)
failedAt = print_log( 'Sending .ehlo()')
smtp_connection.ehlo()
if not SMTP_SKIP_TLS:
failedAt = print_log('SMTP_SKIP_TLS == False so sending .starttls()')
smtp_connection.starttls()
failedAt = print_log('SMTP_SKIP_TLS == False so sending .ehlo()')
smtp_connection.ehlo()
if not SMTP_SKIP_LOGIN:
failedAt = print_log('SMTP_SKIP_LOGIN == False so sending .login()')
smtp_connection.login (SMTP_USER, SMTP_PASS)
smtp_connection.sendmail (REPORT_FROM, REPORT_TO, msg.as_string())
smtp_connection.quit()
failedAt = print_log('Sending .sendmail()')
smtp_connection.sendmail (REPORT_FROM, REPORT_TO, msg.as_string())
smtp_connection.quit()
except smtplib.SMTPAuthenticationError as e:
file_print(' ERROR: Couldn\'t connect to the SMTP server, skipping Email')
file_print(' ERROR: Failed at - ', failedAt)
file_print(' ERROR: Couldn\'t connect to the SMTP server (SMTPAuthenticationError), skipping Email (enable PRINT_LOG for more logging)')
except smtplib.SMTPServerDisconnected as e:
file_print(' ERROR: Failed at - ', failedAt)
file_print(' ERROR: Couldn\'t connect to the SMTP server (SMTPServerDisconnected), skipping Email (enable PRINT_LOG for more logging)')
file_print(' DEBUG: Last executed - ', failedAt)
#-------------------------------------------------------------------------------
@@ -2730,35 +2771,16 @@ def upgradeDB ():
ALTER TABLE "Devices" ADD "dev_Network_Node_port" INTEGER
""")
# Re-creating Parameters table
file_print("[upgradeDB] Re-creating Parameters table")
sql.execute("DROP TABLE Parameters;")
# dev_Icon column
dev_Icon_missing = sql.execute ("""
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Icon'
""").fetchone()[0] == 0
sql.execute("""
CREATE TABLE "Parameters" (
"par_ID" TEXT,
"par_Value" TEXT
);
""")
params = [
# General
('Front_Events_Period', '1 day'),
('Front_Details_Sessions_Rows', '50'),
('Front_Details_Events_Rows', '50'),
('Front_Details_Events_Hide', 'True'),
('Front_Events_Rows', '50'),
('Front_Details_Period', '1 day'),
('Front_Devices_Order', '[[3,"desc"],[0,"asc"]]'),
('Front_Devices_Rows', '100'),
('Front_Details_Tab', 'tabDetails'),
('Back_Settings_Imported', round(time.time() * 1000)),
('Back_App_State', 'Initializing'),
('Back_New_Version_Available', False),
('Front_Event', 'finished')
]
sql.executemany ("""INSERT INTO Parameters ("par_ID", "par_Value") VALUES (?, ?)""", params)
if dev_Icon_missing :
file_print("[upgradeDB] Adding dev_Icon to the Devices table")
sql.execute("""
ALTER TABLE "Devices" ADD "dev_Icon" TEXT
""")
# indicates, if Settings table is available
settingsMissing = sql.execute("""
@@ -3073,17 +3095,20 @@ def isNewVersion():
buildTimestamp = int(f.read().strip())
f.close()
url = requests.get("https://api.github.com/repos/jokob-sk/Pi.Alert/releases")
text = url.text
data = json.loads(text)
try:
url = requests.get("https://api.github.com/repos/jokob-sk/Pi.Alert/releases")
text = url.text
data = json.loads(text)
except requests.exceptions.ConnectionError as e:
file_print(" Couldn't check for new release.")
data = ""
# make sure we received a valid response and not an API rate limit exceeded message
if len(data) > 0 and "published_at" in data[0]:
dateTimeStr = data[0]["published_at"]
realeaseTimestamp = int(datetime.datetime.strptime(dateTimeStr, '%Y-%m-%dT%H:%M:%SZ').strftime('%s'))
dateTimeStr = data[0]["published_at"]
realeaseTimestamp = int(datetime.datetime.strptime(dateTimeStr, '%Y-%m-%dT%H:%M:%SZ').strftime('%s'))
if realeaseTimestamp > buildTimestamp + 600:
file_print(" New version of the container available!")

0
back/report_sample_1.txt Normal file → Executable file
View File

View File

@@ -21,9 +21,9 @@
</td>
</tr>
<tr>
<a style="color:#ffffff" href="https://github.com/jokob-sk/Pi.Alert/releases">
<td bgcolor=#2656f1 width=100% align=center style="padding: 20px 10px 10px 10px; font-size: 20px; font-weight: bold; color:#ffffff; border-top-right-radius: 5px; border-top-left-radius: 5px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">🆕 New version available 🆕</td>
</a>
<td bgcolor=#2656f1 width=100% align=center style="padding: 20px 10px 10px 10px; font-size: 20px; font-weight: bold; color:#ffffff; border-top-right-radius: 5px; border-top-left-radius: 5px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2)">
<a style="color:#ffffff;cursor:pointer;" href="https://github.com/jokob-sk/Pi.Alert/releases">🆕 New version available 🆕</a>
</td>
</tr>
<tr>
<td>

View File

@@ -13,10 +13,11 @@ services:
# (optional) map an empty file with the name 'setting_darkmode' if you want to force the dark mode on container rebuilt
- ${APP_DATA_LOCATION}/pialert/db/setting_darkmode:/home/pi/pialert/db/setting_darkmode
# (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
- ${DEV_LOCATION}/back/pialert.py:/home/pi/pialert/back/pialert.py
- ${DEV_LOCATION}/back/pialert.py:/home/pi/pialert/back/pialert.py
- ${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}/dockerfiles:/home/pi/pialert/dockerfiles
- ${APP_DATA_LOCATION}/pialert/php.ini:/etc/php/7.4/fpm/php.ini

View File

@@ -1,4 +1,4 @@
[![Docker](https://img.shields.io/github/actions/workflow/status/jokob-sk/Pi.Alert/docker_prod.yml?branch=main&label=Build&logo=GitHub)](https://github.com/jokob-sk/Pi.Alert/actions/workflows/docker_prod.yml)
[![Docker](https://img.shields.io/github/actions/workflow/status/jokob-sk/Pi.Alert/docker_prod.yml?label=Build&logo=GitHub)](https://github.com/jokob-sk/Pi.Alert/actions/workflows/docker_prod.yml)
[![GitHub Committed](https://img.shields.io/github/last-commit/jokob-sk/Pi.Alert?color=40ba12&label=Committed&logo=GitHub&logoColor=fff)](https://github.com/jokob-sk/Pi.Alert)
[![Docker Size](https://img.shields.io/docker/image-size/jokobsk/pi.alert?label=Size&logo=Docker&color=0aa8d2&logoColor=fff)](https://hub.docker.com/r/jokobsk/pi.alert)
[![Docker Pulls](https://img.shields.io/docker/pulls/jokobsk/pi.alert?label=Pulls&logo=docker&color=0aa8d2&logoColor=fff)](https://hub.docker.com/r/jokobsk/pi.alert)
@@ -6,7 +6,7 @@
# 🐳 A docker image for Pi.Alert
🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/pi.alert) | 📄 [Dockerfile](https://github.com/jokob-sk/Pi.Alert/blob/main/Dockerfile) | 📚 [Docker instructions](https://github.com/jokob-sk/Pi.Alert/blob/main//dockerfiles/README.md) | 🆕 [Release notes](https://github.com/jokob-sk/Pi.Alert/issues/138)
🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/pi.alert) | 📄 [Dockerfile](https://github.com/jokob-sk/Pi.Alert/blob/main/Dockerfile) | 📚 [Docker instructions](https://github.com/jokob-sk/Pi.Alert/blob/main//dockerfiles/README.md) | 🆕 [Release notes](https://github.com/jokob-sk/Pi.Alert/releases)
<a href="https://raw.githubusercontent.com/jokob-sk/Pi.Alert/main/docs/img/devices_split.png" target="_blank">
<img src="https://raw.githubusercontent.com/jokob-sk/Pi.Alert/main/docs/img/devices_split.png" width="300px" />

0
docs/WEBHOOK_N8N.md Normal file → Executable file
View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 141 KiB

0
docs/img/size_h_1250_w_1000.txt Normal file → Executable file
View File

View File

@@ -691,6 +691,9 @@ height: 50px;
margin: 10px;
}
#settingsPage .panel-heading:hover{
background-color: #272c30;
}
.settings-expand-icon {
font-size: medium;
@@ -723,4 +726,72 @@ height: 50px;
.pointer
{
cursor:pointer;
}
}
.db_info_table_row .select2-container--default .select2-selection--multiple .select2-selection__choice
{
background-color:#258744;
}
.db_info_table_row .select2-container--default .select2-selection--multiple
{
background-color:#606060;
}
.select2-container .select2-dropdown
{
background-color:#606060;
}
#networkTree .box
{
padding:2px;
margin:2px;
}
#networkTree .netNodeText
{
top: 2px;
margin: 2px;
position: absolute;
}
#networkTree
{
margin-left: 16px;
/* border: solid;
border-color:#606060; */
position: relative;
font-size: 0.75em;
}
#networkTree .netIcon
{
width: 25px;;
float:left;
display:inline;
}
#networkTree .netCollapse
{
display: block;
position: absolute;
margin-left: 156px;
top: -3px;
font-size: large;
left: -15px;
}
#networkTree .highlightedNode
{
border: solid;
border-color:cyan;
}
#networkTree .netStatus-Off-line i
{
color: #dd4b39;
}
.spanNetworkTree {
display: inline-block;
width: 120px;
white-space: nowrap;
overflow: hidden !important;
text-overflow: ellipsis;
}

View File

@@ -151,7 +151,7 @@
<div class="col-sm-9">
<div class="input-group">
<input class="form-control" id="txtName" type="text" value="--">
<span class="input-group-addon"><i class="fa fa-pencil drp-edit" onclick="editDrp('txtName');"></i></span>
<span class="input-group-addon"><i class="fa fa-pencil pointer" onclick="editDrp('txtName');"></i></span>
</div>
</div>
</div>
@@ -162,7 +162,7 @@
<div class="col-sm-9">
<div class="input-group">
<input class="form-control" id="txtOwner" type="text" value="--">
<span class="input-group-addon"><i class="fa fa-pencil drp-edit" onclick="editDrp('txtOwner');"></i></span>
<span class="input-group-addon"><i class="fa fa-pencil pointer" onclick="editDrp('txtOwner');"></i></span>
<div class="input-group-btn">
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="fa fa-caret-down "></span></button>
@@ -179,7 +179,7 @@
<div class="col-sm-9">
<div class="input-group">
<input class="form-control" id="txtDeviceType" type="text" value="--">
<span class="input-group-addon"><i class="fa fa-pencil drp-edit" onclick="editDrp('txtDeviceType');"></i></span>
<span class="input-group-addon"><i class="fa fa-pencil pointer" onclick="editDrp('txtDeviceType');"></i></span>
<div class="input-group-btn">
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-expanded="false" >
<span class="fa fa-caret-down"></span></button>
@@ -191,6 +191,28 @@
</div>
</div>
<!-- Icon -->
<div class="form-group">
<label class="col-sm-3 control-label">
<?php echo lang('DevDetail_Icon');?>
<a href="https://fontawesome.com/search?q=laptop&o=r&m=free" target="_blank"> <span><i class="fa fa-fw fa-arrow-up-right-from-square"></i></a><span>
</label>
<div class="col-sm-9">
<div class="input-group">
<input class="form-control" title="<?php echo lang('DevDetail_Icon_Descr');?>" id="txtIcon" type="text" value="--">
<span class="input-group-addon" title='<?php echo lang('DevDetail_button_OverwriteIcons_Tooltip');?>'><i class="fa fa-copy pointer" onclick="askOverwriteIconType();"></i></span>
<span class="input-group-addon"><i class="fa fa-pencil pointer" onclick="editDrp('txtIcon');"></i></span>
<div class="input-group-btn">
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="fa fa-caret-down"></span>
</button>
<ul id="dropdownIcon" class="dropdown-menu dropdown-menu-right">
</ul>
</div>
</div>
</div>
</div>
<!-- Vendor -->
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Vendor');?></label>
@@ -213,7 +235,7 @@
<div class="col-sm-9">
<div class="input-group">
<input class="form-control" id="txtGroup" type="text" value="--">
<span class="input-group-addon"><i class="fa fa-pencil drp-edit" onclick="editDrp('txtGroup');"></i></span>
<span class="input-group-addon"><i class="fa fa-pencil pointer" onclick="editDrp('txtGroup');"></i></span>
<div class="input-group-btn">
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="fa fa-caret-down"></span>
@@ -231,7 +253,7 @@
<div class="col-sm-9">
<div class="input-group">
<input class="form-control" id="txtLocation" type="text" value="--">
<span class="input-group-addon"><i class="fa fa-pencil drp-edit" onclick="editDrp('txtLocation');"></i></span>
<span class="input-group-addon"><i class="fa fa-pencil pointer" onclick="editDrp('txtLocation');"></i></span>
<div class="input-group-btn">
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="fa fa-caret-down"></span></button>
@@ -250,31 +272,7 @@
<textarea class="form-control" rows="3" id="txtComments"></textarea>
</div>
</div>
<!-- Network -->
<h4 class="bottom-border-aqua"><?php echo lang('DevDetail_MainInfo_Network_Title');?></h4>
<div class="form-group">
<label class="col-sm-6 control-label"><?php echo lang('DevDetail_MainInfo_Network');?></label>
<div class="col-sm-6">
<div class="input-group">
<input class="form-control" id="txtNetworkNodeMac" type="text" value="--">
<div class="input-group-btn">
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-expanded="false" id="buttonNetworkNodeMac">
<span class="fa fa-caret-down"></span></button>
<ul id="dropdownNetworkNodeMac" class="dropdown-menu dropdown-menu-right">
</ul>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-6 control-label"><?php echo lang('DevDetail_MainInfo_Network_Port');?></label>
<div class="col-sm-6">
<input class="form-control" id="txtNetworkPort" type="text" value="--">
</div>
</div>
</div>
@@ -324,6 +322,32 @@
<input class="checkbox blue hidden" id="chkStaticIP" type="checkbox">
</div>
</div>
<!-- Network -->
<h4 class="bottom-border-aqua"><?php echo lang('DevDetail_MainInfo_Network_Title');?></h4>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Network');?></label>
<div class="col-sm-9">
<div class="input-group">
<input class="form-control" id="txtNetworkNodeMac" type="text" value="--">
<span class="input-group-addon"><i title="<?php echo lang('DevDetail_GoToNetworkNode');?>" class="fa fa-square-up-right pointer" onclick="goToNetworkNode('txtNetworkNodeMac');"></i></span>
<div class="input-group-btn">
<button type="button" class="btn btn-info dropdown-toggle" data-mynodemac="" data-toggle="dropdown" aria-expanded="false" id="buttonNetworkNodeMac">
<span class="fa fa-caret-down"></span></button>
<ul id="dropdownNetworkNodeMac" class="dropdown-menu dropdown-menu-right">
</ul>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"><?php echo lang('DevDetail_MainInfo_Network_Port');?></label>
<div class="col-sm-9">
<input class="form-control" id="txtNetworkPort" type="text" value="--">
</div>
</div>
</div>
</div>
@@ -547,7 +571,7 @@
<th>Port</th>
<th>State</th>
<th>Service</th>
<th>Extra</th>
<th>Extra (Notes)</th>
</tr>
</thead>
<!-- Comment out tbody when trying to implement better table with datatables here -->
@@ -677,8 +701,9 @@ if ($ENABLED_DARKMODE === True) {
?>
<!-- page script ----------------------------------------------------------- -->
<script>
<script defer>
// ------------------------------------------------------------
function getMac(){
params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
@@ -687,8 +712,38 @@ if ($ENABLED_DARKMODE === True) {
return params.mac
}
// ------------------------------------------------------------
function getDevicesListValue(idColumn, idValue, returnColumn)
{
if(emptyArr.includes(devicesList) || emptyArr.includes(idValue))
{
return '';
}
return devicesList.find((item) => {return item[idColumn] == idValue})[returnColumn]
}
// ------------------------------------------------------------
function getDevicesList()
{
// Read cache
devicesList = getCache('devicesList');
if (devicesList != '') {
devicesList = JSON.parse (devicesList);
} else {
devicesList = [];
}
return devicesList;
}
// ------------------------------------------------------------
mac = getMac() // can also be rowID!! not only mac
var devicesList = []; // this will contain a list the database row IDs of the devices ordered by the position displayed in the UI
devicesList = getDevicesList();
var pos = -1;
var parPeriod = 'Front_Details_Period';
var parTab = 'Front_Details_Tab';
@@ -729,7 +784,7 @@ function main () {
tab = selectedTab;
// get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ parPeriod, function(data) {
$.get('php/server/parameters.php?action=get&defaultValue=1 day&parameter='+ parPeriod, function(data) {
var result = JSON.parse(data);
if (result) {
period = result;
@@ -737,21 +792,21 @@ function main () {
}
// get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ parSessionsRows, function(data) {
$.get('php/server/parameters.php?action=get&defaultValue=50&parameter='+ parSessionsRows, function(data) {
var result = JSON.parse(data);
if (Number.isInteger (result) ) {
sessionsRows = result;
}
// get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ parEventsRows, function(data) {
$.get('php/server/parameters.php?action=get&defaultValue=50&parameter='+ parEventsRows, function(data) {
var result = JSON.parse(data);
if (Number.isInteger (result) ) {
eventsRows = result;
}
// get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ parEventsHide, function(data) {
$.get('php/server/parameters.php?action=get&defaultValue=true&parameter='+ parEventsHide, function(data) {
var result = JSON.parse(data);
if (result) {
eventsHide = result;
@@ -763,16 +818,7 @@ function main () {
initializeiCheck();
initializeCombos();
initializeDatatables();
initializeCalendar();
// Read Cookies
devicesList = getCache('devicesList');
if (devicesList != '') {
devicesList = JSON.parse (devicesList);
} else {
devicesList = [];
}
initializeCalendar();
// query data
getDeviceData(true);
@@ -851,11 +897,12 @@ function initializeiCheck () {
// -----------------------------------------------------------------------------
function initializeCombos () {
// Initialize combos with queries
initializeCombo ( '#dropdownOwner', 'getOwners', 'txtOwner', true);
initializeCombo ( '#dropdownDeviceType', 'getDeviceTypes', 'txtDeviceType', true);
initializeCombo ( '#dropdownGroup', 'getGroups', 'txtGroup', true);
initializeCombo ( '#dropdownLocation', 'getLocations', 'txtLocation', true);
initializeCombo ( '#dropdownNetworkNodeMac', 'getNetworkNodes', 'txtNetworkNodeMac', false);
initializeCombo ( '#dropdownOwner', 'getOwners', 'txtOwner', true);
initializeCombo ( '#dropdownDeviceType', 'getDeviceTypes', 'txtDeviceType', true);
initializeCombo ( '#dropdownGroup', 'getGroups', 'txtGroup', true);
initializeCombo ( '#dropdownLocation', 'getLocations', 'txtLocation', true);
initializeCombo ( '#dropdownNetworkNodeMac', 'getNetworkNodes', 'txtNetworkNodeMac', false);
initializeCombo ( '#dropdownIcon', 'getIcons', 'txtIcon', false);
// Initialize static combos
initializeComboSkipRepeated ();
@@ -903,13 +950,21 @@ function initializeCombo (dropdownId, queryAction, txtDataField, useCache) {
}
}
// -----------------------------------------------------------------------------
// Edit dropdown value
function editDrp(dropdownId)
{
$('#'+dropdownId).focus();
}
// -----------------------------------------------------------------------------
// Go to the correct network node in the Network section
function goToNetworkNode(dropdownId)
{
setCache('activeNetworkTab', $('#'+dropdownId).attr('data-mynodemac').replaceAll(":","_")+'_id');
window.location.href = './network.php';
}
// -----------------------------------------------------------------------------
// write out the HTML for the dropdown
function writeDropdownHtml(dropdownId, dropdownHtmlContent)
@@ -923,23 +978,7 @@ function writeDropdownHtml(dropdownId, dropdownHtmlContent)
HTMLelement.innerHTML += dropdownHtmlContent;
}
// -----------------------------------------------------------------------------
// function getCache(key)
// {
// // check cache
// if(sessionStorage.getItem(key))
// {
// return sessionStorage.getItem(key);
// } else
// {
// return "";
// }
// }
// // -----------------------------------------------------------------------------
// function setCache(key, data)
// {
// sessionStorage.setItem(key, data);
// }
// -----------------------------------------------------------------------------
function initializeComboSkipRepeated () {
// find dropdown menu element
@@ -1191,7 +1230,7 @@ function getDeviceData (readAllData=false) {
// Check MAC
if (mac == '') {
console.log("getDeviceData mac AA: ", mac)
// console.log("getDeviceData mac AA: ", mac)
return;
}
@@ -1225,6 +1264,7 @@ function getDeviceData (readAllData=false) {
$('#txtOwner').val ('--');
$('#txtDeviceType').val ('--');
$('#txtVendor').val ('--');
$('#txtIcon').val ('--');
$('#chkFavorite').iCheck ('uncheck');
$('#txtGroup').val ('--');
@@ -1252,7 +1292,7 @@ function getDeviceData (readAllData=false) {
// Deactivate controls
$('#panDetails :input').attr('disabled', true);
// Check if device is deleted o no exists in this session
// Check if device is deleted or don't exist in this session
if (pos == -1) {
devicesList = [];
$('#pageTitle').html ('Device not found: <small>'+ mac +'</small>');
@@ -1300,7 +1340,7 @@ function getDeviceData (readAllData=false) {
// Activate controls
$('#panDetails :input').attr('disabled', false);
mac =deviceData['dev_MAC'];
mac = deviceData['dev_MAC'];
// update the mac parameter in the URL, this makes the selected device persistent when the page is reloaded
var searchParams = new URLSearchParams(window.location.search);
@@ -1308,18 +1348,22 @@ function getDeviceData (readAllData=false) {
var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString();
history.pushState(null, '', newRelativePathQuery);
getSessionsPresenceEvents();
devicesList = getDevicesList();
$('#txtMAC').val (deviceData['dev_MAC']);
$('#txtName').val (deviceData['dev_Name']);
$('#txtOwner').val (deviceData['dev_Owner']);
$('#txtDeviceType').val (deviceData['dev_DeviceType']);
$('#txtVendor').val (deviceData['dev_Vendor']);
$('#txtIcon').val (initDefault(deviceData['dev_Icon'], 'laptop'));
if (deviceData['dev_Favorite'] == 1) {$('#chkFavorite').iCheck('check');} else {$('#chkFavorite').iCheck('uncheck');}
$('#txtGroup').val (deviceData['dev_Group']);
$('#txtLocation').val (deviceData['dev_Location']);
$('#txtComments').val (deviceData['dev_Comments']);
$('#txtNetworkNodeMac').val (deviceData['dev_Network_Node_MAC_ADDR']);
$('#txtComments').val (deviceData['dev_Comments']);
$('#txtNetworkNodeMac').val (getDevicesListValue('mac', deviceData['dev_Network_Node_MAC_ADDR'] ,'name'));
$('#txtNetworkNodeMac').attr ('data-mynodemac', deviceData['dev_Network_Node_MAC_ADDR']);
$('#txtNetworkPort').val (deviceData['dev_Network_Node_port']);
$('#txtFirstConnection').val (deviceData['dev_FirstConnection']);
@@ -1344,7 +1388,7 @@ function getDeviceData (readAllData=false) {
// Check if device is part of the devicesList
pos = devicesList.findIndex(item => item.rowid == deviceData['rowid']);
if (pos == -1) {
devicesList.push({"rowid" : deviceData['rowid'], "mac" : deviceData['dev_MAC']});
devicesList.push({"rowid" : deviceData['rowid'], "mac" : deviceData['dev_MAC'], "name": deviceData['dev_Name'], "type": deviceData['dev_DeviceType']});
pos=0;
}
}
@@ -1413,8 +1457,6 @@ function performSwitch(direction)
}
}
// console.log('here ' + pos)
// get new mac from the devicesList. Don't change to the commented out line below, the mac query string in the URL isn't updated yet!
// mac = params.mac;
mac = devicesList[pos].mac.toString();
@@ -1425,6 +1467,15 @@ function performSwitch(direction)
reloadTab()
}
// -----------------------------------------------------------------------------
function initDefault (value, defaultVal) {
if (emptyArr.includes(value))
{
return defaultVal;
}
return value;
}
// -----------------------------------------------------------------------------
function setDeviceData (direction='', refreshCallback='') {
// Check MAC
@@ -1438,11 +1489,12 @@ function setDeviceData (direction='', refreshCallback='') {
+ '&owner=' + $('#txtOwner').val()
+ '&type=' + $('#txtDeviceType').val()
+ '&vendor=' + $('#txtVendor').val()
+ '&icon=' + $('#txtIcon').val()
+ '&favorite=' + ($('#chkFavorite')[0].checked * 1)
+ '&group=' + $('#txtGroup').val()
+ '&location=' + $('#txtLocation').val()
+ '&comments=' + $('#txtComments').val()
+ '&networknode=' + $('#txtNetworkNodeMac').val()
+ '&networknode=' + $('#txtNetworkNodeMac').attr('data-mynodemac')
+ '&networknodeport=' + $('#txtNetworkPort').val()
+ '&staticIP=' + ($('#chkStaticIP')[0].checked * 1)
+ '&scancycle=' + ($('#txtScanCycle').val() == "yes" ? "1" : "0")
@@ -1502,26 +1554,29 @@ function skipNotifications () {
}
// -----------------------------------------------------------------------------
function askDeleteDeviceEvents () {
// Overwrite all devices of the same type with the currently selected icon
function askOverwriteIconType () {
// Check MAC
if (mac == '') {
return;
}
// Ask delete device Events
showModalWarning ('<?php echo lang('DevDetail_button_DeleteEvents');?>', '<?php echo lang('DevDetail_button_DeleteEvents_Warning');?>',
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Delete');?>', 'deleteDeviceEvents');
// Ask overwrite icon types
showModalWarning ('<?php echo lang('DevDetail_button_OverwriteIcons');?>', '<?php echo lang('DevDetail_button_OverwriteIcons_Warning');?>',
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Okay');?>', 'overwriteIconType');
}
// -----------------------------------------------------------------------------
function deleteDeviceEvents () {
function overwriteIconType () {
// Check MAC
if (mac == '') {
return;
}
var icon = $('#txtIcon').val();
// Delete device events
$.get('php/server/devices.php?action=deleteDeviceEvents&mac='+ mac, function(msg) {
$.get('php/server/devices.php?action=overwriteIconType&mac='+ mac + '&icon=' + icon, function(msg) {
showMessage (msg);
});
@@ -1542,6 +1597,34 @@ function askDeleteDevice () {
}
// -----------------------------------------------------------------------------
function deleteDevice () {
// Check MAC
if (mac == '') {
return;
}
// Delete device
$.get('php/server/devices.php?action=deleteDevice&mac='+ mac, function(msg) {
showMessage (msg);
});
// Deactivate controls
$('#panDetails :input').attr('disabled', true);
}
// -----------------------------------------------------------------------------
function askDeleteDevice () {
// Check MAC
if (mac == '') {
return;
}
// Ask delete device
showModalWarning ('Delete Device', 'Are you sure you want to delete this device?<br>(maybe you prefer to archive it)',
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Delete');?>', 'deleteDevice');
}
// -----------------------------------------------------------------------------
function deleteDevice () {
// Check MAC
@@ -1593,8 +1676,17 @@ $(document).on('input', 'input:text', function() {
});
// -----------------------------------------------------------------------------
// Initialize a text input with the correct value
function setTextValue (textElement, textValue) {
$('#'+textElement).val (textValue);
if(textElement == "txtNetworkNodeMac")
{
$('#'+textElement).attr ('data-mynodemac', textValue);
$('#'+textElement).val (getDevicesListValue('mac', textValue ,'name') );
} else
{
$('#'+textElement).attr ('data-myvalue', textValue);
$('#'+textElement).val (textValue);
}
}
// -----------------------------------------------------------------------------
@@ -1663,7 +1755,7 @@ function loadNmap()
<td>\
<div class="input-group">\
<input class="form-control" id="port_'+item.Index+'" type="text" value="'+item.Extra+'">\
<span class="input-group-addon"><i class="fa fa-save " onclick="saveNmapPort('+item.Index+')"></i></span>\
<span class="input-group-addon"><i class="fa fa-save pointer" onclick="saveNmapPort('+item.Index+')"></i></span>\
</div>\
</td>\
</tr>';

View File

@@ -150,20 +150,8 @@
<div class="box-body table-responsive">
<table id="tableDevices" class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th><?php echo lang('Device_TableHead_Name');?></th>
<th><?php echo lang('Device_TableHead_Owner');?></th>
<th><?php echo lang('Device_TableHead_Type');?></th>
<th><?php echo lang('Device_TableHead_Favorite');?></th>
<th><?php echo lang('Device_TableHead_Group');?></th>
<th><?php echo lang('Device_TableHead_FirstSession');?></th>
<th><?php echo lang('Device_TableHead_LastSession');?></th>
<th><?php echo lang('Device_TableHead_LastIP');?></th>
<th><?php echo lang('Device_TableHead_MAC');?></th>
<th><?php echo lang('Device_TableHead_Status');?></th>
<th><?php echo lang('Device_TableHead_MAC');?></th>
<th><?php echo lang('Device_TableHead_LastIPOrder');?></th>
<th><?php echo lang('Device_TableHead_Rowid');?></th>
<tr>
</tr>
</thead>
</table>
@@ -204,6 +192,9 @@
var parTableOrder = 'Front_Devices_Order';
var tableRows = 10;
var tableOrder = [[3,'desc'], [0,'asc']];
var tableColumnVisible = [0,1,2,3,4,5,6,7,8,9,10,12,13,14];
var columnsStr = '[0,1,2,3,4,5,6,7,8,9,10,12,13,14]';
var tableColumnOrder = [0,1,2,3,4,5,6,7,8,9,10,12,13,14] ;
// Read parameters & Initialize components
main();
@@ -211,43 +202,115 @@
// -----------------------------------------------------------------------------
function main () {
// get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ parTableRows, function(data) {
var result = JSON.parse(data);
result = parseInt(result, 10)
// get visible columns
$.get('php/server/parameters.php?action=get&expireMinutes=525600&defaultValue='+columnsStr+'&parameter=Front_Devices_Columns_Visible', function(data) {
tableColumnVisible = numberArrayFromString(data);
if (Number.isInteger (result) ) {
tableRows = result;
}
// get the custom order specified by the user
$.get('php/server/parameters.php?action=get&expireMinutes=525600&defaultValue='+columnsStr+'&parameter=Front_Devices_Columns_Order', function(data) {
tableColumnOrder = numberArrayFromString(data);
// get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ parTableOrder, function(data) {
var result = JSON.parse(data);
result = JSON.parse(result);
if (Array.isArray (result) ) {
tableOrder = result;
//initialize the table headers in the correct order
var headersDefaultOrder = [ '<?php echo lang('Device_TableHead_Name');?>',
'<?php echo lang('Device_TableHead_Owner');?>',
'<?php echo lang('Device_TableHead_Type');?>',
'<?php echo lang('Device_TableHead_Icon');?>',
'<?php echo lang('Device_TableHead_Favorite');?>',
'<?php echo lang('Device_TableHead_Group');?>',
'<?php echo lang('Device_TableHead_FirstSession');?>',
'<?php echo lang('Device_TableHead_LastSession');?>',
'<?php echo lang('Device_TableHead_LastIP');?>',
'<?php echo lang('Device_TableHead_MAC');?>',
'<?php echo lang('Device_TableHead_Status');?>',
'<?php echo lang('Device_TableHead_MAC_full');?>',
'<?php echo lang('Device_TableHead_LastIPOrder');?>',
'<?php echo lang('Device_TableHead_Rowid');?>',
'<?php echo lang('Device_TableHead_Parent_MAC');?>'
];
html = '';
for(index = 0; index < tableColumnOrder.length; index++)
{
html += '<th>' + headersDefaultOrder[tableColumnOrder[index]] + '</th>';
}
// Initialize components with parameters
initializeDatatable();
$('#tableDevices tr').html(html);
// query data
getDevicesTotals();
getDevicesList (deviceStatus);
});
// get parameter value
$.get('php/server/parameters.php?action=get&defaultValue=50&parameter='+ parTableRows, function(data) {
var result = JSON.parse(data);
result = parseInt(result, 10)
if (Number.isInteger (result) ) {
tableRows = result;
}
// get parameter value
$.get('php/server/parameters.php?action=get&defaultValue=[[3,"desc"],[0,"asc"]]&parameter='+ parTableOrder, function(data) {
var result = JSON.parse(data);
result = JSON.parse(result);
if (Array.isArray (result) ) {
tableOrder = result;
}
// Initialize components with parameters
initializeDatatable();
// query data
getDevicesTotals();
getDevicesList (deviceStatus);
});
});
});
});
}
// -----------------------------------------------------------------------------
var tableColumnHide = [];
function mapIndx(oldIndex)
{
for(i=0;i<tableColumnOrder.length;i++)
{
if(tableColumnOrder[i] == oldIndex)
{
// console.log('newIndex')
// console.log(i)
return i;
}
}
}
// -----------------------------------------------------------------------------
function initializeDatatable () {
for(i = 0; i < tableColumnOrder.length; i++)
{
// hide this column if not in the tableColumnVisible variable
if(tableColumnVisible.includes(tableColumnOrder[i]) == false)
{
tableColumnHide.push(mapIndx(tableColumnOrder[i]));
}
}
// If the device has a small width (mobile) only show name, ip, and status columns.
if (window.screen.width < 400) {
var tableColumnShow = [10,11,12,1,2,3,4,5,6,8];
} else {
var tableColumnShow = [10, 11, 12];
};
if (window.screen.width < 400) {
tableColumnHide = [11,12,13,1,2,4,5,6,7,9];
}
// else {
// // var tableColumnHide = [11, 12, 13];
// tableColumnHide = [11, 12, 13];
// };
var table=
$('#tableDevices').DataTable({
'paging' : true,
@@ -265,20 +328,50 @@ function initializeDatatable () {
// 'order' : [[3,'desc'], [0,'asc']],
'columnDefs' : [
{visible: false, targets: tableColumnShow },
{className: 'text-center', targets: [3, 8, 9] },
{width: '80px', targets: [5, 6] },
{width: '0px', targets: 9 },
{orderData: [11], targets: 7 },
{visible: false, targets: tableColumnHide },
{className: 'text-center', targets: [mapIndx(3), mapIndx(4), mapIndx(9), mapIndx(10)] },
{width: '80px', targets: [mapIndx(6), mapIndx(7)] },
{width: '30px', targets: [mapIndx(10), mapIndx(13)] },
{orderData: [mapIndx(11)], targets: mapIndx(8) },
// Device Name
{targets: [0],
{targets: [mapIndx(0)],
'createdCell': function (td, cellData, rowData, row, col) {
$(td).html ('<b><a href="deviceDetails.php?mac='+ rowData[10] +'" class="">'+ cellData +'</a></b>');
$(td).html ('<b class="anonymizeDev"><a href="deviceDetails.php?mac='+ rowData[mapIndx(11)] +'" class="">'+ cellData +'</a></b>');
} },
// Favorite
{targets: [3],
// Icon
{targets: [mapIndx(3)],
'createdCell': function (td, cellData, rowData, row, col) {
if (!emptyArr.includes(cellData)){
$(td).html ('<i class="fa fa-'+cellData+' " style="font-size:16px"></i>');
} else {
$(td).html ('');
}
} },
// Full MAC
{targets: [mapIndx(11)],
'createdCell': function (td, cellData, rowData, row, col) {
if (!emptyArr.includes(cellData)){
$(td).html ('<span class="anonymizeMac">'+cellData+'</span>');
} else {
$(td).html ('');
}
} },
// IP address
{targets: [mapIndx(12)],
'createdCell': function (td, cellData, rowData, row, col) {
if (!emptyArr.includes(cellData)){
$(td).html ('<span class="anonymizeIp">'+cellData+'</span>');
} else {
$(td).html ('');
}
} },
// Favorite
{targets: [mapIndx(4)],
'createdCell': function (td, cellData, rowData, row, col) {
if (cellData == 1){
$(td).html ('<i class="fa fa-star text-yellow" style="font-size:16px"></i>');
@@ -287,14 +380,14 @@ function initializeDatatable () {
}
} },
// Dates
{targets: [5, 6],
// Dates
{targets: [mapIndx(6), mapIndx(7)],
'createdCell': function (td, cellData, rowData, row, col) {
$(td).html (translateHTMLcodes (cellData));
} },
// Random MAC
{targets: [8],
// Random MAC
{targets: [mapIndx(9)],
'createdCell': function (td, cellData, rowData, row, col) {
if (cellData == 1){
$(td).html ('<i data-toggle="tooltip" data-placement="right" title="Random MAC" style="font-size: 16px;" class="text-yellow glyphicon glyphicon-random"></i>');
@@ -303,8 +396,8 @@ function initializeDatatable () {
}
} },
// Status color
{targets: [9],
// Status color
{targets: [mapIndx(10)],
'createdCell': function (td, cellData, rowData, row, col) {
switch (cellData) {
case 'Down': color='red'; break;
@@ -354,18 +447,27 @@ function initializeDatatable () {
// -----------------------------------------------------------------------------
// Gets a JSON list of rowID and mac from the displayed table in the UI
function getDevicesFromTable(table)
{
rowIDs = table.column(12, { 'search': 'applied' }).data().toArray() // rowID is in hidden column 12
rowMACs = table.column(10, { 'search': 'applied' }).data().toArray() // MAC is in hidden column 10
{
rowIDs = table.column(mapIndx(13), { 'search': 'applied' }).data().toArray() //
rowMACs = table.column(mapIndx(11), { 'search': 'applied' }).data().toArray() //
rowNames = table.column(mapIndx(0), { 'search': 'applied' }).data().toArray() //
rowTypes = table.column(mapIndx(2), { 'search': 'applied' }).data().toArray() //
rowIcons = table.column(mapIndx(3), { 'search': 'applied' }).data().toArray() //
rowParentMAC = table.column(mapIndx(14), { 'search': 'applied' }).data().toArray() //
rowStatus = table.column(mapIndx(10), { 'search': 'applied' }).data().toArray() //
result = []
rowIDs.map(function(rowID, index){
result.push({"rowid": rowID, "mac":rowMACs[index]})
result.push({
"rowid": rowID,
"mac":rowMACs[index],
"name" : rowNames[index],
"type" : rowTypes[index],
"icon" : rowIcons[index],
"parentMac" : rowParentMAC[index],
"status" : rowStatus[index] })
})
// console.log(rowIDs)
// console.log(result)
return JSON.stringify (result)
}
@@ -392,6 +494,10 @@ function getDevicesTotals () {
}
// -----------------------------------------------------------------------------
function getDeviceColumns () {
}
// -----------------------------------------------------------------------------
function getDevicesList (status) {
// Save status selected
@@ -419,3 +525,5 @@ function getDevicesList (status) {
};
</script>
<script src="js/pialert_common.js"></script>

View File

@@ -188,7 +188,7 @@
// -----------------------------------------------------------------------------
function main () {
// get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ parPeriod, function(data) {
$.get('php/server/parameters.php?action=get&defaultValue=1 day&parameter='+ parPeriod, function(data) {
var result = JSON.parse(data);
if (result) {
period = result;
@@ -196,7 +196,7 @@ function main () {
}
// get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ parTableRows, function(data) {
$.get('php/server/parameters.php?action=get&defaultValue=50&parameter='+ parTableRows, function(data) {
var result = JSON.parse(data);
result = parseInt(result, 10)
if (Number.isInteger (result) ) {

View File

@@ -2,7 +2,6 @@
require 'php/templates/language/lang.php';
require 'php/templates/skinUI.php';
require 'php/templates/security.php';
if ($Pia_WebProtection != 'true')

0
front/js/handle_version.js Normal file → Executable file
View File

View File

@@ -206,6 +206,13 @@ function sanitize(data)
return data.replace(/(\r\n|\n|\r)/gm,"").replace(/[^\x00-\x7F]/g, "")
}
// -----------------------------------------------------------------------------
function numberArrayFromString(data)
{
data = JSON.parse(sanitize(data));
return data.replace(/\[|\]/g, '').split(',').map(Number);
}
// -----------------------------------------------------------------------------
function setParameter (parameter, value) {
// Retry
@@ -230,11 +237,11 @@ function setParameter (parameter, value) {
// -----------------------------------------------------------------------------
function saveData(functionName, index, value) {
function saveData(functionName, id, value) {
$.ajax({
method: "GET",
url: "php/server/devices.php",
data: { action: functionName, index: index, value:value },
data: { action: functionName, id: id, value:value },
success: function(data) {
if(sanitize(data) == 'OK')
@@ -253,6 +260,16 @@ function saveData(functionName, index, value) {
}
// -----------------------------------------------------------------------------
// remove an item from an array
function removeItemFromArray(arr, value) {
var index = arr.indexOf(value);
if (index > -1) {
arr.splice(index, 1);
}
return arr;
}
// -----------------------------------------------------------------------------
function sleep(milliseconds) {
const date = Date.now();

375
front/lib/treeviz/index.js Executable file

File diff suppressed because one or more lines are too long

5
front/lib/treeviz/require.js Executable file

File diff suppressed because one or more lines are too long

0
front/log/.gitignore vendored Normal file → Executable file
View File

View File

@@ -246,10 +246,41 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a">
<button type="button" class="btn bg-green dbtools-button" id="btnPiaEnableDarkmode" onclick="askPiaEnableDarkmode()"><?php echo lang('Maintenance_Tool_darkmode');?></button>
<button type="button" class="btn bg-green dbtools-button" id="btnToggleDarkmode" onclick="askToggleDarkmode()"><?php echo lang('Maintenance_Tool_darkmode');?></button>
</div>
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_darkmode_text');?></div>
</div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a">
<div class="form-group" >
<div class="input-group" >
<select id="columnsSelect" class="form-control select2 select2-hidden-accessible" multiple="" style="width: 100%;" tabindex="-1" aria-hidden="true">
<option value="0"><?php echo lang('Device_TableHead_Name');?></option>
<option value="1"><?php echo lang('Device_TableHead_Owner');?></option>
<option value="2"><?php echo lang('Device_TableHead_Type');?></option>
<option value="3"><?php echo lang('Device_TableHead_Icon');?></option>
<option value="4"><?php echo lang('Device_TableHead_Favorite');?></option>
<option value="5"><?php echo lang('Device_TableHead_Group');?></option>
<option value="6"><?php echo lang('Device_TableHead_FirstSession');?></option>
<option value="7"><?php echo lang('Device_TableHead_LastSession');?></option>
<option value="8"><?php echo lang('Device_TableHead_LastIP');?></option>
<option value="9"><?php echo lang('Device_TableHead_MAC');?></option>
<option value="10"><?php echo lang('Device_TableHead_Status');?></option>
<option value="11"><?php echo lang('Device_TableHead_MAC_full');?></option>
<option value="12"><?php echo lang('Device_TableHead_LastIPOrder');?></option>
<option value="13"><?php echo lang('Device_TableHead_Rowid');?></option>
<option value="14"><?php echo lang('Device_TableHead_Parent_MAC');?></option>
</select>
<span class="input-group-addon"><i title="<?php echo lang('DevDetail_GoToNetworkNode');?>" class="fa fa-save pointer" onclick="saveSelectedColumns();"></i></span>
</div>
</div>
</div>
<div class="db_tools_table_cell_b"><?php echo lang('Maintenance_Tool_displayed_columns_text');?></div>
</div>
</div>
</div>
<div class="tab-pane" id="tab_DBTools">
@@ -482,6 +513,8 @@ if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
<!-- ----------------------------------------------------------------------- -->
<script>
var emptyArr = ['undefined', "", undefined, null];
@@ -641,39 +674,52 @@ function ImportCSV()
});
}
// --------------------------------------------------------
// Switch Darkmode
function askPiaEnableDarkmode() {
function askToggleDarkmode() {
// Ask
showModalWarning('<?php echo lang('Maintenance_Tool_darkmode_noti');?>', '<?php echo lang('Maintenance_Tool_darkmode_noti_text');?>',
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Switch');?>', 'PiaEnableDarkmode');
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Switch');?>', 'ToggleDarkmode');
}
function PiaEnableDarkmode()
{
// Execute
$.get('php/server/devices.php?action=PiaEnableDarkmode', function(msg) {
showMessage (msg);
});
}
// Toggle the Arp-Scans
function askPiaToggleArpScan () {
// Ask
showModalWarning('<?php echo lang('Maintenance_Tool_arpscansw_noti');?>', '<?php echo lang('Maintenance_Tool_arpscansw_noti_text');?>',
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Switch');?>', 'PiaToggleArpScan');
}
function PiaToggleArpScan()
{
// Execute
$.get('php/server/devices.php?action=PiaToggleArpScan', function(msg) {
showMessage (msg);
// --------------------------------------------------------
function ToggleDarkmode()
{
// get parameter Front_Dark_Mode_Enabled value
$.get('php/server/parameters.php?action=get&defaultValue=false&expireMinutes=525600&parameter=Front_Dark_Mode_Enabled', function(data) {
var result = JSON.parse(data);
if (result) {
darkModeEnabled = result == 'true';
// invert value
darkModeEnabled = !darkModeEnabled;
// save inverted value
$.get('php/server/parameters.php?action=set&parameter=Front_Dark_Mode_Enabled&expireMinutes=525600&value='+ darkModeEnabled,
function(data) {
if (data != "OK") {
showMessage (data);
setTimeout(function (){location.reload()}, 1000);
} else {
showMessage (data);
};
} );
}
});
}
// --------------------------------------------------------
// Clean log file
var targetLogFile = "";
var logFileAction = "";
// --------------------------------------------------------
function logManage(callback) {
targetLogFile = arguments[0]; // target
logFileAction = arguments[1]; // action
@@ -682,6 +728,7 @@ function logManage(callback) {
'<?php echo lang('Gen_Cancel');?>', '<?php echo lang('Gen_Okay');?>', "performLogManage");
}
// --------------------------------------------------------
function performLogManage() {
// Execute
console.log("targetLogFile:" + targetLogFile)
@@ -697,37 +744,98 @@ function performLogManage() {
})
}
// --------------------------------------------------------
function scrollDown()
{
var tempArea = $('#pialert_log');
$(tempArea[0]).scrollTop(tempArea[0].scrollHeight);
var areaIDs = ['pialert_log', 'pialert_front_log', 'IP_changes_log', 'stdout_log', 'stderr_log', 'pialert_pholus_log', 'pialert_pholus_lastrun_log'];
for (let i = 0; i < areaIDs.length; i++) {
tempArea = $('#pialert_front_log');
$(tempArea[0]).scrollTop(tempArea[0].scrollHeight);
tempArea = $('#IP_changes_log');
$(tempArea[0]).scrollTop(tempArea[0].scrollHeight);
tempArea = $('#stdout_log');
$(tempArea[0]).scrollTop(tempArea[0].scrollHeight);
tempArea = $('#stderr_log');
$(tempArea[0]).scrollTop(tempArea[0].scrollHeight);
tempArea = $('#pialert_pholus_log');
$(tempArea[0]).scrollTop(tempArea[0].scrollHeight);
tempArea = $('#pialert_pholus_lastrun_log');
$(tempArea[0]).scrollTop(tempArea[0].scrollHeight);
var tempArea = $('#' + areaIDs[i]);
$(tempArea[0]).scrollTop(tempArea[0].scrollHeight);
}
}
// --------------------------------------------------------
// Manage displayed columns
// --------------------------------------------------------
function saveSelectedColumns () {
$.get('php/server/parameters.php?action=set&expireMinutes=525600&value=['+ $('#columnsSelect').val().toString() +']&parameter=Front_Devices_Columns_Visible', function(data) {
// save full order of all columns to simplify mapping later on
colDisplayed = $('#columnsSelect').val();
colDefaultOrder = ['0','1','2','3','4','5','6','7','8','9','10','12','13','14'];
colNewOrder = colDisplayed;
// append the remaining columns in the previous order
for(i = 0; i < colDefaultOrder.length; i++)
{
if(!colDisplayed.includes(colDefaultOrder[i]))
{
colNewOrder.push(colDefaultOrder[i])
}
}
// save the setting in the DB
$.get('php/server/parameters.php?action=set&expireMinutes=525600&value=['+ colNewOrder.toString() +']&parameter=Front_Devices_Columns_Order', function(data) {
showMessage(data);
});
});
}
// --------------------------------------------------------
function initializeSelectedColumns () {
$.get('php/server/parameters.php?action=get&expireMinutes=525600&defaultValue=[0,1,2,3,4,5,6,7,8,9,10,12,13,14]&parameter=Front_Devices_Columns_Visible', function(data) {
tableColumnShow = numberArrayFromString(data);
for(i=0; i < tableColumnShow.length; i++)
{
// create the option and append to Select2
var option = new Option($('#columnsSelect option[value='+tableColumnShow[i]+']').html(), tableColumnShow[i] , true, true);
$("#columnsSelect").append(option).trigger('change');
$(option).attr('eee','eee')
}
});
}
// --------------------------------------------------------
//Initialize Select2 Elements and make them sortable
$(function () {
selectEl = $('.select2').select2();
selectEl.next().children().children().children().sortable({
containment: 'parent', stop: function (event, ui) {
ui.item.parent().children('[title]').each(function () {
var title = $(this).attr('title');
var original = $( 'option:contains(' + title + ')', selectEl ).first();
original.detach();
selectEl.append(original)
});
selectEl.change();
}
});
});
// --------------------------------------------------------
// General initialization
// --------------------------------------------------------
function initializeTabs () {
key = "activeMaintenanceTab"
// --------------------------------------------------------
// default selection
selectedTab = "tab_Settings"
@@ -736,9 +844,8 @@ function initializeTabs () {
// update cookie if target specified
if(target != "")
{
// console.log(target)
setCache(key, target+'_id')
{
setCache(key, target+'_id') // _id is added so it doesn't conflict with AdminLTE tab behavior
}
// get the tab id from the cookie (already overriden by the target)
@@ -748,10 +855,6 @@ function initializeTabs () {
}
// Activate panel
if(!emptyArr.includes(getCache(key)))
{
selectedTab = getCache(key);
}
$('.nav-tabs a[id='+ selectedTab +']').tab('show');
// When changed save new current tab
@@ -762,7 +865,7 @@ function initializeTabs () {
// events on tab change
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var target = $(e.target).attr("href") // activated tab
//alert(target);
if(target == "#tab_Logging")
{
scrollDown();
@@ -770,6 +873,8 @@ function initializeTabs () {
});
}
// --------------------------------------------------------
// save language in a cookie
$('#langselector').on('change', function (e) {
var optionSelected = $("option:selected", this);
@@ -777,11 +882,13 @@ $('#langselector').on('change', function (e) {
setCookie("language",valueSelected )
location.reload();
});
// --------------------------------------------------------
// load footer asynchronously not to block the page load/other sections
window.onload = function asyncFooter()
{
initializeSelectedColumns();
scrollDown();
initializeTabs();
@@ -795,5 +902,11 @@ window.onload = function asyncFooter()
</script>
<link rel="stylesheet" href="lib/AdminLTE/bower_components/select2/dist/css/select2.min.css">
<script src="lib/AdminLTE/bower_components/select2/dist/js/select2.full.min.js"></script>
<script src="lib/AdminLTE/bower_components/jquery-ui/jquery-ui.min.js"></script>
<!-- ----------------------------------------------------------------------- -->
<script src="js/pialert_common.js"></script>

View File

@@ -20,16 +20,19 @@
<section class="content-header">
<?php require 'php/templates/notification.php'; ?>
<h1 id="pageTitle">
<?php echo lang('Network_Title');?>
<i class="fa fa-network-wired"></i> <?php echo lang('Network_Title');?>
</h1>
</section>
<div id="networkTree" ></div>
<!-- Main content ---------------------------------------------------------- -->
<section class="content">
<?php
// Create top-level node (network devices) tabs
function createDeviceTabs($node_mac, $node_name, $node_status, $node_type, $node_ports_count, $activetab) {
function createDeviceTabs($node_mac, $node_name, $node_status, $node_type, $node_ports_count, $icon, $activetab) {
// prepare string with port number in brackets if available
$str_port = "";
@@ -46,11 +49,16 @@
{
$node_badge = circle_offline;
}
if($icon != '')
{
$icon = '<i class="fa fa-'.$icon.'"></i> ';
}
$idFromMac = str_replace(":", "_", $node_mac);
$str_tab_header = '<li class="'.$activetab.'">
<a href="#'.str_replace(":", "_", $node_mac).'" data-toggle="tab" >'
.$node_name.' ' .$str_port.$node_badge.
<a href="#'.$idFromMac.'" data-mytabmac="'.$node_mac.'" id="'.$idFromMac.'_id" data-toggle="tab" >' // _id is added so it doesn't conflict with AdminLTE tab behavior
.$icon.$node_name.' ' .$str_port.$node_badge.
'</a>
</li>';
@@ -71,17 +79,29 @@
$node_badge = badge_offline;
}
$str_tab_pane = '<div class="tab-pane '.$activetab.'" id="'.str_replace(":", "_", $node_mac).'">
<a href="./deviceDetails.php?mac='.$node_mac.'">
<h4>'.$node_name.'</h4>
</a>
<table class="table table-striped" style="width:200px;">
$idFromMac = str_replace(":", "_", $node_mac);
$idParentMac = str_replace(":", "_", $node_parent_mac);
$str_tab_pane = '<div class="tab-pane '.$activetab.'" id="'.$idFromMac.'">
<div>
<h2 class="page-header"><i class="fa fa-server"></i> '.lang('Network_Node'). '</h2>
</div>
<table class="table table-striped" >
<tbody>
<tr>
<td >
<b>MAC:</b>
<td class="col-sm-3">
<b>'.lang('Network_Node').'</b>
</td>
<td class="anonymize">'
<td class="anonymize">
<a href="./deviceDetails.php?mac='.$node_mac.'">
'.$node_name.'
</a>
</td>
</tr>
<tr>
<td >
<b>MAC</b>
</td>
<td data-mynodemac="'.$node_mac.'" class="anonymize">'
.$node_mac.
'</td>
</tr>
@@ -95,7 +115,7 @@
</tr>
<tr>
<td>
<b>'.lang('Network_Table_State').':</b>
<b>'.lang('Network_Table_State').'</b>
</td>
<td> '
.$node_badge.
@@ -103,29 +123,33 @@
</tr>
<tr>
<td>
<b>'.lang('DevDetail_MainInfo_Network').'</b>
<b>'.lang('Network_Parent').'</b>
</td>
<td>
<a href="./deviceDetails.php?mac='.$node_parent_mac.'">
<b class="anonymize">'.$node_parent_mac.'</b>
<a onclick="setCache(\'activeNetworkTab\',\''.$idParentMac.'_id\')" href="./network.php">
<b class="anonymize">'.$idParentMac.' <i class="fa fa-square-up-right"></i></b>
</a>
</td>
</tr>
</tbody>
</table>
<br>
<div class="box-body no-padding">';
<div id="assignedDevices" class="box-body no-padding">
<div class="page-header">
<h3>
<i class="fa fa-sitemap"></i> '.lang('Network_Connected').'
</h3>
</div>
';
$str_table = ' <h4>
'.lang('Device_Title').'
</h4>
<table class="table table-striped">
$str_table = ' <table class="table table-striped">
<tbody>
<tr>
<th style="width: 40px">Port</th>
<th style="width: 100px">'.lang('Network_Table_State').'</th>
<th>'.lang('Network_Table_Hostname').'</th>
<th>'.lang('Network_Table_IP').'</th>
<th class="col-sm-1" >Port</th>
<th class="col-sm-1" >'.lang('Network_Table_State').'</th>
<th class="col-sm-2" >'.lang('Network_Table_Hostname').'</th>
<th class="col-sm-1" >'.lang('Network_Table_IP').'</th>
<th class="col-sm-3" >'.lang('Network_ManageLeaf').'</th>
</tr>';
// Prepare Array for Devices with Port value
@@ -204,6 +228,9 @@
<td class="anonymize">'
.$row['last_ip'].
'</td>
<td class="">
<button class="btn btn-primary btn-danger btn-sm" data-myleafmac="'.$row['mac'].'" >'.lang('Network_ManageUnassign').'</button>
</td>
</tr>';
}
@@ -214,13 +241,9 @@
// no connected device - don't render table, just display some info
if($str_table_rows == "")
{
$str_table = "<div>
<h4>
".lang('Device_Title')."
</h4>
$str_table = "<div>
<div>
This network device (node) doesn't have any assigned devices (leaf nodes).
Go to <a href='devices.php'><b>".lang('Device_Title')."</b></a>, select a device you want to attach to this node and assign it in the <b>Details</b> tab by selecting it in the <b>".lang('DevDetail_MainInfo_Network') ."</b> dropdown.
".lang("Network_NoAssignedDevices")."
</div>
</div>";
$str_table_close = "";
@@ -247,16 +270,17 @@
// \
// PC (leaf)
$sql = "SELECT node_name, node_mac, online, node_type, node_ports_count, parent_mac
$sql = "SELECT node_name, node_mac, online, node_type, node_ports_count, parent_mac, node_icon
FROM
(
SELECT a.dev_Name as node_name,
a.dev_MAC as node_mac,
a.dev_PresentLastScan as online,
a.dev_DeviceType as node_type,
a.dev_Network_Node_MAC_ADDR as parent_mac
a.dev_Network_Node_MAC_ADDR as parent_mac,
a.dev_Icon as node_icon
FROM Devices a
WHERE a.dev_DeviceType in ('AP', 'Gateway', 'Powerline', 'Switch', 'WLAN', 'PLC', 'Router','USB LAN Adapter', 'USB WIFI Adapter', 'Internet')
WHERE a.dev_DeviceType in ('AP', 'Gateway', 'Firewall', 'Powerline', 'Switch', 'WLAN', 'PLC', 'Router','USB LAN Adapter', 'USB WIFI Adapter', 'Internet')
) t1
LEFT JOIN
(
@@ -279,7 +303,8 @@
'online' => $row['online'],
'node_type' => $row['node_type'],
'parent_mac' => $row['parent_mac'],
'node_ports_count' => $row['node_ports_count']);
'node_icon' => $row['node_icon'],
'node_ports_count' => $row['node_ports_count']);
}
// Control no rows
@@ -290,13 +315,14 @@
echo '<div class="nav-tabs-custom" style="margin-bottom: 0px;">
<ul class="nav nav-tabs">';
$activetab='active';
$activetab='active';
foreach ($tableData as $row) {
createDeviceTabs( $row['node_mac'],
$row['node_name'],
$row['online'],
$row['node_type'],
$row['node_ports_count'],
$row['node_icon'],
$activetab);
$activetab = ""; // reset active tab indicator, only the first tab is active
@@ -318,8 +344,6 @@
$activetab = ""; // reset active tab indicator, only the first tab is active
}
commitDB ();
?>
<!-- /.tab-pane -->
@@ -354,17 +378,19 @@
if (!(empty($tableData))) {
$str_table_header = '
<div class="content">
<div class="box box-aqua box-body">
<div id="unassignedDevices" class="box box-aqua box-body">
<section>
<h4>
'.lang('Network_UnassignedDevices').'
</h4>
<h3>
<i class="fa fa-laptop"></i> '.lang('Network_UnassignedDevices').'
</h3>
<table class="table table-striped">
<tbody>
<tr>
<th style="width: 100px">'.lang('Network_Table_State').'</th>
<th>'.lang('Network_Table_Hostname').'</th>
<th>'.lang('Network_Table_IP').'</th>
<th class="col-sm-1" ></th>
<th class="col-sm-1" >'.lang('Network_Table_State').'</th>
<th class="col-sm-2" >'.lang('Network_Table_Hostname').'</th>
<th class="col-sm-1" >'.lang('Network_Table_IP').'</th>
<th class="col-sm-3" >'.lang('Network_Assign').'</th>
</tr>';
$str_table_rows = "";
@@ -378,7 +404,9 @@
}
$str_table_rows = $str_table_rows.
'<tr>
'
<tr>
<td> </td>
<td>'
.$state.
'</td>
@@ -389,9 +417,11 @@
</td>
<td>'
.$row['last_ip'].
'</td>
'</td>
<td>
<button class="btn btn-primary btn-sm" data-myleafmac="'.$row['mac'].'" >'.lang('Network_ManageAssign').'</button>
</td>
</tr>';
}
$str_table_close = '</tbody>
@@ -404,14 +434,300 @@
echo $str_table_header.$str_table_rows.$str_table_close;
}
CommitDB ();
?>
?>
<!-- /.content -->
</div>
<!-- /.content-wrapper -->
<!-- ----------------------------------------------------------------------- -->
<?php
require 'php/templates/footer.php';
?>
<script src="lib/treeviz/index.js"></script>
<script src="lib/treeviz/require.js"></script>
<script src="js/pialert_common.js"></script>
<script>
// ---------------------------------------------------------------------------
// Tree functionality
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
function getDevicesList()
{
// Read cache
devicesList = getCache('devicesList');
if (devicesList != '') {
devicesList = JSON.parse (devicesList);
} else {
devicesList = [];
}
return devicesList;
}
// ---------------------------------------------------------------------------
var leafNodesCount = 0;
var treeLoadedAlready = false;
var hiddenMacs = [];
function getChildren(node, list, path)
{
var children = [];
// loop thru all items and find childern...
for(var i in list)
{
//... of teh current node
if(list[i].parentMac == node.mac && !hiddenMacs.includes(list[i].parentMac))
{
// and process them
children.push(getChildren(list[i], list, path + ((path == "") ? "" : '|') + list[i].parentMac, hiddenMacs))
}
}
// note the total number of leaf nodes to calculate the font scaling
if(!treeLoadedAlready && children.length == 0)
{
leafNodesCount++
}
return {
name: node.name,
path: path,
mac: node.mac,
parentMac: node.parentMac,
icon: node.icon,
type: node.type,
status: node.status,
hasChildren: children.length > 0 || hiddenMacs.includes(node.mac),
hiddenChildren: hiddenMacs.includes(node.mac),
qty: children.length,
children: children
};
}
// ---------------------------------------------------------------------------
list = getDevicesList();
function getHierarchy()
{
for(i in list)
{
if(list[i].mac == 'Internet')
{
return (getChildren(list[i], list, ''))
break;
}
}
}
// ---------------------------------------------------------------------------
function toggleSubTree(parentMac, treePath)
{
treePath = treePath.split('|')
if(!hiddenMacs.includes(parentMac))
{
hiddenMacs.push(parentMac)
}
else
{
removeItemFromArray(hiddenMacs, parentMac)
}
list = getDevicesList();
// updatedTree = myHierarchy;
updatedTree = getHierarchy()
myTree.refresh(updatedTree);
// re-attach any onclick events
attachTreeEvents();
}
// ---------------------------------------------------------------------------
function attachTreeEvents()
{
// toggle subtree functionality
$("div[data-mytreemac]").each(function(){
$(this).attr('onclick', 'toggleSubTree("'+$(this).attr('data-mytreemac')+'","'+ $(this).attr('data-mytreepath')+'")')
});
}
// ---------------------------------------------------------------------------
var myTree;
var treeAreaHeight = 600;
function initTree(myHierarchy)
{
// to prevent font scaling everytime we collapse/expand a subtree
treeLoadedAlready = true;
$("#networkTree").attr('style', "height:"+treeAreaHeight+"px; width:1070px")
myTree = Treeviz.create({
htmlId: "networkTree",
renderNode: nodeData => {
// calculate the font size of the leaf nodes to fit everything into the tree area
var fontSize = (nodeData.data.hasChildren) ? "" : "font-size:"+((600/(20*leafNodesCount)).toFixed(2))+"em;";
deviceIcon = (!emptyArr.includes(nodeData.data.icon )) ? "<div class='netIcon '><i class='fa fa-"+nodeData.data.icon +"'></i></div>" : "";
collapseExpandIcon = nodeData.data.hiddenChildren ? "square-plus" :"square-minus";
collapseExpandHtml = (nodeData.data.hasChildren) ? "<div class='netCollapse' data-mytreepath='"+nodeData.data.path+"' data-mytreemac='"+nodeData.data.mac+"'><i class='fa fa-"+ collapseExpandIcon +" pointer'></i></div>" : "";
statusCss = " netStatus-" + nodeData.data.status;
selectedNodeMac = $(".nav-tabs-custom .active a").attr('data-mytabmac')
highlightedCss = nodeData.data.mac == selectedNodeMac ? " highlightedNode" : "";
return result = "<div class='box "+statusCss+" "+highlightedCss+"' data-mytreemacmain='"+nodeData.data.mac+"' \
style='height:"+nodeData.settings.nodeHeight+"px;\
width:180px;\
display:flex;\
flex-direction:column;\
justify-content:center;\
" + fontSize + "\
align-items:center;\
background-color:" +nodeData.data.color+";\
border-radius:5px;'\
>\
<div class='netNodeText '>\
<strong>" + deviceIcon +
"<span class='spanNetworkTree anonymizeDev'>"+nodeData.data.name+"</span>\
</strong>"
+collapseExpandHtml+
"</div></div>";
},
onNodeClick: nodeData => {
// console.log(this)
},
mainAxisNodeSpacing: 'auto',
secondaryAxisNodeSpacing: 0.3,
nodeHeight: '25',
marginTop: '5',
hasZoom: false,
hasPan: false,
marginLeft: '15',
idKey: "name",
hasFlatData: false,
linkWidth: (nodeData) => 3,
relationnalField: "children",
});
myTree.refresh(myHierarchy);
}
// ---------------------------------------------------------------------------
// Tabs functionality
// ---------------------------------------------------------------------------
// Register events on tab change
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
// init parent node
var currentNodeMac = $(".tab-content .active td[data-mynodemac]").attr('data-mynodemac');
initButtons(currentNodeMac);
// change highlighted node in the tree
selNode = $("#networkTree .highlightedNode")[0]
// console.log(selNode)
if(selNode)
{
$(selNode).attr('class', $(selNode).attr('class').replace('highlightedNode'))
}
newSelNode = $("#networkTree div[data-mytreemacmain='"+currentNodeMac+"']")[0]
$(newSelNode).attr('class', $(newSelNode).attr('class') + ' highlightedNode')
});
// ---------------------------------------------------------------------------
function initTab()
{
key = "activeNetworkTab"
// default selection
selectedTab = "Internet_id"
// the #target from the url
target = window.location.hash.substr(1)
// update cookie if target specified
if(target != "")
{
setCache(key, target+'_id') // _id is added so it doesn't conflict with AdminLTE tab behavior
}
// get the tab id from the cookie (already overriden by the target)
if(!emptyArr.includes(getCache(key)))
{
selectedTab = getCache(key);
}
// Activate panel
$('.nav-tabs a[id='+ selectedTab +']').tab('show');
// When changed save new current tab
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
setCache(key, $(e.target).attr('id'))
});
}
// ---------------------------------------------------------------------------
function initButtons(currentNodeMac)
{
// init the Assign buttons
$('#unassignedDevices button[data-myleafmac]').each(function(){
$(this).attr('onclick', 'updateLeaf("'+$(this).attr('data-myleafmac')+'","'+currentNodeMac+'")')
});
// init Unassign buttons
$('#assignedDevices button[data-myleafmac]').each(function(){
$(this).attr('onclick', 'updateLeaf("'+$(this).attr('data-myleafmac')+'","")')
});
}
// ---------------------------------------------------------------------------
function updateLeaf(leafMac,nodeMac)
{
saveData('updateNetworkLeaf', leafMac, nodeMac);
setTimeout("location.reload();", 1000); // refresh page after 1s
}
// init selected (first) tab
initTab();
// create tree
initTree(getHierarchy());
// attach on-click events
attachTreeEvents();
</script>

View File

@@ -70,11 +70,6 @@ function OpenDB (...$DBPath) {
$db->exec('PRAGMA journal_mode = wal;');
}
function CommitDB () {
global $db;
// $db->commit();
}
// # Open DB once and keep open
// # Opening / closing DB frequently actually casues more issues

View File

@@ -12,7 +12,7 @@
require '/home/pi/pialert/front/php/templates/timezone.php';
require '/home/pi/pialert/front/php/templates/language/lang.php';
require '/home/pi/pialert/front/php/server/db.php';
require '/home/pi/pialert/front/php/server/util.php';
require '/home/pi/pialert/front/php/server/util.php';
//------------------------------------------------------------------------------
// Action selector
@@ -41,9 +41,7 @@
case 'deleteDeviceEvents': deleteDeviceEvents(); break;
case 'PiaBackupDBtoArchive': PiaBackupDBtoArchive(); break;
case 'PiaRestoreDBfromArchive': PiaRestoreDBfromArchive(); break;
case 'PiaPurgeDBBackups': PiaPurgeDBBackups(); break;
case 'PiaEnableDarkmode': PiaEnableDarkmode(); break;
case 'PiaToggleArpScan': PiaToggleArpScan(); break;
case 'PiaPurgeDBBackups': PiaPurgeDBBackups(); break;
case 'ExportCSV': ExportCSV(); break;
case 'ImportCSV': ImportCSV(); break;
@@ -58,12 +56,15 @@
case 'getPholus': getPholus(); break;
case 'getNmap': getNmap(); break;
case 'saveNmapPort': saveNmapPort(); break;
case 'updateNetworkLeaf': updateNetworkLeaf(); break;
case 'overwriteIconType': overwriteIconType(); break;
case 'getIcons': getIcons(); break;
default: logServerConsole ('Action: '. $action); break;
}
}
CommitDB();
//------------------------------------------------------------------------------
// Query Device Data
@@ -153,6 +154,7 @@ function setDeviceData() {
dev_Owner = "'. quotes($_REQUEST['owner']) .'",
dev_DeviceType = "'. quotes($_REQUEST['type']) .'",
dev_Vendor = "'. quotes($_REQUEST['vendor']) .'",
dev_Icon = "'. quotes($_REQUEST['icon']) .'",
dev_Favorite = "'. quotes($_REQUEST['favorite']) .'",
dev_Group = "'. quotes($_REQUEST['group']) .'",
dev_Location = "'. quotes($_REQUEST['location']) .'",
@@ -523,28 +525,8 @@ function ImportCSV() {
echo lang('BackDevices_DBTools_ImportCSVMissing');
}
CommitDB();
}
//------------------------------------------------------------------------------
// Toggle Dark/Light Themes
//------------------------------------------------------------------------------
function PiaEnableDarkmode() {
$file = '../../../db/setting_darkmode';
if (file_exists($file)) {
echo lang('BackDevices_darkmode_disabled');
unlink($file);
echo("<meta http-equiv='refresh' content='1'>");
} else {
echo lang('BackDevices_darkmode_enabled');
$darkmode = fopen($file, 'w');
echo("<meta http-equiv='refresh' content='1'>");
}
}
//------------------------------------------------------------------------------
// Query total numbers of Devices by status
//------------------------------------------------------------------------------
@@ -587,6 +569,41 @@ function getDevicesTotals() {
function getDevicesList() {
global $db;
// This object is used to map from the old order ( second parameter, first number) to the 3rd parameter (Second number (here initialized to -1))
$columnOrderMapping = array(
array("dev_Name", 0, -1),
array("dev_Owner", 1, -1),
array("dev_DeviceType", 2, -1),
array("dev_Icon", 3, -1),
array("dev_Favorite", 4, -1),
array("dev_Group", 5, -1),
array("dev_FirstConnection", 6, -1),
array("dev_LastConnection", 7, -1),
array("dev_LastIP", 8, -1),
array("dev_MAC", 9, -1),
array("dev_Status", 10, -1),
array("dev_MAC_full", 11, -1),
array("dev_LastIP_orderable", 12, -1),
array("rowid", 13, -1),
array("dev_Network_Node_MAC_ADDR", 14, -1)
);
// get device columns order
$sql = 'SELECT par_Value FROM Parameters where par_ID = "Front_Devices_Columns_Order"';
$result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_NUM);
if($row != NULL && count($row) == 1)
{
// ordered columns setting from the maintenance page
$orderedColumns = createArray($row[0]);
// init ordered columns
for($i = 0; $i < count($orderedColumns); $i++) {
$columnOrderMapping[$i][2] = $orderedColumns[$i];
}
}
// SQL
$condition = getDeviceCondition ($_REQUEST['status']);
@@ -598,24 +615,37 @@ function getDevicesList() {
END AS dev_Status
FROM Devices '. $condition;
$result = $db->query($sql);
// arrays of rows
$tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
$tableData['data'][] = array ($row['dev_Name'],
$row['dev_Owner'],
$row['dev_DeviceType'],
$row['dev_Favorite'],
$row['dev_Group'],
formatDate ($row['dev_FirstConnection']),
formatDate ($row['dev_LastConnection']),
$row['dev_LastIP'],
( in_array($row['dev_MAC'][1], array("2","6","A","E","a","e")) ? 1 : 0),
$row['dev_Status'],
$row['dev_MAC'], // MAC (hidden)
formatIPlong ($row['dev_LastIP']), // IP orderable
$row['rowid'] // Rowid (hidden)
);
$defaultOrder = array ($row['dev_Name'],
$row['dev_Owner'],
$row['dev_DeviceType'],
$row['dev_Icon'],
$row['dev_Favorite'],
$row['dev_Group'],
formatDate ($row['dev_FirstConnection']),
formatDate ($row['dev_LastConnection']),
$row['dev_LastIP'],
( in_array($row['dev_MAC'][1], array("2","6","A","E","a","e")) ? 1 : 0),
$row['dev_Status'],
$row['dev_MAC'], // MAC (hidden)
formatIPlong ($row['dev_LastIP']), // IP orderable
$row['rowid'], // Rowid (hidden)
$row['dev_Network_Node_MAC_ADDR'] //
);
$newOrder = array();
for($index = 0; $index < count($columnOrderMapping); $index++)
{
array_push($newOrder, $defaultOrder[$columnOrderMapping[$index][2]]);
}
$tableData['data'][] = $newOrder;
}
// Control no rows
@@ -695,7 +725,7 @@ function getNetworkNodes() {
global $db;
// Device Data
$sql = 'SELECT * FROM Devices WHERE dev_DeviceType in ( "AP", "Gateway", "Powerline", "Switch", "WLAN", "PLC", "Router","USB LAN Adapter", "USB WIFI Adapter")';
$sql = 'SELECT * FROM Devices WHERE dev_DeviceType in ( "AP", "Gateway", "Firewall", "Powerline", "Switch", "WLAN", "PLC", "Router","USB LAN Adapter", "USB WIFI Adapter")';
$result = $db->query($sql);
@@ -716,6 +746,32 @@ function getNetworkNodes() {
echo (json_encode ($tableData));
}
//------------------------------------------------------------------------------
function getIcons() {
global $db;
// Device Data
$sql = 'select dev_Icon from Devices group by dev_Icon';
$result = $db->query($sql);
// arrays of rows
$tableData = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
// Push row data
$tableData[] = array('id' => $row['dev_Icon'],
'name' => '<i class="fa fa-'.$row['dev_Icon'].'"></i> - '.$row['dev_Icon'] );
}
// Control no rows
if (empty($tableData)) {
$tableData = [];
}
// Return json
echo (json_encode ($tableData));
}
//------------------------------------------------------------------------------
// Query the List of types
@@ -733,7 +789,7 @@ function getDeviceTypes() {
"Laptop", "Mini PC", "PC", "Printer", "Server", "Singleboard Computer (SBC)", "NAS",
"Domotic", "IP Camera", "Game Console", "SmartTV", "TV Decoder", "Virtual Assistance",
"Clock", "House Appliance", "Phone", "Radio",
"AP", "Gateway", "Powerline", "Switch", "WLAN", "PLC", "Router","USB LAN Adapter", "USB WIFI Adapter" )
"AP", "Gateway", "Firewall", "Powerline", "Switch", "WLAN", "PLC", "Router","USB LAN Adapter", "USB WIFI Adapter" )
UNION SELECT 1 as dev_Order, "Smartphone"
UNION SELECT 1 as dev_Order, "Tablet"
@@ -761,6 +817,7 @@ function getDeviceTypes() {
-- network devices
UNION SELECT 5 as dev_Order, "AP"
UNION SELECT 5 as dev_Order, "Gateway"
UNION SELECT 5 as dev_Order, "Firewall"
UNION SELECT 5 as dev_Order, "Powerline"
UNION SELECT 5 as dev_Order, "Switch"
UNION SELECT 5 as dev_Order, "WLAN"
@@ -969,7 +1026,7 @@ function getNmap() {
function saveNmapPort()
{
$portIndex = $_REQUEST['index'];
$portIndex = $_REQUEST['id'];
$value = $_REQUEST['value'];
if(is_integer((int)$portIndex))
@@ -987,9 +1044,62 @@ function saveNmapPort()
echo 'KO';
}
}
// echo "asdasdasasd";
}
// ----------------------------------------------------------------------------------------
function updateNetworkLeaf()
{
$nodeMac = $_REQUEST['value'];
$leafMac = $_REQUEST['id'];
if ((false === filter_var($nodeMac , FILTER_VALIDATE_MAC) && $nodeMac != "Internet" && $nodeMac != "") || false === filter_var($leafMac , FILTER_VALIDATE_MAC) ) {
throw new Exception('Invalid mac address');
}
else
{
global $db;
// sql
$sql = 'UPDATE Devices SET "dev_Network_Node_MAC_ADDR" = "'. $nodeMac .'" WHERE "dev_MAC"="' . $leafMac.'"' ;
// update Data
$result = $db->query($sql);
// check result
if ($result == TRUE) {
echo 'OK';
} else {
echo 'KO';
}
}
}
// ----------------------------------------------------------------------------------------
function overwriteIconType()
{
$mac = $_REQUEST['mac'];
$icon = $_REQUEST['icon'];
if ((false === filter_var($mac , FILTER_VALIDATE_MAC) && $mac != "Internet" && $mac != "") ) {
throw new Exception('Invalid mac address');
}
else
{
global $db;
// sql
$sql = 'UPDATE Devices SET "dev_Icon" = "'. $icon .'" where dev_DeviceType in (select dev_DeviceType from Devices where dev_MAC = "' . $mac.'")' ;
// update Data
$result = $db->query($sql);
// check result
if ($result == TRUE) {
echo 'OK';
} else {
echo 'KO';
}
}
}
//------------------------------------------------------------------------------
// Status Where conditions

View File

@@ -22,17 +22,28 @@
ini_set ('max_execution_time','15');
$skipCache = FALSE;
$expireMinutes = 5;
$defaultValue = '';
if (isset ($_REQUEST['skipcache'])) {
$skipCache = TRUE;
}
if (isset ($_REQUEST['defaultValue'])) {
$defaultValue = $_REQUEST['defaultValue'];
}
if (isset ($_REQUEST['expireMinutes'])) {
$expireMinutes = $_REQUEST['expireMinutes'];
}
// Action functions
if (isset ($_REQUEST['action']) && !empty ($_REQUEST['action'])) {
$action = $_REQUEST['action'];
switch ($action) {
case 'get': getParameter($skipCache); break;
case 'set': setParameter(); break;
case 'get': getParameter($skipCache, $defaultValue, $expireMinutes); break;
case 'set': setParameter($expireMinutes); break;
default: logServerConsole ('Action: '. $action); break;
}
}
@@ -41,18 +52,19 @@
//------------------------------------------------------------------------------
// Get Parameter Value
//------------------------------------------------------------------------------
function getParameter($skipCache) {
function getParameter($skipCache, $defaultValue, $expireMinutes) {
$parameter = $_REQUEST['parameter'];
$value = "";
// get the value from the cookie if available
if(getCache($parameter) != "")
// get the value from the cache if available
$cachedValue = getCache($parameter);
if($cachedValue != "")
{
$value = getCache($parameter);
$value = $cachedValue;
}
// query the database if no cache entry found or requesting live data for the Back_App_State in the header
// query the database if no cache entry found or requesting live data (skipping cache)
if($skipCache || $value == "" )
{
global $db;
@@ -62,13 +74,16 @@ function getParameter($skipCache) {
$result = $db->query($sql);
$row = $result -> fetchArray (SQLITE3_NUM);
$value = $row[0];
// Commit DB
CommitDB();
if($row != NULL && count($row) == 1)
{
$value = $row[0];
} else{
$value = $defaultValue;
}
// update cookie cache
setCache($parameter, $value);
// update cache
setCache($parameter, $value, $expireMinutes);
}
// return value
echo (json_encode ($value));
@@ -78,10 +93,10 @@ function getParameter($skipCache) {
//------------------------------------------------------------------------------
// Set Parameter Value
//------------------------------------------------------------------------------
function setParameter() {
function setParameter($expireMinutes) {
$parameter = $_REQUEST['parameter'];
$value = $_REQUEST['value'];
$value = $_REQUEST['value'];
global $db;
@@ -109,11 +124,8 @@ function setParameter() {
}
}
// Commit DB
CommitDB();
// update cookie cache
setCache($parameter, $value);
// update cache
setCache($parameter, $value, $expireMinutes);
echo 'OK';
}

View File

@@ -79,6 +79,24 @@ function createArray($input){
return $options;
}
// -------------------------------------------------------------------------------------------
// For debugging - Print arrays
function printArray ($array) {
echo '[';
foreach ($array as $val)
{
if(is_array($val))
{
echo '<br/>';
printArray($val);
} else
{
echo $val.', ';
}
}
echo ']<br/>';
}
// -------------------------------------------------------------------------------------------
function formatDate ($date1) {
return date_format (new DateTime ($date1) , 'Y-m-d H:i');
@@ -205,6 +223,8 @@ function cleanLog($logFile)
}
}
// ----------------------------------------------------------------------------------------
function saveSettings()
{
@@ -339,7 +359,7 @@ function logServerConsole ($text) {
function getNetworkTypes(){
$array = array(
"AP", "Gateway", "Powerline", "Switch", "WLAN", "PLC", "Router","USB LAN Adapter", "USB WIFI Adapter"
"AP", "Gateway", "Firewall", "Powerline", "Switch", "WLAN", "PLC", "Router","USB LAN Adapter", "USB WIFI Adapter"
);
return $array;
@@ -389,8 +409,8 @@ function getCache($key) {
}
}
// -------------------------------------------------------------------------------------------
function setCache($key, $value) {
setcookie($key, $value, time()+300, "/","", 0); // 5min cache
function setCache($key, $value, $expireMinutes = 5) {
setcookie($key, $value, time()+$expireMinutes*60, "/","", 0);
}

View File

@@ -10,7 +10,6 @@
<?php
require '/home/pi/pialert/front/php/templates/timezone.php';
require '/home/pi/pialert/front/php/templates/skinUI.php';
require '/home/pi/pialert/front/php/templates/language/lang.php';
require '/home/pi/pialert/front/php/templates/security.php';
@@ -210,11 +209,11 @@ if ($ENABLED_DARKMODE === True) {
<ul class="sidebar-menu" data-widget="tree">
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('devices.php', 'deviceDetails.php') ) ){ echo 'active'; } ?>">
<a href="devices.php"><i class="fa fa-laptop"></i> <span><?php echo lang('Navigation_Devices');?></span></a>
<a href="devices.php"><span><?php echo lang('Navigation_Devices');?></span></a>
</li>
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('presence.php') ) ){ echo 'active'; } ?>">
<a href="presence.php"><i class="fa fa-calendar"></i> <span><?php echo lang('Navigation_Presence');?></span></a>
<a href="presence.php"><?php echo lang('Navigation_Presence');?></span></a>
</li>
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('events.php') ) ){ echo 'active'; } ?>">
@@ -222,7 +221,7 @@ if ($ENABLED_DARKMODE === True) {
</li>
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('network.php') ) ){ echo 'active'; } ?>">
<a href="network.php"><i class="fa fa-server"></i> <span><?php echo lang('Navigation_Network');?></span></a>
<a href="network.php"><span><?php echo lang('Navigation_Network');?></span></a>
</li>
<li class=" <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('maintenance.php') ) ){ echo 'active'; } ?>">
@@ -260,7 +259,7 @@ if ($ENABLED_DARKMODE === True) {
}
// get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ key + skipCacheQuery, function(data) {
$.get('php/server/parameters.php?action=get&defaultValue=NULL&parameter='+ key + skipCacheQuery, function(data) {
var result = data;
document.getElementById(targetId).innerHTML = result.replaceAll('"', '');

View File

@@ -380,7 +380,7 @@ $lang['de_de'] = array(
lösche ggf. die betreffende DHCP-Lease. Anschließend schaue, ebenfalls in Pi-hole, unter Tools -> Network, ob sich dort die immer wiederkehrenden Hosts finden lassen.
Wenn ja, lösche diese dort ebenfalls. Nun kannst du Pi.Alert wieder starten. Jetzt sollte das Gerät/die Geräte nicht mehr auftauchen.',
'HelpFAQ_Cat_Detail_300_head' => 'Was bedeutet ',
'HelpFAQ_Cat_Detail_300_text_a' => 'meint ein Netzwerkgerät (welches den typ AP, Gateway, Powerline, Switch, WLAN, PLC, Router,USB LAN Adapter, USB WIFI Adapter, or Internet eingestellt hat)',
'HelpFAQ_Cat_Detail_300_text_a' => 'meint ein Netzwerkgerät (welches den typ AP, Gateway, Firewall, Powerline, Switch, WLAN, PLC, Router,USB LAN Adapter, USB WIFI Adapter, or Internet eingestellt hat)',
'HelpFAQ_Cat_Detail_300_text_b' => 'bezeichnet die Anschlussnummer/Portnummer, an der das gerade bearbeitete Gerät mit diesem Netzwerkgerät verbunden ist.',
'HelpFAQ_Cat_Detail_301_head_a' => 'Wann wird nun gescannt? Bei ',
'HelpFAQ_Cat_Detail_301_head_b' => ' steht 1min aber der Graph zeigt 5min - Abstände an.',

View File

@@ -15,6 +15,8 @@ $lang['en_us'] = array(
'Gen_Delete' => 'Delete',
'Gen_Cancel' => 'Cancel',
'Gen_Okay' => 'Ok',
'Gen_Save' => 'Save',
'Gen_Saved' => 'Saved',
'Gen_Purge' => 'Purge',
'Gen_Backup' => 'Run Backup',
'Gen_Restore' => 'Run Restore',
@@ -45,12 +47,12 @@ $lang['en_us'] = array(
// Device Page
//////////////////////////////////////////////////////////////////
'Navigation_Devices' => 'Devices',
'Navigation_Presence' => 'Presence',
'Navigation_Devices' => '<i class="fa fa-laptop"></i> Devices',
'Navigation_Presence' => '<i class="fa fa-calendar"></i> Presence',
'Navigation_Events' => 'Events',
'Navigation_Maintenance' => 'Maintenance',
'Navigation_Settings' => 'Settings',
'Navigation_Network' => 'Network',
'Navigation_Network' => '<i class="fa fa-fw fa-network-wired"></i> Network',
'Navigation_HelpFAQ' => 'Help / FAQ',
'Device_Title' => 'Devices',
'Device_Shortcut_AllDevices' => 'All Devices',
@@ -64,14 +66,17 @@ $lang['en_us'] = array(
'Device_TableHead_Name' => 'Name',
'Device_TableHead_Owner' => 'Owner',
'Device_TableHead_Type' => 'Type',
'Device_TableHead_Icon' => 'Icon',
'Device_TableHead_RowID' => 'Row ID',
'Device_TableHead_Parent_MAC' => 'Parent node MAC',
'Device_TableHead_Favorite' => 'Favorite',
'Device_TableHead_Group' => 'Group',
'Device_TableHead_FirstSession' => 'First Session',
'Device_TableHead_LastSession' => 'Last Session',
'Device_TableHead_LastIP' => 'Last IP',
'Device_TableHead_MAC' => 'MAC',
'Device_TableHead_MAC_full' => 'Full MAC',
'Device_TableHead_LastIPOrder' => 'Last IP Order',
'Device_TableHead_Rowid' => 'Rowid',
'Device_TableHead_Status' => 'Status',
'Device_Searchbox' => 'Search',
'Device_Tablelenght' => 'Show _MENU_ entries',
@@ -150,36 +155,39 @@ $lang['en_us'] = array(
'DevDetail_Shortcut_Sessions' => 'Sessions',
'DevDetail_Shortcut_Presence' => 'Presence',
'DevDetail_Shortcut_DownAlerts' => 'Down Alerts',
'DevDetail_Tab_Details' => 'Details',
'DevDetail_Tab_Nmap' => 'Nmap',
'DevDetail_Tab_Sessions' => 'Sessions',
'DevDetail_Tab_Presence' => 'Presence',
'DevDetail_Tab_Events' => 'Events',
'DevDetail_Tab_Pholus' => 'Pholus',
'DevDetail_Tab_Details' => '<i class="fa fa-info-circle"></i> Details',
'DevDetail_Tab_Nmap' => '<i class="fa fa-ethernet"></i> Nmap',
'DevDetail_Tab_Sessions' => '<i class="fa fa-list-ol"></i> Sessions',
'DevDetail_Tab_Presence' => '<i class="fa fa-calendar"></i> Presence',
'DevDetail_Tab_Events' => '<i class="fa fa-bolt"></i> Events',
'DevDetail_Tab_Pholus' => '<i class="fa fa-search"></i> Pholus',
'DevDetail_Tab_PholusEmpty' => 'Nothing sniffed out with Pholus for this device.',
'DevDetail_Tab_NmapTableHeader' => 'Scheduled scan results',
'DevDetail_Tab_NmapTableText' => 'Set up a schedule in <a href="/settings.php#NMAP_ACTIVE">Settings</a>',
'DevDetail_Tab_NmapEmpty' => 'No ports detected with Nmap on this device.',
'DevDetail_MainInfo_Title' => 'Main Info',
'DevDetail_MainInfo_Title' => '<i class="fa fa-pencil"></i> Main Info',
'DevDetail_MainInfo_mac' => 'MAC',
'DevDetail_MainInfo_Name' => 'Name',
'DevDetail_MainInfo_Owner' => 'Owner',
'DevDetail_MainInfo_Type' => 'Type',
'DevDetail_Icon' => 'Icon',
'DevDetail_Icon_Descr' => 'Enter a font awesome icon name without the fa- prefix.',
'DevDetail_MainInfo_Vendor' => 'Vendor',
'DevDetail_MainInfo_Favorite' => 'Favorite',
'DevDetail_MainInfo_Group' => 'Group',
'DevDetail_MainInfo_Location' => 'Location',
'DevDetail_MainInfo_Comments' => 'Comments',
'DevDetail_MainInfo_Network_Title' => 'Network',
'DevDetail_MainInfo_Network' => 'Network Node (MAC)',
'DevDetail_MainInfo_Network_Port' => 'Connected to Port',
'DevDetail_SessionInfo_Title' => 'Session Info',
'DevDetail_MainInfo_Network_Title' => '<i class="fa fa-network-wired"></i> Network',
'DevDetail_MainInfo_Network' => '<i class="fa fa-server"></i> Node (MAC)',
'DevDetail_GoToNetworkNode' => 'Navigate to the Network page of the given node.',
'DevDetail_MainInfo_Network_Port' => '<i class="fa fa-ethernet"></i> Port',
'DevDetail_SessionInfo_Title' => '<i class="fa fa-calendar"></i> Session Info',
'DevDetail_SessionInfo_Status' => 'Status',
'DevDetail_SessionInfo_FirstSession' => 'First Session',
'DevDetail_SessionInfo_LastSession' => 'Last Session',
'DevDetail_SessionInfo_LastIP' => 'Last IP',
'DevDetail_SessionInfo_StaticIP' => 'Static IP',
'DevDetail_EveandAl_Title' => 'Events & Alerts config',
'DevDetail_EveandAl_Title' => '<i class="fa fa-bolt"></i> Events & Alerts config',
'DevDetail_EveandAl_ScanCycle' => 'Scan device',
'DevDetail_EveandAl_AlertAllEvents' => 'Alert All Events',
'DevDetail_EveandAl_AlertDown' => 'Alert Down',
@@ -194,8 +202,9 @@ $lang['en_us'] = array(
'DevDetail_button_DeleteEvents_Warning' => 'Are you sure you want to delete all Events of this device?<br><br>(this will clear the <b>Events history</b> and the <b>Sessions</b> and might help with constant (persistent) notifications)',
'DevDetail_button_Reset' => 'Reset Changes',
'DevDetail_button_Save' => 'Save',
'DevDetail_button_DeleteEvents' => 'Delete Events',
'DevDetail_button_DeleteEvents_Warning' => 'Are you sure you want to delete all Events of this device?<br><br>(this will clear the <b>Events history</b> and the <b>Sessions</b> and might help with constant (persistent) notifications)',
'DevDetail_button_OverwriteIcons' => 'Overwrite Icons',
'DevDetail_button_OverwriteIcons_Tooltip' => 'Overwrite icons of all devices with the same type',
'DevDetail_button_OverwriteIcons_Warning' => 'Are you sure you want to overwrite all icons of all devices with the same device type as the current device type?',
'DevDetail_SessionTable_Order' => 'Order',
'DevDetail_SessionTable_Connection' => 'Connection',
'DevDetail_SessionTable_Disconnection' => 'Disconnection',
@@ -246,7 +255,11 @@ $lang['en_us'] = array(
'Maintenance_Tools_Tab_Tools' => 'Tools',
'Maintenance_Tools_Tab_BackupRestore' => 'Backup / Restore',
'Maintenance_Tools_Tab_Logging' => 'Logs',
'Maintenance_Tool_displayed_columns_text' => 'Change the visibility and order of the columns in the <a href="devices.php"><b> <i class="fa fa-laptop"></i> Devices</b></a> page. (The drag-and-drop is a bit clunky, but for now workable, not a common task - won\'t fix for now (tried for <a href="https://github.com/jokob-sk/Pi.Alert/commit/94b32f0f7332879f5a7d2af05dafa2e5d5cfa5da">like 3h</a> - happy for someone to submit a PR :) )).',
'Maintenance_Tool_order_columns_text' => '',
'Maintenance_Tool_darkmode' => 'Toggle Modes (Dark/Light)',
'Maintenance_Tool_drag_me' => 'Drag me to reorder columns.',
'Maintenance_Tool_check_visible' => 'Uncheck to hide column.',
'Maintenance_Tool_darkmode_text' => 'Toggle between dark mode and light mode. If the switch does not work properly, try to clear the browser cache. The change takes place on the server side, so it affects all devices in use.',
'Maintenance_Tool_darkmode_noti' => 'Toggle Modes',
'Maintenance_Tool_darkmode_noti_text' => 'After the theme switch, the page tries to reload itself to activate the change. If necessary, the cache must be cleared.',
@@ -339,6 +352,8 @@ $lang['en_us'] = array(
'Network_Title' => 'Network overview',
'Network_ManageDevices' => 'Manage Devices',
'Network_ManageAdd' => 'Add Device',
'Network_ManageAssign' => 'Assign',
'Network_ManageUnassign' => 'Unassign',
'Network_ManageEdit' => 'Update Device',
'Network_ManageDel' => 'Delete Device',
'Network_ManageAdd_Name' => 'Device Name',
@@ -364,6 +379,13 @@ $lang['en_us'] = array(
'Network_Table_Hostname' => 'Hostname',
'Network_Table_IP' => 'IP',
'Network_UnassignedDevices' => 'Unassigned devices',
'Network_Assign' => 'Connect to the above <i class="fa fa-server"></i> Network node',
'Network_Connected' => 'Connected devices',
'Network_ManageLeaf' => 'Manage assignment',
'Network_Node' => 'Network node',
'Network_Node_Name' => 'Node name',
'Network_Parent' => 'Parent network device',
'Network_NoAssignedDevices' => 'This network node doesn\'t have any assigned devices (leaf nodes). Assign one from bellow or go to the <b><i class="fa fa-info-circle"></i> Details</b> tab of any device in <a href="devices.php"><b> <i class="fa fa-laptop"></i> Devices</b></a>, and assign it to a network <b><i class="fa fa-server"></i> Node (MAC)</b> and <b><i class="fa fa-ethernet"></i> Port</b> there.',
//////////////////////////////////////////////////////////////////
// Help Page
@@ -371,7 +393,7 @@ $lang['en_us'] = array(
'HelpFAQ_Title' => 'Help / FAQ',
'HelpFAQ_Cat_General' => 'General',
'HelpFAQ_Cat_Detail' => 'Details',
'HelpFAQ_Cat_Detail' => '<i class="fa fa-info-circle"></i> Details',
'HelpFAQ_Cat_General_100_head' => 'The clock on the top right and the times of the events/presence are not correct (time difference).',
'HelpFAQ_Cat_General_100_text_a' => 'On your PC the following time zone is set for the PHP environment:',
'HelpFAQ_Cat_General_100_text_b' => 'If this is not the timezone you are in, you should change the timezone in the PHP configuration file. You can find it in this directory:',
@@ -389,7 +411,7 @@ $lang['en_us'] = array(
chmod -R 770 ~/pialert/db
</span><br>
If the database is still read-only, try reinstalling or restoring a database backup from the maintenance page.',
'HelpFAQ_Cat_General_102docker_head' => '(🐳 Docker only) Database issues (AJAX errors, read-only, not found)',
'HelpFAQ_Cat_General_102docker_head' => 'Database issues (AJAX errors, read-only, not found)',
'HelpFAQ_Cat_General_102docker_text' => 'Double-check you\'ve followed the <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/tree/main/dockerfiles">dockerfile readme (most up-to-date info)</a>. <br/> <br/> <ul data-sourcepos="49:4-52:146" dir="auto">
<li data-sourcepos="49:4-49:106">Download the <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/blob/main/db/pialert.db">original DB from GitHub</a>.</li>
<li data-sourcepos="50:4-50:195">Map the <code>pialert.db</code> file (<g-emoji class="g-emoji" alias="warning" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/26a0.png">⚠</g-emoji> not folder) from above to <code>/home/pi/pialert/db/pialert.db</code> (see <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/tree/main/dockerfiles#-examples">Examples</a> for details).</li>
@@ -405,7 +427,7 @@ $lang['en_us'] = array(
delete the DHCP lease if necessary. Then, also in Pi-hole, look under Tools -> Network to see if you can find the recurring hosts there.
If yes, delete them there as well. Now you can start Pi.Alert again. Now the device(s) should not show up anymore.',
'HelpFAQ_Cat_Detail_300_head' => 'What means ',
'HelpFAQ_Cat_Detail_300_text_a' => 'means a network device (a device of the type AP, Gateway, Powerline, Switch, WLAN, PLC, Router,USB LAN Adapter, USB WIFI Adapter, or Internet).',
'HelpFAQ_Cat_Detail_300_text_a' => 'means a network device (a device of the type AP, Gateway, Firewall, Powerline, Switch, WLAN, PLC, Router,USB LAN Adapter, USB WIFI Adapter, or Internet).',
'HelpFAQ_Cat_Detail_300_text_b' => 'designates the port number where the currently edited device is connected to this network device.',
'HelpFAQ_Cat_Detail_301_head_a' => 'When is scanning now? At ',
'HelpFAQ_Cat_Detail_301_head_b' => ' says 1min but the graph shows 5min intervals.',
@@ -454,11 +476,11 @@ $lang['en_us'] = array(
//General
'General_settings_group' => '<i class="fa fa-gears"></i> General',
'ENABLE_ARPSCAN_name' => 'Enable ARP scan',
'ENABLE_ARPSCAN_description' => 'Arp-scan is a command-line tool that uses the ARP protocol to discover and fingerprint IP hosts on the local network. An alternative to ARP scan is to enable the <a onclick="toggleAllSettings()" href="#PIHOLE_ACTIVE"><code>PIHOLE_ACTIVE</code>PiHole integration settings</a>.',
'SCAN_SUBNETS_name' => 'Subnets to scan',
'SCAN_SUBNETS_description' => '
The arp-scan time itself depends on the number of IP addresses to check.
The number of IPs to check depends on the <a target="_blank" href="https://www.calculator.net/ip-subnet-calculator.html">network mask</a> you set here.
For example, a <code>/24</code> mask results in 256 IPs to check, where as a <code>/16</code>
@@ -489,12 +511,13 @@ the arp-scan will take hours to complete instead of seconds.
'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>.',
//Email
'Email_settings_group' => '<i class="fa fa-at"></i> Email',
'REPORT_MAIL_name' => 'Enable email',
'REPORT_MAIL_description' => 'If enabled an email is sent out with a list of changes you\'ve subscribed to. Please also fill out all remaining settings related to the SMTP setup below.',
'SMTP_SERVER_name' => 'SMTP server URL',
'SMTP_SERVER_description' => 'The SMTP server host URL. For example <code>smtp-relay.sendinblue.com</code>.',
'SMTP_SERVER_description' => 'The SMTP server host URL. For example <code>smtp-relay.sendinblue.com</code>. I don\'t recommend using Gmail as an SMTP server as the setup is <a target="_blank" href="https://support.google.com/a/answer/176600">quite complex</a> (I couldn\'t get it to work - Please reach out with a guide if you did)',
'SMTP_PORT_name' => 'SMTP server PORT',
'SMTP_PORT_description' => 'Port number used for the SMTP connection.',
'SMTP_PORT_description' => 'Port number used for the SMTP connection. Set to <code>0</code> if you don\'t want to use a port when connecting to the SMTP server.',
'SMTP_SKIP_LOGIN_name' => 'Skip authentication',
'SMTP_SKIP_LOGIN_description' => 'Don\'t use authentication when connecting to the SMTP server.',
'SMTP_USER_name' => 'SMTP user',
@@ -503,12 +526,15 @@ the arp-scan will take hours to complete instead of seconds.
'SMTP_PASS_description' => 'The SMTP server password. ',
'SMTP_SKIP_TLS_name' => 'Don\'t use TLS',
'SMTP_SKIP_TLS_description' => 'Disable TLS when connecting to your SMTP server.',
'SMTP_FORCE_SSL_name' => 'Force SSL',
'SMTP_FORCE_SSL_description' => 'Force SSL when connecting to your SMTP server.',
'REPORT_TO_name' => 'Send email to',
'REPORT_TO_description' => 'Email address to which the notification will be send to.',
'REPORT_FROM_name' => 'Email subject',
'REPORT_FROM_description' => 'Notification email subject line.',
//Webhooks
'Webhooks_settings_group' => '<i class="fa fa-circle-nodes"></i> Webhooks',
'REPORT_WEBHOOK_name' => 'Enable Webhooks',
'REPORT_WEBHOOK_description' => 'Enable webhooks for notifications. Webhooks help you to connect to a lot of 3rd party tools, such as IFTTT, Zapier or <a href="https://n8n.io/" target="_blank">n8n</a> to name a few. Check out this simple <a href="https://github.com/jokob-sk/Pi.Alert/blob/main/docs/WEBHOOK_N8N.md" target="_blank">n8n guide here</a> to get started. If enabled, configure related settings below.',
'WEBHOOK_URL_name' => 'Target URL',
@@ -519,6 +545,7 @@ the arp-scan will take hours to complete instead of seconds.
'WEBHOOK_REQUEST_METHOD_description' => 'The HTTP request method to be used for the webhook call.',
// Apprise
'Apprise_settings_group' => '<i class="fa fa-bullhorn"></i> Apprise',
'REPORT_APPRISE_name' => 'Enable Apprise',
'REPORT_APPRISE_description' => 'Enable sending notifications via <a target="_blank" href="https://hub.docker.com/r/caronc/apprise">Apprise</a>.',
'APPRISE_HOST_name' => 'Apprise host URL',
@@ -527,6 +554,7 @@ the arp-scan will take hours to complete instead of seconds.
'APPRISE_URL_description' => 'Apprise notification target URL.',
// NTFY
'NTFY_settings_group' => '<i class="fa fa-terminal"></i> NTFY',
'REPORT_NTFY_name' => 'Enable NTFY',
'REPORT_NTFY_description' => 'Enable sending notifications via <a target="_blank" href="https://ntfy.sh/">NTFY</a>.',
'NTFY_HOST_name' => 'NTFY host URL',
@@ -539,6 +567,7 @@ the arp-scan will take hours to complete instead of seconds.
'NTFY_PASSWORD_description' => 'Enter password if you need (host) an instance with enabled authetication.',
// Pushsafer
'PUSHSAFER_settings_group' => '<i class="fa fa-bell"></i> Pushsafer',
'REPORT_PUSHSAFER_name' => 'Enable Pushsafer',
'REPORT_PUSHSAFER_description' => 'Enable sending notifications via <a target="_blank" href="https://www.pushsafer.com/">Pushsafer</a>.',
'PUSHSAFER_TOKEN_name' => 'Pushsafer token',
@@ -546,6 +575,7 @@ the arp-scan will take hours to complete instead of seconds.
// MQTT
'MQTT_settings_group' => '<i class="fa fa-square-rss"></i> MQTT',
'REPORT_MQTT_name' => 'Enable MQTT',
'REPORT_MQTT_description' => 'Enable sending notifications via <a target="_blank" href="https://www.home-assistant.io/integrations/mqtt/">MQTT</a> to your Home Assistance instance.',
'MQTT_BROKER_name' => 'MQTT broker URL',
@@ -562,6 +592,7 @@ the arp-scan will take hours to complete instead of seconds.
'MQTT_DELAY_SEC_description' => 'A little hack - delay adding to the queue in case the process is restarted and previous publish processes aborted (it takes ~<code>2</code>s to update a sensor config on the broker). Tested with <code>2</code>-<code>3</code> seconds of delay. This delay is only applied when devices are created (during the first notification loop). It doesn\'t affect subsequent scans or notifications.',
//DynDNS
'DynDNS_settings_group' => '<i class="fa fa-globe"></i> DynDNS',
'DDNS_ACTIVE_name' => 'Enable DynDNS',
'DDNS_ACTIVE_description' => '',
'DDNS_DOMAIN_name' => 'DynDNS domain URL',
@@ -574,12 +605,14 @@ the arp-scan will take hours to complete instead of seconds.
'DDNS_UPDATE_URL_description' => 'Update URL starting with <code>http://</code> or <code>https://</code>.',
// PiHole
'PiHole_settings_group' => '<i class="fa fa-seedling"></i> PiHole',
'PIHOLE_ACTIVE_name' => 'Enable PiHole mapping',
'PIHOLE_ACTIVE_description' => 'You need to map<code>:/etc/pihole/pihole-FTL.db</code> in the <code>docker-compose.yml</code> file if you enable this setting.',
'DHCP_ACTIVE_name' => 'Enable PiHole DHCP',
'DHCP_ACTIVE_description' => 'You need to map <code>:/etc/pihole/dhcp.leases</code> in the <code>docker-compose.yml</code> file if you enable this setting.',
// Pholus
'Pholus_settings_group' => '<i class="fa fa-search"></i> Pholus',
'PHOLUS_ACTIVE_name' => 'Cycle run',
'PHOLUS_ACTIVE_description' => '<a href="https://github.com/jokob-sk/Pi.Alert/tree/main/pholus" target="_blank" >Pholus</a> is a sniffing tool to discover additional information about the devices on the network, including the device name. If enabled this will execute the scan before every network scan cycle until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Please be aware it can spam the network with unnecessary traffic. Depends on the <a onclick="toggleAllSettings()" href="#SCAN_SUBNETS"><code>SCAN_SUBNETS</code> setting</a>. For a scheduled or one-off scan, check the <a href="#PHOLUS_RUN"><code>PHOLUS_RUN</code> setting</a>.',
'PHOLUS_TIMEOUT_name' => 'Cycle run timeout',
@@ -597,6 +630,7 @@ the arp-scan will take hours to complete instead of seconds.
'PHOLUS_DAYS_DATA_description' => 'How many days of Pholus scan entries should be kept (globally, not device specific!). The <a href="/maintenance.php#tab_Logging">pialert_pholus.log</a> file is not touched. Enter <code>0</code> to disable.',
// Nmap
'Nmap_settings_group' => '<i class="fa fa-ethernet"></i> Nmap',
'NMAP_ACTIVE_name' => 'Cycle run',
'NMAP_ACTIVE_description' => 'If enabled this will execute a scan on a newly found device. For a scheduled or one-off scan, check the <a href="#NMAP_RUN"><code>NMAP_RUN</code> setting</a>.',
'NMAP_TIMEOUT_name' => 'Run timeout',

1
front/php/templates/language/lang.php Normal file → Executable file
View File

@@ -14,6 +14,7 @@ if(!isset($_COOKIE["language"])) {
if (isset($pia_lang_selected) == FALSE or (strlen($pia_lang_selected) == 0)) {$pia_lang_selected = defaultLang;}
require '/home/pi/pialert/front/php/templates/skinUI.php';
require 'en_us.php';
require 'de_de.php';
require 'es_es.php';

0
front/php/templates/security.php Normal file → Executable file
View File

9
front/php/templates/skinUI.php Normal file → Executable file
View File

@@ -4,9 +4,14 @@
// ## GUI settings processing start
// ###################################
if (file_exists('/home/pi/pialert/db/setting_darkmode')) {
$ENABLED_DARKMODE = True;
if( isset($_COOKIE['Front_Dark_Mode_Enabled']))
{
$ENABLED_DARKMODE = $_COOKIE['Front_Dark_Mode_Enabled'] == "true";
}else
{
$ENABLED_DARKMODE = False;
}
foreach (glob("/home/pi/pialert/db/setting_skin*") as $filename) {
$pia_skin_selected = str_replace('setting_','',basename($filename));
}

0
front/php/templates/timezone.php Normal file → Executable file
View File

13
front/settings.php Normal file → Executable file
View File

@@ -40,11 +40,10 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
);
}
CommitDB();
?>
<!-- Page ------------------------------------------------------------------ -->
<div class="content-wrapper">
<div id="settingsPage" class="content-wrapper">
<!-- Content header--------------------------------------------------------- -->
<section class="content-header">
@@ -79,7 +78,7 @@ CommitDB();
$html = $html.'<div class=" box panel panel-default">
<a data-toggle="collapse" data-parent="#accordion_gen" href="#'.$group.'">
<div class="panel-heading">
<h4 class="panel-title">'.$group.'</h4>
<h4 class="panel-title">'.lang($group.'_settings_group').'</h4>
</div>
</a>
<div id="'.$group.'" data-myid="collapsible" class="panel-collapse collapse '.$isIn.'">
@@ -286,7 +285,7 @@ CommitDB();
<script>
// number of settings has to be equal to
var settingsNumber = 60;
var settingsNumber = 61;
// Wrong number of settings processing
if(<?php echo count($settings)?> != settingsNumber)
@@ -375,9 +374,7 @@ CommitDB();
method: "POST",
url: "../php/server/util.php",
data: { function: 'savesettings', settings: collectSettings() },
success: function(data, textStatus) {
// $("#result").html(data);
// console.log(data);
success: function(data, textStatus) {
showModalOk ('Result', data );
// Remove navigation prompt "Are you sure you want to leave..."
window.onbeforeunload = null;
@@ -397,7 +394,7 @@ CommitDB();
}
// get parameter value
$.get('php/server/parameters.php?action=get&parameter='+ key + skipCacheQuery, function(data) {
$.get('php/server/parameters.php?action=get&defaultValue=0&parameter='+ key + skipCacheQuery, function(data) {
var result = data;

0
pholus/README.md Normal file → Executable file
View File

0
pholus/licence.txt Normal file → Executable file
View File

0
pholus/pholus.py Normal file → Executable file
View File

0
pholus/pholus3.py Normal file → Executable file
View File