Compare commits
80 Commits
v24.10.31
...
a0508f2db9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0508f2db9 | ||
|
|
72942cb0d1 | ||
|
|
ca87a56549 | ||
|
|
84c5fdae43 | ||
|
|
39473593c2 | ||
|
|
bc8e845385 | ||
|
|
1eee710040 | ||
|
|
948635433a | ||
|
|
302ab4b1d8 | ||
|
|
7538b17695 | ||
|
|
55881249e2 | ||
|
|
1b404e579a | ||
|
|
ff9be75871 | ||
|
|
b3d256339f | ||
|
|
0c4c8ca5c3 | ||
|
|
69d41f2ed4 | ||
|
|
76d1ec46a6 | ||
|
|
5aae841b82 | ||
|
|
87ee8efe36 | ||
|
|
404c5cc34b | ||
|
|
6d8dcc7a22 | ||
|
|
e6b82c14ff | ||
|
|
410becfe21 | ||
|
|
202baab409 | ||
|
|
31121eab2a | ||
|
|
78fc9214bb | ||
|
|
52632bc8ef | ||
|
|
6407ee5c13 | ||
|
|
ab8b07e614 | ||
|
|
81d3ee4af7 | ||
|
|
4e90a82ea4 | ||
|
|
70e0542488 | ||
|
|
8b1830569b | ||
|
|
60492157d1 | ||
|
|
44b18e131c | ||
|
|
7512d31e1b | ||
|
|
815480513c | ||
|
|
d1f3998fbf | ||
|
|
7fae6a8cce | ||
|
|
c1c6813b6e | ||
|
|
66786d1d42 | ||
|
|
072821181a | ||
|
|
359360a5ea | ||
|
|
f007eac656 | ||
|
|
5bed1172b6 | ||
|
|
76d1805439 | ||
|
|
34db6fec6c | ||
|
|
4f082b223d | ||
|
|
cc8cddb039 | ||
|
|
79fe759470 | ||
|
|
39bf09c24c | ||
|
|
60777b2f82 | ||
|
|
f4928e3895 | ||
|
|
bf9f55355e | ||
|
|
0bc8b39cec | ||
|
|
cf6c6a3510 | ||
|
|
ad359a5a4d | ||
|
|
2663fbce0f | ||
|
|
70a771e687 | ||
|
|
3cf3305b8f | ||
|
|
775e46529d | ||
|
|
adf2ac3341 | ||
|
|
f426d7b960 | ||
|
|
dd3229284c | ||
|
|
106ec07f3b | ||
|
|
4fb1a55ac0 | ||
|
|
03239cd2b0 | ||
|
|
6523932a87 | ||
|
|
73e27a3883 | ||
|
|
827fdd1504 | ||
|
|
1f01bae1fd | ||
|
|
37a39e23df | ||
|
|
7ce0215a56 | ||
|
|
70be053bd2 | ||
|
|
ab0e99d870 | ||
|
|
2b9f009e8b | ||
|
|
580c5ae36a | ||
|
|
08644feac3 | ||
|
|
d4b5672081 | ||
|
|
1378c8707d |
10
.github/ISSUE_TEMPLATE/i-have-an-issue.yml
vendored
@@ -9,6 +9,16 @@ body:
|
||||
options:
|
||||
- label: I have searched the existing open and closed issues and I checked the docs https://github.com/jokob-sk/NetAlertX/tree/main/docs
|
||||
required: true
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: The issue occurs in the following browsers. Select at least 2.
|
||||
description: This step helps me understand if this is a cache or browser-specific issue.
|
||||
options:
|
||||
- label: "Firefox"
|
||||
- label: "Chrome"
|
||||
- label: "Edge"
|
||||
- label: "Safari (unsupported) - PRs welcome"
|
||||
- label: "N/A - This is an issue with the backend"
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Current Behavior
|
||||
|
||||
@@ -15,7 +15,7 @@ ENV PATH="/opt/venv/bin:$PATH"
|
||||
COPY . ${INSTALL_DIR}/
|
||||
|
||||
|
||||
RUN pip install netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros \
|
||||
RUN pip install graphene flask netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros \
|
||||
&& bash -c "find ${INSTALL_DIR} -type d -exec chmod 750 {} \;" \
|
||||
&& bash -c "find ${INSTALL_DIR} -type f -exec chmod 640 {} \;" \
|
||||
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
|
||||
|
||||
@@ -95,7 +95,6 @@ Thank you to all the wonderful people who are sponsoring this project.
|
||||
<!-- SPONSORS-LIST DO NOT MODIFY BELOW -->
|
||||
| All Sponsors |
|
||||
|---|
|
||||
| [joel72265](https://github.com/joel72265) |
|
||||
|
||||
<!-- SPONSORS-LIST DO NOT MODIFY ABOVE -->
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ services:
|
||||
- ${APP_DATA_LOCATION}/netalertx/dhcp_samples/pihole_dhcp_2.leases:/etc/pihole/dhcp2.leases
|
||||
- ${APP_DATA_LOCATION}/pihole/etc-pihole/pihole-FTL.db:/etc/pihole/pihole-FTL.db
|
||||
- ${DEV_LOCATION}/server:/app/server
|
||||
- ${DEV_LOCATION}/test:/app/test
|
||||
- ${DEV_LOCATION}/dockerfiles:/app/dockerfiles
|
||||
# - ${APP_DATA_LOCATION}/netalertx/php.ini:/etc/php/8.2/fpm/php.ini
|
||||
- ${DEV_LOCATION}/install:/app/install
|
||||
|
||||
@@ -44,6 +44,8 @@ docker run -d --rm --network=host \
|
||||
|`APP_CONF_OVERRIDE` | JSON override for settings, e.g. `{"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_theme":"Dark"}` (Experimental 🧪) | `N/A` |
|
||||
|`ALWAYS_FRESH_INSTALL` | If `true` will delete the content of the `/db` & `/config` folders. For testing purposes. Can be coupled with [watchtower](https://github.com/containrrr/watchtower) to have an always freshly installed `netalertx`/`netalertx-dev` image. | `N/A` |
|
||||
|
||||
> You can override the default GraphQL port setting `GRAPHQL_PORT` (set to `20212`) by using the `APP_CONF_OVERRIDE` env variable.
|
||||
|
||||
### Docker paths
|
||||
|
||||
> [!NOTE]
|
||||
|
||||
60
docs/API.md
@@ -58,38 +58,38 @@ Example JSON of the `table_devices.json` endpoint with two Devices (database row
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"dev_MAC": "Internet",
|
||||
"dev_Name": "Net - Huawei",
|
||||
"dev_DeviceType": "Router",
|
||||
"dev_Vendor": null,
|
||||
"dev_Group": "Always on",
|
||||
"dev_FirstConnection": "2021-01-01 00:00:00",
|
||||
"dev_LastConnection": "2021-01-28 22:22:11",
|
||||
"dev_LastIP": "192.168.1.24",
|
||||
"dev_StaticIP": 0,
|
||||
"dev_PresentLastScan": 1,
|
||||
"dev_LastNotification": "2023-01-28 22:22:28.998715",
|
||||
"dev_NewDevice": 0,
|
||||
"dev_Network_Node_MAC_ADDR": "",
|
||||
"dev_Network_Node_port": "",
|
||||
"dev_Icon": "globe"
|
||||
"devMac": "Internet",
|
||||
"devName": "Net - Huawei",
|
||||
"devType": "Router",
|
||||
"devVendor": null,
|
||||
"devGroup": "Always on",
|
||||
"devFirstConnection": "2021-01-01 00:00:00",
|
||||
"devLastConnection": "2021-01-28 22:22:11",
|
||||
"devLastIP": "192.168.1.24",
|
||||
"devStaticIP": 0,
|
||||
"devPresentLastScan": 1,
|
||||
"devLastNotification": "2023-01-28 22:22:28.998715",
|
||||
"devIsNew": 0,
|
||||
"devParentMAC": "",
|
||||
"devParentPort": "",
|
||||
"devIcon": "globe"
|
||||
},
|
||||
{
|
||||
"dev_MAC": "a4:8f:ff:aa:ba:1f",
|
||||
"dev_Name": "Net - USG",
|
||||
"dev_DeviceType": "Firewall",
|
||||
"dev_Vendor": "Ubiquiti Inc",
|
||||
"dev_Group": "",
|
||||
"dev_FirstConnection": "2021-02-12 22:05:00",
|
||||
"dev_LastConnection": "2021-07-17 15:40:00",
|
||||
"dev_LastIP": "192.168.1.1",
|
||||
"dev_StaticIP": 1,
|
||||
"dev_PresentLastScan": 1,
|
||||
"dev_LastNotification": "2021-07-17 15:40:10.667717",
|
||||
"dev_NewDevice": 0,
|
||||
"dev_Network_Node_MAC_ADDR": "Internet",
|
||||
"dev_Network_Node_port": 1,
|
||||
"dev_Icon": "shield-halved"
|
||||
"devMac": "a4:8f:ff:aa:ba:1f",
|
||||
"devName": "Net - USG",
|
||||
"devType": "Firewall",
|
||||
"devVendor": "Ubiquiti Inc",
|
||||
"devGroup": "",
|
||||
"devFirstConnection": "2021-02-12 22:05:00",
|
||||
"devLastConnection": "2021-07-17 15:40:00",
|
||||
"devLastIP": "192.168.1.1",
|
||||
"devStaticIP": 1,
|
||||
"devPresentLastScan": 1,
|
||||
"devLastNotification": "2021-07-17 15:40:10.667717",
|
||||
"devIsNew": 0,
|
||||
"devParentMAC": "Internet",
|
||||
"devParentPort": 1,
|
||||
"devIcon": "shield-halved"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ To download and install NetAlertX on the hardware/server directly use the `curl`
|
||||
> [!NOTE]
|
||||
> This is an Experimental feature 🧪 and it relies on community support.
|
||||
>
|
||||
> Looking for maintainers for this installation method 🙂
|
||||
>
|
||||
> There is no guarantee that the install script or any other script will gracefully handle other installed software.
|
||||
> Data loss is a possibility, **it is recommended to install NetAlertX using the supplied Docker image**.
|
||||
|
||||
|
||||
@@ -170,20 +170,20 @@ This SQL query is executed on the `app.db` SQLite database file.
|
||||
> SQL query example:
|
||||
>
|
||||
> ```SQL
|
||||
> SELECT dv.dev_Name as Object_PrimaryID,
|
||||
> cast(dv.dev_LastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID,
|
||||
> SELECT dv.devName as Object_PrimaryID,
|
||||
> cast(dv.devLastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID,
|
||||
> datetime() as DateTime,
|
||||
> ns.Service as Watched_Value1,
|
||||
> ns.State as Watched_Value2,
|
||||
> 'null' as Watched_Value3,
|
||||
> 'null' as Watched_Value4,
|
||||
> ns.Extra as Extra,
|
||||
> dv.dev_MAC as ForeignKey
|
||||
> dv.devMac as ForeignKey
|
||||
> FROM
|
||||
> (SELECT * FROM Nmap_Scan) ns
|
||||
> LEFT JOIN
|
||||
> (SELECT dev_Name, dev_MAC, dev_LastIP FROM Devices) dv
|
||||
> ON ns.MAC = dv.dev_MAC
|
||||
> (SELECT devName, devMac, devLastIP FROM Devices) dv
|
||||
> ON ns.MAC = dv.devMac
|
||||
> ```
|
||||
>
|
||||
> Required `CMD` setting example with above query (you can set `"type": "label"` if you want it to make uneditable in the UI):
|
||||
@@ -192,7 +192,7 @@ This SQL query is executed on the `app.db` SQLite database file.
|
||||
> {
|
||||
> "function": "CMD",
|
||||
> "type": {"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]},
|
||||
> "default_value":"SELECT dv.dev_Name as Object_PrimaryID, cast(dv.dev_LastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, ns.Service as Watched_Value1, ns.State as Watched_Value2, 'null' as Watched_Value3, 'null' as Watched_Value4, ns.Extra as Extra FROM (SELECT * FROM Nmap_Scan) ns LEFT JOIN (SELECT dev_Name, dev_MAC, dev_LastIP FROM Devices) dv ON ns.MAC = dv.dev_MAC",
|
||||
> "default_value":"SELECT dv.devName as Object_PrimaryID, cast(dv.devLastIP as VARCHAR(100)) || ':' || cast( SUBSTR(ns.Port ,0, INSTR(ns.Port , '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, ns.Service as Watched_Value1, ns.State as Watched_Value2, 'null' as Watched_Value3, 'null' as Watched_Value4, ns.Extra as Extra FROM (SELECT * FROM Nmap_Scan) ns LEFT JOIN (SELECT devName, devMac, devLastIP FROM Devices) dv ON ns.MAC = dv.devMac",
|
||||
> "options": [],
|
||||
> "localized": ["name", "description"],
|
||||
> "name" : [{
|
||||
@@ -460,7 +460,7 @@ Below are some general additional notes, when defining `params`:
|
||||
|
||||
- `"name":"name_value"` - is used as a wildcard replacement in the `CMD` setting value by using curly brackets `{name_value}`. The wildcard is replaced by the result of the `"value" : "param_value"` and `"type":"type_value"` combo configuration below.
|
||||
- `"type":"<sql|setting>"` - is used to specify the type of the params, currently only 2 supported (`sql`,`setting`).
|
||||
- `"type":"sql"` - will execute the SQL query specified in the `value` property. The sql query needs to return only one column. The column is flattened and separated by commas (`,`), e.g: `SELECT dev_MAC from DEVICES` -> `Internet,74:ac:74:ac:74:ac,44:44:74:ac:74:ac`. This is then used to replace the wildcards in the `CMD` setting.
|
||||
- `"type":"sql"` - will execute the SQL query specified in the `value` property. The sql query needs to return only one column. The column is flattened and separated by commas (`,`), e.g: `SELECT devMac from DEVICES` -> `Internet,74:ac:74:ac:74:ac,44:44:74:ac:74:ac`. This is then used to replace the wildcards in the `CMD` setting.
|
||||
- `"type":"setting"` - The setting code name. A combination of the value from `unique_prefix` + `_` + `function` value, or otherwise the code name you can find in the Settings page under the Setting display name, e.g. `PIHOLE_RUN`.
|
||||
- `"value": "param_value"` - Needs to contain a setting code name or SQL query without wildcards.
|
||||
- `"timeoutMultiplier" : true` - used to indicate if the value should multiply the max timeout for the whole script run by the number of values in the given parameter.
|
||||
@@ -474,13 +474,13 @@ Below are some general additional notes, when defining `params`:
|
||||
> "params" : [{
|
||||
> "name" : "ips",
|
||||
> "type" : "sql",
|
||||
> "value" : "SELECT dev_LastIP from DEVICES",
|
||||
> "value" : "SELECT devLastIP from DEVICES",
|
||||
> "timeoutMultiplier" : true
|
||||
> },
|
||||
> {
|
||||
> "name" : "macs",
|
||||
> "type" : "sql",
|
||||
> "value" : "SELECT dev_MAC from DEVICES"
|
||||
> "value" : "SELECT devMac from DEVICES"
|
||||
> },
|
||||
> {
|
||||
> "name" : "timeout",
|
||||
@@ -527,7 +527,7 @@ The UI component is defined as a JSON object containing a list of `elements`. Ea
|
||||
|
||||
```json
|
||||
{
|
||||
"function": "dev_Icon",
|
||||
"function": "devIcon",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -536,7 +536,7 @@ The UI component is defined as a JSON object containing a list of `elements`. Ea
|
||||
"elementOptions": [
|
||||
{ "cssClasses": "input-group-addon iconPreview" },
|
||||
{ "getStringKey": "Gen_SelectToPreview" },
|
||||
{ "customId": "NEWDEV_dev_Icon_preview" }
|
||||
{ "customId": "NEWDEV_devIcon_preview" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
@@ -548,7 +548,7 @@ The UI component is defined as a JSON object containing a list of `elements`. Ea
|
||||
{
|
||||
"onChange": "updateIconPreview(this)"
|
||||
},
|
||||
{ "customParams": "NEWDEV_dev_Icon,NEWDEV_dev_Icon_preview" }
|
||||
{ "customParams": "NEWDEV_devIcon,NEWDEV_devIcon_preview" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
@@ -649,7 +649,7 @@ The UI will adjust how columns are displayed in the UI based on the resolvers de
|
||||
| See below for information on `threshold`, `replace`. | |
|
||||
| | |
|
||||
| `options` Property | Used in conjunction with types like `threshold`, `replace`, `regex`. |
|
||||
| `options_params` Property | Used in conjunction with a `"options": "[{value}]"` template and `text.select`/`list.select`. Can specify SQL query (needs to return 2 columns `SELECT dev_Name as name, dev_Mac as id`) or Setting (not tested) to populate the dropdown. Check example below or have a look at the `NEWDEV` plugin `config.json` file. |
|
||||
| `options_params` Property | Used in conjunction with a `"options": "[{value}]"` template and `text.select`/`list.select`. Can specify SQL query (needs to return 2 columns `SELECT devName as name, devMac as id`) or Setting (not tested) to populate the dropdown. Check example below or have a look at the `NEWDEV` plugin `config.json` file. |
|
||||
| `threshold` | The `options` array contains objects ordered from the lowest `maximum` to the highest. The corresponding `hexColor` is used for the value background color if it's less than the specified `maximum` but more than the previous one in the `options` array. |
|
||||
| `replace` | The `options` array contains objects with an `equals` property, which is compared to the "value." If the values are the same, the string in `replacement` is displayed in the UI instead of the actual "value". |
|
||||
| `regex` | Applies a regex to the value. The `options` array contains objects with an `type` (must be set to `regex`) and `param` (must contain the regex itself) property. |
|
||||
@@ -669,7 +669,7 @@ The UI will adjust how columns are displayed in the UI based on the resolvers de
|
||||
|
||||
|
||||
```json
|
||||
"function": "dev_DeviceType",
|
||||
"function": "devType",
|
||||
"type": {"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]},
|
||||
"maxLength": 30,
|
||||
"default_value": "",
|
||||
@@ -678,7 +678,7 @@ The UI will adjust how columns are displayed in the UI based on the resolvers de
|
||||
{
|
||||
"name" : "value",
|
||||
"type" : "sql",
|
||||
"value" : "SELECT '' as id, '' as name UNION SELECT dev_DeviceType as id, dev_DeviceType as name FROM (SELECT dev_DeviceType FROM Devices UNION SELECT 'Smartphone' UNION SELECT 'Tablet' UNION SELECT 'Laptop' UNION SELECT 'PC' UNION SELECT 'Printer' UNION SELECT 'Server' UNION SELECT 'NAS' UNION SELECT 'Domotic' UNION SELECT 'Game Console' UNION SELECT 'SmartTV' UNION SELECT 'Clock' UNION SELECT 'House Appliance' UNION SELECT 'Phone' UNION SELECT 'AP' UNION SELECT 'Gateway' UNION SELECT 'Firewall' UNION SELECT 'Switch' UNION SELECT 'WLAN' UNION SELECT 'Router' UNION SELECT 'Other') AS all_devices ORDER BY id;"
|
||||
"value" : "SELECT '' as id, '' as name UNION SELECT devType as id, devType as name FROM (SELECT devType FROM Devices UNION SELECT 'Smartphone' UNION SELECT 'Tablet' UNION SELECT 'Laptop' UNION SELECT 'PC' UNION SELECT 'Printer' UNION SELECT 'Server' UNION SELECT 'NAS' UNION SELECT 'Domotic' UNION SELECT 'Game Console' UNION SELECT 'SmartTV' UNION SELECT 'Clock' UNION SELECT 'House Appliance' UNION SELECT 'Phone' UNION SELECT 'AP' UNION SELECT 'Gateway' UNION SELECT 'Firewall' UNION SELECT 'Switch' UNION SELECT 'WLAN' UNION SELECT 'Router' UNION SELECT 'Other') AS all_devices ORDER BY id;"
|
||||
},
|
||||
{
|
||||
"name" : "uilang",
|
||||
|
||||
@@ -27,6 +27,7 @@ There is also an in-app Help / FAQ section that should be answering frequently a
|
||||
|
||||
#### 📥 Initial Setup
|
||||
|
||||
- [Synology Guide](/docs/SYNOLOGY_GUIDE.md)
|
||||
- [Subnets and VLANs configuration for arp-scan](/docs/SUBNETS.md)
|
||||
- [SMTP server config](/docs/SMTP.md)
|
||||
- [Custom Icon configuration and support](/docs/ICONS.md)
|
||||
@@ -64,6 +65,7 @@ There is also an in-app Help / FAQ section that should be answering frequently a
|
||||
|
||||
- [Version history (legacy)](/docs/VERSIONS_HISTORY.md)
|
||||
- [Reverse proxy (Nginx, Apache, SWAG)](/docs/REVERSE_PROXY.md)
|
||||
- [Installing Updates](/docs/UPDATES.md)
|
||||
- [Setting up Authelia](/docs/AUTHELIA.md) (DRAFT)
|
||||
|
||||
#### 👩💻For Developers👨💻
|
||||
|
||||
74
docs/SYNOLOGY_GUIDE.md
Executable file
@@ -0,0 +1,74 @@
|
||||
# Installation on a Synology NAS
|
||||
|
||||
There are different ways to install NetAlertX on a Synology, including SSH-ing into the machine and using the command line. For this guide, we will use the Project option in Container manager.
|
||||
|
||||
## Create the folder structure
|
||||
|
||||
The folders you are creating below will contain the configuration and the database. Back them up regularly.
|
||||
|
||||
1. Create a parent folder named `netalertx`
|
||||
2. Create a `db` sub-folder
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
3. Create a `config` sub-folder
|
||||
|
||||

|
||||
|
||||
4. Note down the folders Locations:
|
||||
|
||||

|
||||

|
||||
|
||||
5. Open **Container manager** -> **Project** and click **Create**.
|
||||
6. Fill in the details:
|
||||
|
||||
- Project name: `netalertx`
|
||||
- Path: `/app_storage/netalertx` (will differ from yours)
|
||||
- Paste in the following template:
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
netalertx:
|
||||
container_name: netalertx
|
||||
# use the below line if you want to test the latest dev image
|
||||
# image: "jokobsk/netalertx-dev:latest"
|
||||
image: "jokobsk/netalertx:latest"
|
||||
network_mode: "host"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- local/path/config:/app/config
|
||||
- local/path/db:/app/db
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
- local/path/logs:/app/front/log
|
||||
environment:
|
||||
- TZ=Europe/Berlin
|
||||
- PORT=20211
|
||||
```
|
||||
|
||||

|
||||
|
||||
7. Replace the paths to your volume and/or comment out unnecessary line(s):
|
||||
|
||||
- This is only an example, your paths will differ.
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- /volume1/app_storage/netalertx/config:/app/config
|
||||
- /volume1/app_storage/netalertx/db:/app/db
|
||||
# (optional) useful for debugging if you have issues setting up the container
|
||||
# - local/path/logs:/app/front/log <- commented out with # ⚠
|
||||
```
|
||||
|
||||

|
||||
|
||||
8. (optional) Change the port number from `20211` to an unused port if this port is already used.
|
||||
9. Build the project:
|
||||
|
||||

|
||||
|
||||
10. Navigate to `<Synology URL>:20211` (or your custom port).
|
||||
11. Read the [Subnets](/docs/SUBNETS.md) and [Plugins](/front/plugins/README.md) docs to complete your setup.
|
||||
110
docs/UPDATES.md
Executable file
@@ -0,0 +1,110 @@
|
||||
# Docker Update Strategies for NetAlertX
|
||||
|
||||
This guide outlines several approaches for updating Docker containers, specifically using NetAlertX. Each method offers different benefits depending on the situation. Here are the methods:
|
||||
|
||||
- Manual: Direct commands to stop, remove, and rebuild containers.
|
||||
- Dockcheck: Semi-automated with more control, suited for bulk updates.
|
||||
- Watchtower: Fully automated, runs continuously to check and update containers.
|
||||
|
||||
You can choose any approach that fits your workflow.
|
||||
|
||||
> In the examples I assume that the container name is `netalertx` and the image name is `netalertx` as well.
|
||||
|
||||
## 1. Manual Updates
|
||||
|
||||
Use this method when you need precise control over a single container or when dealing with a broken container that needs immediate attention.
|
||||
Example Commands
|
||||
|
||||
To manually update the `netalertx` container, stop it, delete it, remove the old image, and start a fresh one with `docker-compose`.
|
||||
|
||||
```bash
|
||||
# Stop the container
|
||||
sudo docker container stop netalertx
|
||||
|
||||
# Remove the container
|
||||
sudo docker container rm netalertx
|
||||
|
||||
# Remove the old image
|
||||
sudo docker image rm netalertx
|
||||
|
||||
# Pull and start a new container
|
||||
sudo docker-compose up -d
|
||||
```
|
||||
|
||||
### Alternative: Force Pull with Docker Compose
|
||||
|
||||
You can also use `--pull always` to ensure Docker pulls the latest image before starting the container:
|
||||
|
||||
```bash
|
||||
sudo docker-compose up --pull always -d
|
||||
```
|
||||
|
||||
## 2. Dockcheck for Bulk Container Updates
|
||||
|
||||
Always check the [Dockcheck](https://github.com/mag37/dockcheck) docs if encountering issues with the guide below.
|
||||
|
||||
Dockcheck is a useful tool if you have multiple containers to update and some flexibility for handling potential issues that might arise during mass updates. Dockcheck allows you to inspect each container and decide when to update.
|
||||
|
||||
### Example Workflow with Dockcheck
|
||||
|
||||
You might use Dockcheck to:
|
||||
|
||||
- Inspect container versions.
|
||||
- Pull the latest images in bulk.
|
||||
- Apply updates selectively.
|
||||
|
||||
Dockcheck can help streamline bulk updates, especially if you’re managing multiple containers.
|
||||
|
||||
Below is a script I use to run an update of the Dockcheck script and start a check for new containers:
|
||||
|
||||
```bash
|
||||
cd /path/to/Docker &&
|
||||
rm dockcheck.sh &&
|
||||
wget https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh &&
|
||||
sudo chmod +x dockcheck.sh &&
|
||||
sudo ./dockcheck.sh
|
||||
```
|
||||
|
||||
## 3. Automated Updates with Watchtower
|
||||
|
||||
Always check the [watchtower](https://github.com/containrrr/watchtower) docs if encountering issues with the guide below.
|
||||
|
||||
Watchtower monitors your Docker containers and automatically updates them when new images are available. This is ideal for ongoing updates without manual intervention.
|
||||
|
||||
### Setting Up Watchtower
|
||||
|
||||
#### 1. Pull the Watchtower Image:
|
||||
|
||||
```bash
|
||||
docker pull containrrr/watchtower
|
||||
```
|
||||
|
||||
#### 2. Run Watchtower to update all images:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name watchtower \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
containrrr/watchtower \
|
||||
--interval 300 # Check for updates every 5 minutes
|
||||
```
|
||||
|
||||
#### 3. Run Watchtower to update only NetAlertX:
|
||||
|
||||
You can specify which containers to monitor by listing them. For example, to monitor netalertx only:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name watchtower \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
containrrr/watchtower netalertx
|
||||
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
- Manual: Ideal for individual or critical updates.
|
||||
- Dockcheck: Suitable for controlled, mass updates.
|
||||
- Watchtower: Fully automated, best for continuous deployment setups.
|
||||
|
||||
These approaches allow you to maintain flexibility in how you update Docker containers, depending on the urgency and scale of the update.
|
||||
BIN
docs/img/SYNOLOGY/01_Create_folder_structure.png
Executable file
|
After Width: | Height: | Size: 23 KiB |
BIN
docs/img/SYNOLOGY/02_Create_folder_structure_db.png
Executable file
|
After Width: | Height: | Size: 24 KiB |
BIN
docs/img/SYNOLOGY/03_Create_folder_structure_db.png
Executable file
|
After Width: | Height: | Size: 28 KiB |
BIN
docs/img/SYNOLOGY/04_Create_folder_structure_config.png
Executable file
|
After Width: | Height: | Size: 31 KiB |
BIN
docs/img/SYNOLOGY/05_Access_folder_properties.png
Executable file
|
After Width: | Height: | Size: 42 KiB |
BIN
docs/img/SYNOLOGY/06_Note_location.png
Executable file
|
After Width: | Height: | Size: 48 KiB |
BIN
docs/img/SYNOLOGY/07_Create_project.png
Executable file
|
After Width: | Height: | Size: 26 KiB |
BIN
docs/img/SYNOLOGY/08_Adjust_docker_compose_volumes.png
Executable file
|
After Width: | Height: | Size: 11 KiB |
BIN
docs/img/SYNOLOGY/09_Run_and_build.png
Executable file
|
After Width: | Height: | Size: 15 KiB |
@@ -681,7 +681,7 @@ switch ($UI_THEME) {
|
||||
// Iterate through the data and filter only visible devices
|
||||
$.each(devicesList, function(index, item) {
|
||||
// Check if the current item's MAC exists in visibleDevicesMACs
|
||||
if (visibleDevicesMACs.includes(item.dev_MAC)) {
|
||||
if (visibleDevicesMACs.includes(item.devMac)) {
|
||||
devicesList_tmp.push(item);
|
||||
}
|
||||
});
|
||||
@@ -827,12 +827,12 @@ function initializeCombos () {
|
||||
// nameTransformer) // callback to transform name
|
||||
|
||||
|
||||
generateOptionsOrSetOptions("NEWDEV_dev_Icon", [], "dropdownIcon_tmp", genListWithInputSet, 'txtIcon', ["base64"])
|
||||
generateOptionsOrSetOptions("NEWDEV_dev_DeviceType", [], "dropdownDeviceType_tmp", genListWithInputSet, 'txtDeviceType' )
|
||||
generateOptionsOrSetOptions("NEWDEV_dev_Owner", [], "dropdownOwner_tmp", genListWithInputSet, 'txtOwner' )
|
||||
generateOptionsOrSetOptions("NEWDEV_dev_Group", [], "dropdownGroup_tmp", genListWithInputSet, 'txtGroup' )
|
||||
generateOptionsOrSetOptions("NEWDEV_dev_Location", [], "dropdownLocation_tmp", genListWithInputSet, 'txtLocation' )
|
||||
generateOptionsOrSetOptions("NEWDEV_dev_Network_Node_MAC_ADDR", [], "dropdownNetworkNodeMac_tmp", genListWithInputSet, 'txtNetworkNodeMac' )
|
||||
generateOptionsOrSetOptions("NEWDEV_devIcon", [], "dropdownIcon_tmp", genListWithInputSet, 'txtIcon', ["base64"])
|
||||
generateOptionsOrSetOptions("NEWDEV_devType", [], "dropdownDeviceType_tmp", genListWithInputSet, 'txtDeviceType' )
|
||||
generateOptionsOrSetOptions("NEWDEV_devOwner", [], "dropdownOwner_tmp", genListWithInputSet, 'txtOwner' )
|
||||
generateOptionsOrSetOptions("NEWDEV_devGroup", [], "dropdownGroup_tmp", genListWithInputSet, 'txtGroup' )
|
||||
generateOptionsOrSetOptions("NEWDEV_devLocation", [], "dropdownLocation_tmp", genListWithInputSet, 'txtLocation' )
|
||||
generateOptionsOrSetOptions("NEWDEV_devParentMAC", [], "dropdownNetworkNodeMac_tmp", genListWithInputSet, 'txtNetworkNodeMac' )
|
||||
|
||||
// Initialize static combos
|
||||
initializeComboSkipRepeated ();
|
||||
@@ -1171,7 +1171,7 @@ function getDeviceData (readAllData=false) {
|
||||
var deviceData = JSON.parse(data);
|
||||
|
||||
// check device exists
|
||||
if (deviceData['dev_MAC'] == null) {
|
||||
if (deviceData['devMac'] == null) {
|
||||
// Status
|
||||
$('#deviceStatus').html ('--');
|
||||
$('#deviceStatus')[0].className = 'text-gray';
|
||||
@@ -1227,16 +1227,16 @@ function getDeviceData (readAllData=false) {
|
||||
} else {
|
||||
|
||||
// Name
|
||||
if (deviceData['dev_Owner'] == null || deviceData['dev_Owner'] == '' ||
|
||||
(deviceData['dev_Name'].toString()).indexOf (deviceData['dev_Owner']) != -1 ) {
|
||||
$('#pageTitle').html (deviceData['dev_Name']);
|
||||
if (deviceData['devOwner'] == null || deviceData['devOwner'] == '' ||
|
||||
(deviceData['devName'].toString()).indexOf (deviceData['devOwner']) != -1 ) {
|
||||
$('#pageTitle').html (deviceData['devName']);
|
||||
} else {
|
||||
$('#pageTitle').html (deviceData['dev_Name'] + ' ('+ deviceData['dev_Owner'] +')');
|
||||
$('#pageTitle').html (deviceData['devName'] + ' ('+ deviceData['devOwner'] +')');
|
||||
}
|
||||
|
||||
// Status
|
||||
$('#deviceStatus').html (deviceData['dev_Status'].replace('-', ''));
|
||||
switch (deviceData['dev_Status']) {
|
||||
$('#deviceStatus').html (deviceData['devStatus'].replace('-', ''));
|
||||
switch (deviceData['devStatus']) {
|
||||
case 'On-line': icon='fa fa-check'; color='text-green'; break;
|
||||
case 'Off-line': icon='fa fa-close'; color='text-gray'; break;
|
||||
case 'Down': icon='fa fa-warning'; color='text-red'; break;
|
||||
@@ -1247,16 +1247,16 @@ function getDeviceData (readAllData=false) {
|
||||
$('#deviceStatusIcon')[0].className = icon +' '+ color;
|
||||
|
||||
// Totals
|
||||
$('#deviceSessions').html (deviceData['dev_Sessions'].toLocaleString());
|
||||
$('#deviceDownAlerts').html (deviceData['dev_DownAlerts'].toLocaleString());
|
||||
$('#deviceSessions').html (deviceData['devSessions'].toLocaleString());
|
||||
$('#deviceDownAlerts').html (deviceData['devDownAlerts'].toLocaleString());
|
||||
|
||||
// Presence
|
||||
$('#deviceEventsTitle').html ('Presence');
|
||||
$('#deviceEventsIcon').html ('<i class="fa fa-calendar">');
|
||||
if (deviceData['dev_PresenceHours'] == null || deviceData['dev_PresenceHours'] < 0) {
|
||||
if (deviceData['devPresenceHours'] == null || deviceData['devPresenceHours'] < 0) {
|
||||
$('#deviceEvents').html ('0 h.');
|
||||
} else {
|
||||
$('#deviceEvents').html (deviceData['dev_PresenceHours'].toLocaleString() +' h.');
|
||||
$('#deviceEvents').html (deviceData['devPresenceHours'].toLocaleString() +' h.');
|
||||
}
|
||||
|
||||
// Device info
|
||||
@@ -1264,7 +1264,7 @@ function getDeviceData (readAllData=false) {
|
||||
// Activate controls
|
||||
$('#panDetails :input').attr('disabled', false);
|
||||
|
||||
mac = deviceData['dev_MAC'];
|
||||
mac = deviceData['devMac'];
|
||||
|
||||
// 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);
|
||||
@@ -1275,51 +1275,51 @@ function getDeviceData (readAllData=false) {
|
||||
|
||||
devicesList = getDevicesList();
|
||||
|
||||
// handle empty dev_Network_Node_MAC_ADDR
|
||||
networkParentMac = deviceData['dev_Network_Node_MAC_ADDR']
|
||||
// handle empty devParentMAC
|
||||
networkParentMac = deviceData['devParentMAC']
|
||||
if(networkParentMac)
|
||||
{
|
||||
networkParentMacName = getDeviceDataByMac(deviceData['dev_Network_Node_MAC_ADDR'], "dev_Name")
|
||||
networkParentMacName = getDeviceDataByMac(deviceData['devParentMAC'], "devName")
|
||||
} else
|
||||
{
|
||||
networkParentMacName = '--'
|
||||
}
|
||||
|
||||
$('#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'], 'PGkgY2xhc3M9ImZhIGZhLWxhcHRvcCI+PC9pPg==')); // base64 laptop icon
|
||||
$('#txtMAC').val (deviceData['devMac']);
|
||||
$('#txtName').val (deviceData['devName']);
|
||||
$('#txtOwner').val (deviceData['devOwner']);
|
||||
$('#txtDeviceType').val (deviceData['devType']);
|
||||
$('#txtVendor').val (deviceData['devVendor']);
|
||||
$('#txtIcon').val (initDefault(deviceData['devIcon'], 'PGkgY2xhc3M9ImZhIGZhLWxhcHRvcCI+PC9pPg==')); // base64 laptop icon
|
||||
$('#txtIcon').trigger('change')
|
||||
|
||||
if (deviceData['dev_Favorite'] == 1) {$('#chkFavorite').iCheck('check');} else {$('#chkFavorite').iCheck('uncheck');}
|
||||
$('#txtGroup').val (deviceData['dev_Group']);
|
||||
$('#txtLocation').val (deviceData['dev_Location']);
|
||||
$('#txtComments').val (decodeSpecialChars(deviceData['dev_Comments']));
|
||||
if (deviceData['devFavorite'] == 1) {$('#chkFavorite').iCheck('check');} else {$('#chkFavorite').iCheck('uncheck');}
|
||||
$('#txtGroup').val (deviceData['devGroup']);
|
||||
$('#txtLocation').val (deviceData['devLocation']);
|
||||
$('#txtComments').val (decodeSpecialChars(deviceData['devComments']));
|
||||
$('#txtNetworkNodeMac').val ( networkParentMacName) ;
|
||||
$('#txtNetworkNodeMac').attr ('data-mynodemac', deviceData['dev_Network_Node_MAC_ADDR']);
|
||||
$('#txtNetworkPort').val (deviceData['dev_Network_Node_port']);
|
||||
$('#txtNetworkSite').val (deviceData['dev_NetworkSite']);
|
||||
$('#txtSSID').val (deviceData['dev_SSID']);
|
||||
$('#txtNetworkNodeMac').attr ('data-mynodemac', deviceData['devParentMAC']);
|
||||
$('#txtNetworkPort').val (deviceData['devParentPort']);
|
||||
$('#txtNetworkSite').val (deviceData['devSite']);
|
||||
$('#txtSSID').val (deviceData['devSSID']);
|
||||
// disabling network node configuration if root Internet node
|
||||
toggleNetworkConfiguration(mac == 'Internet')
|
||||
|
||||
|
||||
$('#txtFirstConnection').val (deviceData['dev_FirstConnection']);
|
||||
$('#txtLastConnection').val (deviceData['dev_LastConnection']);
|
||||
$('#txtLastIP').val (deviceData['dev_LastIP']);
|
||||
$('#txtStatus').val (deviceData['dev_Status'].replace('-', ''));
|
||||
if (deviceData['dev_StaticIP'] == 1) {$('#chkStaticIP').iCheck('check');} else {$('#chkStaticIP').iCheck('uncheck');}
|
||||
$('#txtFirstConnection').val (deviceData['devFirstConnection']);
|
||||
$('#txtLastConnection').val (deviceData['devLastConnection']);
|
||||
$('#txtLastIP').val (deviceData['devLastIP']);
|
||||
$('#txtStatus').val (deviceData['devStatus'].replace('-', ''));
|
||||
if (deviceData['devStaticIP'] == 1) {$('#chkStaticIP').iCheck('check');} else {$('#chkStaticIP').iCheck('uncheck');}
|
||||
|
||||
$('#txtScanCycle').val (deviceData['dev_ScanCycle'] == "1" ? "yes" : "no");
|
||||
if (deviceData['dev_AlertEvents'] == 1) {$('#chkAlertEvents').iCheck('check');} else {$('#chkAlertEvents').iCheck('uncheck');}
|
||||
if (deviceData['dev_AlertDeviceDown'] == 1) {$('#chkAlertDown').iCheck('check');} else {$('#chkAlertDown').iCheck('uncheck');}
|
||||
$('#txtSkipRepeated').val (findSkipRepeated (deviceData['dev_SkipRepeated']));
|
||||
if (deviceData['dev_NewDevice'] == 1) {$('#chkNewDevice').iCheck('check');} else {$('#chkNewDevice').iCheck('uncheck');}
|
||||
if (deviceData['dev_Archived'] == 1) {$('#chkArchived').iCheck('check');} else {$('#chkArchived').iCheck('uncheck');}
|
||||
$('#txtScanCycle').val (deviceData['devScan'] == "1" ? "yes" : "no");
|
||||
if (deviceData['devAlertEvents'] == 1) {$('#chkAlertEvents').iCheck('check');} else {$('#chkAlertEvents').iCheck('uncheck');}
|
||||
if (deviceData['devAlertDown'] == 1) {$('#chkAlertDown').iCheck('check');} else {$('#chkAlertDown').iCheck('uncheck');}
|
||||
$('#txtSkipRepeated').val (findSkipRepeated (deviceData['devSkipRepeated']));
|
||||
if (deviceData['devIsNew'] == 1) {$('#chkNewDevice').iCheck('check');} else {$('#chkNewDevice').iCheck('uncheck');}
|
||||
if (deviceData['devIsArchived'] == 1) {$('#chkArchived').iCheck('check');} else {$('#chkArchived').iCheck('uncheck');}
|
||||
|
||||
if (deviceData['dev_RandomMAC'] == 1) {$('#iconRandomMACactive').removeClass ('hidden');
|
||||
if (deviceData['devRandomMAC'] == 1) {$('#iconRandomMACactive').removeClass ('hidden');
|
||||
$('#iconRandomMACinactive').addClass ('hidden'); }
|
||||
else {$('#iconRandomMACactive').addClass ('hidden');
|
||||
$('#iconRandomMACinactive').removeClass ('hidden'); };
|
||||
@@ -1329,7 +1329,7 @@ function getDeviceData (readAllData=false) {
|
||||
pos = devicesList.findIndex(item => item.rowid == deviceData['rowid']);
|
||||
|
||||
if (pos == -1) {
|
||||
devicesList.push({"rowid" : deviceData['rowid'], "mac" : deviceData['dev_MAC'], "name": deviceData['dev_Name'], "type": deviceData['dev_DeviceType']});
|
||||
devicesList.push({"rowid" : deviceData['rowid'], "mac" : deviceData['devMac'], "name": deviceData['devName'], "type": deviceData['devType']});
|
||||
pos=0;
|
||||
}
|
||||
}
|
||||
@@ -1401,7 +1401,7 @@ function performSwitch(direction)
|
||||
// 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].dev_MAC.toString();
|
||||
mac = devicesList[pos].devMac.toString();
|
||||
|
||||
setCache("piaDeviceDetailsMac", mac);
|
||||
|
||||
@@ -1728,7 +1728,7 @@ function setTextValue (textElement, textValue) {
|
||||
if(textElement == "txtNetworkNodeMac")
|
||||
{
|
||||
$('#'+textElement).attr ('data-mynodemac', textValue);
|
||||
$('#'+textElement).val (getDeviceDataByMac(textValue, "dev_Name"));
|
||||
$('#'+textElement).val (getDeviceDataByMac(textValue, "devName"));
|
||||
} else
|
||||
{
|
||||
$('#'+textElement).attr ('data-myvalue', textValue);
|
||||
|
||||
@@ -77,16 +77,16 @@
|
||||
<?= lang("DevDetail_Nmap_Scans_desc") ?>
|
||||
</div>
|
||||
|
||||
<button type="button" id="piamanualnmap_fast" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'dev_LastIP'), 'fast')">
|
||||
<button type="button" id="piamanualnmap_fast" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'devLastIP'), 'fast')">
|
||||
<?= lang("DevDetail_Loading") ?>
|
||||
</button>
|
||||
<button type="button" id="piamanualnmap_normal" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'dev_LastIP'), 'normal')">
|
||||
<button type="button" id="piamanualnmap_normal" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'devLastIP'), 'normal')">
|
||||
<?= lang("DevDetail_Loading") ?>
|
||||
</button>
|
||||
<button type="button" id="piamanualnmap_detail" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'dev_LastIP'), 'detail')">
|
||||
<button type="button" id="piamanualnmap_detail" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'devLastIP'), 'detail')">
|
||||
<?= lang("DevDetail_Loading") ?>
|
||||
</button>
|
||||
<button type="button" id="piamanualnmap_skipdiscovery" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'dev_LastIP'), 'skipdiscovery')">
|
||||
<button type="button" id="piamanualnmap_skipdiscovery" class="btn btn-primary pa-btn" style="margin-bottom: 20px; margin-left: 10px; margin-right: 10px;" onclick="manualnmapscan(getDeviceDataByMac(getMac(), 'devLastIP'), 'skipdiscovery')">
|
||||
<?= lang("DevDetail_Loading") ?>
|
||||
</button>
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
$( "#tracerouteoutput" ).empty();
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
url: "./php/server/traceroute.php?action=get&ip=" + getDeviceDataByMac(getMac(), 'dev_LastIP') + "",
|
||||
url: "./php/server/traceroute.php?action=get&ip=" + getDeviceDataByMac(getMac(), 'devLastIP') + "",
|
||||
beforeSend: function() { $('#tracerouteoutput').addClass("ajax_scripts_loading"); },
|
||||
complete: function() { $('#tracerouteoutput').removeClass("ajax_scripts_loading"); },
|
||||
success: function(data, textStatus) {
|
||||
@@ -170,7 +170,7 @@
|
||||
$( "#nslookupoutput" ).empty();
|
||||
$.ajax({
|
||||
method: "GET",
|
||||
url: "./php/server/nslookup.php?action=get&ip=" + getDeviceDataByMac(getMac(), 'dev_LastIP') + "",
|
||||
url: "./php/server/nslookup.php?action=get&ip=" + getDeviceDataByMac(getMac(), 'devLastIP') + "",
|
||||
beforeSend: function() { $('#nslookupoutput').addClass("ajax_scripts_loading"); },
|
||||
complete: function() { $('#nslookupoutput').removeClass("ajax_scripts_loading"); },
|
||||
success: function(data, textStatus) {
|
||||
|
||||
@@ -159,6 +159,8 @@
|
||||
var tableColumnHide = [];
|
||||
var tableColumnOrder = [];
|
||||
var tableColumnVisible = [];
|
||||
headersDefaultOrder = [];
|
||||
missingNumbers = [];
|
||||
|
||||
// Read parameters & Initialize components
|
||||
callAfterAppInitialized(main)
|
||||
@@ -169,9 +171,12 @@ function main () {
|
||||
|
||||
showSpinner();
|
||||
|
||||
// render tiles
|
||||
getDevicesTotals();
|
||||
|
||||
//initialize the table headers in the correct order
|
||||
var availableColumns = getSettingOptions("UI_device_columns").split(",");
|
||||
var headersDefaultOrder = availableColumns.map(val => getString(val));
|
||||
headersDefaultOrder = availableColumns.map(val => getString(val));
|
||||
var selectedColumns = JSON.parse(getSetting("UI_device_columns").replace(/'/g, '"'));
|
||||
|
||||
// generate default order lists of given length
|
||||
@@ -192,27 +197,11 @@ function main () {
|
||||
const fullArray = Array.from({ length: tableColumnOrder.length }, (_, i) => i);
|
||||
|
||||
// Filter out the elements already present in inputArray
|
||||
const missingNumbers = fullArray.filter(num => !tableColumnVisible.includes(num));
|
||||
missingNumbers = fullArray.filter(num => !tableColumnVisible.includes(num));
|
||||
|
||||
// Concatenate the inputArray with the missingNumbers
|
||||
tableColumnOrder = [...tableColumnVisible, ...missingNumbers];
|
||||
|
||||
// render table headers
|
||||
html = '';
|
||||
|
||||
for(index = 0; index < tableColumnOrder.length; index++)
|
||||
{
|
||||
html += '<th>' + headersDefaultOrder[tableColumnOrder[index]] + '</th>';
|
||||
}
|
||||
|
||||
$('#tableDevices tr').html(html);
|
||||
|
||||
// Hide UI elements as per settings
|
||||
// setTimeout(() => {
|
||||
hideUIelements("UI_DEV_SECTIONS")
|
||||
|
||||
// }, 10);
|
||||
|
||||
// Initialize components with parameters
|
||||
initializeDatatable(getUrlAnchor('my_devices'));
|
||||
|
||||
@@ -237,60 +226,77 @@ function mapIndx(oldIndex)
|
||||
//------------------------------------------------------------------------------
|
||||
// Query total numbers of Devices by status
|
||||
//------------------------------------------------------------------------------
|
||||
function getDevicesTotals(devicesData) {
|
||||
function getDevicesTotals() {
|
||||
// Check cache first
|
||||
let resultJSON = getCache("getDevicesTotals");
|
||||
|
||||
let resultJSON = "";
|
||||
|
||||
if (getCache("getDevicesTotals") !== "") {
|
||||
resultJSON = getCache("getDevicesTotals");
|
||||
if (resultJSON !== "") {
|
||||
resultJSON = JSON.parse(resultJSON);
|
||||
processDeviceTotals(resultJSON);
|
||||
} else {
|
||||
// Fetch data via AJAX
|
||||
$.ajax({
|
||||
url: "/api/table_devices_tiles.json",
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: function(response) {
|
||||
if (response && response.data) {
|
||||
resultJSON = response.data[0]; // Assuming the structure {"data": [ ... ]}
|
||||
|
||||
// Save the result to cache
|
||||
setCache("getDevicesTotals", JSON.stringify(resultJSON));
|
||||
|
||||
// Define filter conditions and corresponding objects
|
||||
const filters = [
|
||||
{ status: 'my_devices', color: 'bg-aqua', label: getString('Device_Shortcut_AllDevices'), icon: 'fa-laptop' },
|
||||
{ status: 'all', color: 'bg-aqua', label: getString('Gen_All_Devices'), icon: 'fa-laptop' },
|
||||
{ status: 'connected', color: 'bg-green', label: getString('Device_Shortcut_Connected'), icon: 'fa-plug' },
|
||||
{ status: 'favorites', color: 'bg-yellow', label: getString('Device_Shortcut_Favorites'), icon: 'fa-star' },
|
||||
{ status: 'new', color: 'bg-yellow', label: getString('Device_Shortcut_NewDevices'), icon: 'fa-plus' },
|
||||
{ status: 'down', color: 'bg-red', label: getString('Device_Shortcut_DownOnly'), icon: 'fa-warning' },
|
||||
{ status: 'archived', color: 'bg-gray', label: getString('Device_Shortcut_Archived'), icon: 'fa-eye-slash' },
|
||||
{ status: 'offline', color: 'bg-gray', label: getString('Gen_Offline'), icon: 'fa-xmark' }
|
||||
];
|
||||
|
||||
// Initialize an empty array to store the final objects
|
||||
let dataArray = [];
|
||||
|
||||
// Loop through each filter condition
|
||||
filters.forEach(filter => {
|
||||
// Calculate count dynamically based on filter condition
|
||||
let count = filterDataByStatus(devicesData, filter.status).length;
|
||||
|
||||
// Check any condition to skip adding the object to dataArray
|
||||
if (
|
||||
(['', 'False'].includes(getSetting('UI_hide_empty')) || (getSetting('UI_hide_empty') == "True" && count > 0)) &&
|
||||
(getSetting('UI_shown_cards') == "" || getSetting('UI_shown_cards').includes(filter.status))
|
||||
) {
|
||||
dataArray.push({
|
||||
onclickEvent: `initializeDatatable('${filter.status}')`,
|
||||
color: filter.color,
|
||||
title: count,
|
||||
label: filter.label,
|
||||
icon: filter.icon
|
||||
});
|
||||
// Process the fetched data
|
||||
processDeviceTotals(resultJSON);
|
||||
} else {
|
||||
console.error("Invalid response format from API");
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Failed to fetch devices data:", error);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// render info boxes/tile cards
|
||||
renderInfoboxes(
|
||||
dataArray
|
||||
)
|
||||
function processDeviceTotals(devicesData) {
|
||||
// Define filter conditions and corresponding objects
|
||||
const filters = [
|
||||
{ status: 'my_devices', color: 'bg-aqua', label: getString('Device_Shortcut_AllDevices'), icon: 'fa-laptop' },
|
||||
{ status: 'all', color: 'bg-aqua', label: getString('Gen_All_Devices'), icon: 'fa-laptop' },
|
||||
{ status: 'connected', color: 'bg-green', label: getString('Device_Shortcut_Connected'), icon: 'fa-plug' },
|
||||
{ status: 'favorites', color: 'bg-yellow', label: getString('Device_Shortcut_Favorites'), icon: 'fa-star' },
|
||||
{ status: 'new', color: 'bg-yellow', label: getString('Device_Shortcut_NewDevices'), icon: 'fa-plus' },
|
||||
{ status: 'down', color: 'bg-red', label: getString('Device_Shortcut_DownOnly'), icon: 'fa-warning' },
|
||||
{ status: 'archived', color: 'bg-gray', label: getString('Device_Shortcut_Archived'), icon: 'fa-eye-slash' },
|
||||
{ status: 'offline', color: 'bg-gray', label: getString('Gen_Offline'), icon: 'fa-xmark' }
|
||||
];
|
||||
|
||||
// save to cache
|
||||
setCache("getDevicesTotals", resultJSON);
|
||||
}
|
||||
// Initialize an empty array to store the final objects
|
||||
let dataArray = [];
|
||||
|
||||
// console.log(resultJSON);
|
||||
// Loop through each filter condition
|
||||
filters.forEach(filter => {
|
||||
// Get count directly from API response data
|
||||
let count = devicesData[filter.status] || 0;
|
||||
|
||||
// Check any condition to skip adding the object to dataArray
|
||||
if (
|
||||
(['', 'False'].includes(getSetting('UI_hide_empty')) || (getSetting('UI_hide_empty') == "True" && count > 0)) &&
|
||||
(getSetting('UI_shown_cards') == "" || getSetting('UI_shown_cards').includes(filter.status))
|
||||
) {
|
||||
dataArray.push({
|
||||
onclickEvent: `forceLoadUrl('devices.php#${filter.status}')`,
|
||||
color: filter.color,
|
||||
title: count,
|
||||
label: filter.label,
|
||||
icon: filter.icon
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Render info boxes/tile cards
|
||||
renderInfoboxes(dataArray);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -320,68 +326,79 @@ function filterDataByStatus(data, status) {
|
||||
|
||||
let result = true;
|
||||
|
||||
if (!to_display.includes('down') && item.dev_PresentLastScan === 0 && item.dev_AlertDeviceDown !== 0) {
|
||||
if (!to_display.includes('down') && item.devPresentLastScan === 0 && item.devAlertDown !== 0) {
|
||||
result = false;
|
||||
} else if (!to_display.includes('new') && item.dev_NewDevice === 1) {
|
||||
} else if (!to_display.includes('new') && item.devIsNew === 1) {
|
||||
result = false;
|
||||
} else if (!to_display.includes('archived') && item.dev_Archived === 1) {
|
||||
} else if (!to_display.includes('archived') && item.devIsArchived === 1) {
|
||||
result = false;
|
||||
} else if (!to_display.includes('offline') && item.dev_PresentLastScan === 0) {
|
||||
} else if (!to_display.includes('offline') && item.devPresentLastScan === 0) {
|
||||
result = false;
|
||||
} else if (!to_display.includes('online') && item.dev_PresentLastScan === 1) {
|
||||
} else if (!to_display.includes('online') && item.devPresentLastScan === 1) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
return result; // Include all items for 'my_devices' status
|
||||
case 'connected':
|
||||
return item.dev_PresentLastScan === 1;
|
||||
return item.devPresentLastScan === 1;
|
||||
case 'favorites':
|
||||
return item.dev_Favorite === 1;
|
||||
return item.devFavorite === 1;
|
||||
case 'new':
|
||||
return item.dev_NewDevice === 1;
|
||||
return item.devIsNew === 1;
|
||||
case 'offline':
|
||||
return item.dev_PresentLastScan === 0;
|
||||
return item.devPresentLastScan === 0;
|
||||
case 'down':
|
||||
return (item.dev_PresentLastScan === 0 && item.dev_AlertDeviceDown !== 0);
|
||||
return (item.devPresentLastScan === 0 && item.devAlertDown !== 0);
|
||||
case 'archived':
|
||||
return item.dev_Archived === 1;
|
||||
return item.devIsArchived === 1;
|
||||
default:
|
||||
return true; // Include all items for unknown statuses
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function getDeviceStatus(item)
|
||||
{
|
||||
|
||||
if(item.dev_NewDevice === 1)
|
||||
{
|
||||
return 'New';
|
||||
}
|
||||
else if(item.dev_PresentLastScan === 1)
|
||||
{
|
||||
return 'On-line';
|
||||
}
|
||||
else if(item.dev_PresentLastScan === 0 && item.dev_AlertDeviceDown !== 0)
|
||||
{
|
||||
return 'Down';
|
||||
}
|
||||
else if(item.dev_Archived === 1)
|
||||
{
|
||||
return 'Archived';
|
||||
}
|
||||
else if(item.dev_PresentLastScan === 0)
|
||||
{
|
||||
return 'Off-line';
|
||||
}
|
||||
|
||||
return "Unknown status"
|
||||
// Map column index to column name for GraphQL query
|
||||
function mapColumnIndexToFieldName(index, tableColumnVisible) {
|
||||
// the order is important, don't change it!
|
||||
const columnNames = [
|
||||
"devName",
|
||||
"devOwner",
|
||||
"devType",
|
||||
"devIcon",
|
||||
"devFavorite",
|
||||
"devGroup",
|
||||
"devFirstConnection",
|
||||
"devLastConnection",
|
||||
"devLastIP",
|
||||
"devIsRandomMac", // resolved on the fly
|
||||
"devStatus", // resolved on the fly
|
||||
"devMac",
|
||||
"devIpLong", //formatIPlong(device.devLastIP) || "", // IP orderable
|
||||
"rowid",
|
||||
"devParentMAC",
|
||||
"devParentChildrenCount", // resolved on the fly
|
||||
"devLocation",
|
||||
"devVendor",
|
||||
"devParentPort",
|
||||
"devGUID",
|
||||
"devSyncHubNode",
|
||||
"devSite",
|
||||
"devSSID",
|
||||
"devSourcePlugin",
|
||||
"devPresentLastScan",
|
||||
"devAlertDown"
|
||||
];
|
||||
|
||||
// console.log("OrderBy: " + columnNames[tableColumnOrder[index]]);
|
||||
|
||||
return columnNames[tableColumnOrder[index]] || null;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function initializeDatatable (status) {
|
||||
|
||||
// ---------------------------------------------------------
|
||||
function initializeDatatable (status) {
|
||||
|
||||
if(!status)
|
||||
{
|
||||
status = 'my_devices'
|
||||
@@ -408,6 +425,17 @@ function initializeDatatable (status) {
|
||||
$('#tableDevicesBox')[0].className = 'box box-'+ color;
|
||||
$('#tableDevicesTitle').html (tableTitle);
|
||||
|
||||
// render table headers
|
||||
html = '';
|
||||
|
||||
for(index = 0; index < tableColumnOrder.length; index++)
|
||||
{
|
||||
html += '<th>' + headersDefaultOrder[tableColumnOrder[index]] + '</th>';
|
||||
}
|
||||
|
||||
$('#tableDevices tr').html(html);
|
||||
|
||||
hideUIelements("UI_DEV_SECTIONS")
|
||||
|
||||
for(i = 0; i < tableColumnOrder.length; i++)
|
||||
{
|
||||
@@ -418,323 +446,344 @@ function initializeDatatable (status) {
|
||||
}
|
||||
}
|
||||
|
||||
$.get('api/table_devices.json?nocache=' + Date.now(), function(result) {
|
||||
// todo: dynamically filter based on status
|
||||
|
||||
// refresh devices cache
|
||||
devicesListAll_JSON = result["data"]
|
||||
devicesListAll_JSON_str = JSON.stringify(devicesListAll_JSON)
|
||||
setCache('devicesListAll_JSON', devicesListAll_JSON_str)
|
||||
|
||||
// query data
|
||||
getDevicesTotals(result.data);
|
||||
|
||||
// Filter the data based on deviceStatus
|
||||
var filteredData = filterDataByStatus(result.data, deviceStatus);
|
||||
|
||||
// Convert JSON data into the desired format
|
||||
var dataArray = {
|
||||
data: filteredData.map(function(item) {
|
||||
var originalRow = [
|
||||
item.dev_Name || "",
|
||||
item.dev_Owner || "",
|
||||
item.dev_DeviceType || "",
|
||||
item.dev_Icon || "",
|
||||
item.dev_Favorite || "",
|
||||
item.dev_Group || "",
|
||||
// ---
|
||||
item.dev_FirstConnection || "",
|
||||
item.dev_LastConnection || "",
|
||||
item.dev_LastIP || "",
|
||||
(isRandomMAC(item.dev_MAC)) || "", // Check if randomized MAC
|
||||
getDeviceStatus(item) || "",
|
||||
item.dev_MAC || "", // hidden
|
||||
formatIPlong(item.dev_LastIP) || "", // IP orderable
|
||||
item.rowid || "",
|
||||
item.dev_Network_Node_MAC_ADDR || "",
|
||||
getNumberOfChildren(item.dev_MAC, result.data) || 0,
|
||||
item.dev_Location || "",
|
||||
item.dev_Vendor || "",
|
||||
item.dev_Network_Node_port || 0,
|
||||
item.dev_GUID || "",
|
||||
item.dev_SyncHubNodeName || "",
|
||||
item.dev_NetworkSite || "",
|
||||
item.dev_SSID || "",
|
||||
item.dev_SourcePlugin || ""
|
||||
var table = $('#tableDevices').DataTable({
|
||||
"serverSide": true,
|
||||
"processing": true,
|
||||
"ajax": {
|
||||
"url": 'php/server/query_graphql.php', // PHP endpoint that proxies to the GraphQL server
|
||||
"type": "POST",
|
||||
"contentType": "application/json",
|
||||
"data": function (d) {
|
||||
// Construct GraphQL query with pagination and sorting options
|
||||
let graphqlQuery = `
|
||||
query devices($options: PageQueryOptionsInput) {
|
||||
devices(options: $options) {
|
||||
devices {
|
||||
rowid
|
||||
devMac
|
||||
devName
|
||||
devOwner
|
||||
devType
|
||||
devVendor
|
||||
devFavorite
|
||||
devGroup
|
||||
devComments
|
||||
devFirstConnection
|
||||
devLastConnection
|
||||
devLastIP
|
||||
devStaticIP
|
||||
devScan
|
||||
devLogEvents
|
||||
devAlertEvents
|
||||
devAlertDown
|
||||
devSkipRepeated
|
||||
devLastNotification
|
||||
devPresentLastScan
|
||||
devIsNew
|
||||
devIsRandomMac
|
||||
devLocation
|
||||
devIsArchived
|
||||
devParentMAC
|
||||
devParentPort
|
||||
devIcon
|
||||
devGUID
|
||||
devSite
|
||||
devSSID
|
||||
devSyncHubNode
|
||||
devSourcePlugin
|
||||
devStatus
|
||||
devParentChildrenCount
|
||||
devIpLong
|
||||
}
|
||||
count
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
console.log(d);
|
||||
|
||||
|
||||
// Prepare query variables for pagination, sorting, and search
|
||||
let query = {
|
||||
"operationName": null,
|
||||
"query": graphqlQuery,
|
||||
"variables": {
|
||||
"options": {
|
||||
"page": Math.floor(d.start / d.length) + 1, // Page number (1-based)
|
||||
"limit": parseInt(d.length, 10), // Page size (ensure it's an integer)
|
||||
"sort": d.order && d.order[0] ? [{
|
||||
"field": mapColumnIndexToFieldName(d.order[0].column, tableColumnVisible), // Sort field from DataTable column
|
||||
"order": d.order[0].dir.toUpperCase() // Sort direction (ASC/DESC)
|
||||
}] : [], // Default to an empty array if no sorting is defined
|
||||
"search": d.search.value, // Search query
|
||||
"status": deviceStatus
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
return JSON.stringify(query); // Send the JSON request
|
||||
},
|
||||
"dataSrc": function (json) {
|
||||
console.log(json);
|
||||
|
||||
// Set the total number of records for pagination
|
||||
json.recordsTotal = json.devices.count || 0;
|
||||
json.recordsFiltered = json.devices.count || 0;
|
||||
|
||||
return json.devices.devices.map(device => {
|
||||
// Convert each device record into the required DataTable row format
|
||||
// Order has to be the same as in the UI_device_columns setting options
|
||||
const originalRow = [
|
||||
device.devName || "",
|
||||
device.devOwner || "",
|
||||
device.devType || "",
|
||||
device.devIcon || "",
|
||||
device.devFavorite || "",
|
||||
device.devGroup || "",
|
||||
device.devFirstConnection || "",
|
||||
device.devLastConnection || "",
|
||||
device.devLastIP || "",
|
||||
device.devIsRandomMac || "", // Custom logic for randomized MAC
|
||||
device.devStatus || "",
|
||||
device.devMac || "", // hidden
|
||||
device.devIpLong || "", // IP orderable
|
||||
device.rowid || "",
|
||||
device.devParentMAC || "",
|
||||
device.devParentChildrenCount || 0,
|
||||
device.devLocation || "",
|
||||
device.devVendor || "",
|
||||
device.devParentPort || "",
|
||||
device.devGUID || "",
|
||||
device.devSyncHubNode || "",
|
||||
device.devSite || "",
|
||||
device.devSSID || "",
|
||||
device.devSourcePlugin || "",
|
||||
device.devPresentLastScan || "",
|
||||
device.devAlertDown || ""
|
||||
];
|
||||
|
||||
var newRow = [];
|
||||
|
||||
// reorder data based on user-defined columns order
|
||||
for (index = 0; index < tableColumnOrder.length; index++) {
|
||||
const newRow = [];
|
||||
// Reorder data based on user-defined columns order
|
||||
for (let index = 0; index < tableColumnOrder.length; index++) {
|
||||
newRow.push(originalRow[tableColumnOrder[index]]);
|
||||
}
|
||||
|
||||
return newRow;
|
||||
})
|
||||
};
|
||||
|
||||
// Check if the DataTable already exists
|
||||
if ($.fn.dataTable.isDataTable('#tableDevices')) {
|
||||
// The DataTable exists, so destroy it
|
||||
var table = $('#tableDevices').DataTable();
|
||||
table.clear().destroy();
|
||||
}
|
||||
|
||||
var table =
|
||||
$('#tableDevices').DataTable({
|
||||
'data' : dataArray["data"],
|
||||
'paging' : true,
|
||||
'lengthChange' : true,
|
||||
'lengthMenu' : [[10, 25, 50, 100, 500, 100000], [10, 25, 50, 100, 500, getString('Device_Tablelenght_all')]],
|
||||
'searching' : true,
|
||||
|
||||
'ordering' : true,
|
||||
'info' : true,
|
||||
'autoWidth' : false,
|
||||
|
||||
// Parameters
|
||||
'pageLength' : tableRows,
|
||||
'order' : tableOrder,
|
||||
'select' : true, // Enable selection
|
||||
|
||||
'columnDefs' : [
|
||||
{visible: false, targets: tableColumnHide },
|
||||
{className: 'text-center', targets: [mapIndx(3), mapIndx(4), mapIndx(9), mapIndx(10), mapIndx(15), mapIndx(18)] },
|
||||
{width: '80px', targets: [mapIndx(6), mapIndx(7), mapIndx(15)] },
|
||||
{width: '30px', targets: [mapIndx(10), mapIndx(13), mapIndx(18)] },
|
||||
{orderData: [mapIndx(12)], targets: mapIndx(8) },
|
||||
|
||||
// Device Name
|
||||
{targets: [mapIndx(0)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
|
||||
// console.log(cellData)
|
||||
$(td).html ('<b class="anonymizeDev"><a href="deviceDetails.php?mac='+ rowData[mapIndx(11)] +'" class="">'+ cellData +'</a></b>');
|
||||
} },
|
||||
|
||||
// Connected Devices
|
||||
{targets: [mapIndx(15)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
// check if this is a network device
|
||||
if(getSetting("NETWORK_DEVICE_TYPES").includes(`'${rowData[mapIndx(2)]}'`) )
|
||||
{
|
||||
$(td).html ('<b><a href="./network.php?mac='+ rowData[mapIndx(11)] +'" class="">'+ cellData +'</a></b>');
|
||||
}
|
||||
else
|
||||
{
|
||||
$(td).html (`<i class="fa-solid fa-xmark" title="${getString("Device_Table_Not_Network_Device")}"></i>`)
|
||||
}
|
||||
|
||||
} },
|
||||
|
||||
// Icon
|
||||
{targets: [mapIndx(3)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
if (!emptyArr.includes(cellData)){
|
||||
$(td).html (atob(cellData));
|
||||
} 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(8)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
if (!emptyArr.includes(cellData)){
|
||||
$(td).html (`<span class="anonymizeIp">
|
||||
<a href="http://${cellData}" class="pointer" target="_blank">
|
||||
${cellData}
|
||||
</a>
|
||||
<a href="https://${cellData}" class="pointer" target="_blank">
|
||||
<i class="fa fa-lock "></i>
|
||||
</a>
|
||||
<span>`);
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
}
|
||||
},
|
||||
// IP address (ordeable)
|
||||
{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>');
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
} },
|
||||
|
||||
// Dates
|
||||
{targets: [mapIndx(6), mapIndx(7)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
var result = cellData.toString(); // Convert to string
|
||||
if (result.includes("+")) { // Check if timezone offset is present
|
||||
result = result.split('+')[0]; // Remove timezone offset
|
||||
}
|
||||
$(td).html (translateHTMLcodes (result));
|
||||
} },
|
||||
|
||||
// Random MAC
|
||||
{targets: [mapIndx(9)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
// console.log(cellData)
|
||||
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>');
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
} },
|
||||
|
||||
// Status color
|
||||
{targets: [mapIndx(10)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
|
||||
devData = getDeviceDataByMac(rowData[mapIndx(11)])
|
||||
|
||||
if (devData.dev_PresentLastScan == 1)
|
||||
{
|
||||
css = "green text-white statusOnline"
|
||||
icon = '<i class="fa-solid fa-plug"></i>'
|
||||
} else if (devData.dev_PresentLastScan != 1 && devData.dev_AlertDeviceDown == 1)
|
||||
{
|
||||
css = "red text-white statusDown"
|
||||
icon = '<i class="fa-solid fa-triangle-exclamation"></i>'
|
||||
} else if(devData.dev_PresentLastScan != 1)
|
||||
{
|
||||
css = "gray text-white statusOffline"
|
||||
icon = '<i class="fa-solid fa-xmark"></i>'
|
||||
} else
|
||||
{
|
||||
css = "gray text-white statusUnknown"
|
||||
icon = '<i class="fa-solid fa-question"></i>'
|
||||
}
|
||||
|
||||
$(td).html (`<a href="deviceDetails.php?mac=${rowData[mapIndx(11)]}" class="badge bg-${css}">${icon} ${cellData.replace('-', '')}</a>`);
|
||||
} },
|
||||
],
|
||||
|
||||
// Processing
|
||||
'processing' : true,
|
||||
'language' : {
|
||||
processing: '<table> <td width="130px" align="middle">Loading...</td><td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td> </table>',
|
||||
emptyTable: 'No data',
|
||||
"lengthMenu": "<?= lang('Device_Tablelenght');?>",
|
||||
"search": "<?= lang('Device_Searchbox');?>: ",
|
||||
"paginate": {
|
||||
"next": "<?= lang('Device_Table_nav_next');?>",
|
||||
"previous": "<?= lang('Device_Table_nav_prev');?>"
|
||||
},
|
||||
"info": "<?= lang('Device_Table_info');?>",
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
'paging' : true,
|
||||
'lengthChange' : true,
|
||||
'lengthMenu' : [[10, 25, 50, 100, 500, 100000], [10, 25, 50, 100, 500, getString('Device_Tablelenght_all')]],
|
||||
'searching' : true,
|
||||
|
||||
// Save cookie Rows displayed, and Parameters rows & order
|
||||
$('#tableDevices').on( 'length.dt', function ( e, settings, len ) {
|
||||
setCookie ("nax_parTableRows", len, 129600); // save for 90 days
|
||||
} );
|
||||
'ordering' : true,
|
||||
'info' : true,
|
||||
'autoWidth' : false,
|
||||
|
||||
// Parameters
|
||||
'pageLength' : tableRows,
|
||||
'order' : tableOrder,
|
||||
'select' : true, // Enable selection
|
||||
|
||||
'columnDefs' : [
|
||||
{visible: false, targets: tableColumnHide },
|
||||
{className: 'text-center', targets: [mapIndx(3), mapIndx(4), mapIndx(9), mapIndx(10), mapIndx(15), mapIndx(18)] },
|
||||
{width: '80px', targets: [mapIndx(6), mapIndx(7), mapIndx(15)] },
|
||||
{width: '30px', targets: [mapIndx(10), mapIndx(13), mapIndx(18)] },
|
||||
{orderData: [mapIndx(12)], targets: mapIndx(8) },
|
||||
|
||||
// Device Name
|
||||
{targets: [mapIndx(0)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
|
||||
// console.log(cellData)
|
||||
$(td).html ('<b class="anonymizeDev"><a href="deviceDetails.php?mac='+ rowData[mapIndx(11)] +'" class="">'+ cellData +'</a></b>');
|
||||
} },
|
||||
|
||||
// Connected Devices
|
||||
{targets: [mapIndx(15)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
|
||||
|
||||
// check if this is a network device
|
||||
if(getSetting("NETWORK_DEVICE_TYPES").includes(`'${rowData[mapIndx(2)]}'`) )
|
||||
{
|
||||
$(td).html ('<b><a href="./network.php?mac='+ rowData[mapIndx(11)] +'" class="">'+ cellData +'</a></b>');
|
||||
}
|
||||
else
|
||||
{
|
||||
$(td).html (`<i class="fa-solid fa-xmark" title="${getString("Device_Table_Not_Network_Device")}"></i>`)
|
||||
}
|
||||
|
||||
} },
|
||||
|
||||
// Icon
|
||||
{targets: [mapIndx(3)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
|
||||
if (!emptyArr.includes(cellData)){
|
||||
$(td).html (atob(cellData));
|
||||
} 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 ('');
|
||||
}
|
||||
} },
|
||||
|
||||
$('#tableDevices').on( 'order.dt', function () {
|
||||
setCookie ("nax_parTableOrder", JSON.stringify (table.order()), 129600); // save for 90 days
|
||||
setCache ('devicesList', getDevicesFromTable(table) );
|
||||
} );
|
||||
|
||||
$('#tableDevices').on( 'search.dt', function () {
|
||||
setCache ('devicesList', getDevicesFromTable(table) );
|
||||
} );
|
||||
|
||||
// add multi-edit button
|
||||
$('#multiEditPlc').append(
|
||||
`<button type="submit" id="multiEdit" class="btn btn-primary" style="display:none" onclick="multiEditDevices();">
|
||||
<i class="fa fa-pencil pointer" ></i> ${getString("Device_MultiEdit")}
|
||||
</button>`)
|
||||
|
||||
// Event listener for row selection in DataTable
|
||||
$('#tableDevices').on('click', 'tr', function (e) {
|
||||
setTimeout(function(){
|
||||
// Check if any row is selected
|
||||
var anyRowSelected = $('#tableDevices tr.selected').length > 0;
|
||||
|
||||
// Toggle visibility of element with ID 'multiEdit'
|
||||
$('#multiEdit').toggle(anyRowSelected);
|
||||
}, 200);
|
||||
|
||||
|
||||
// IP address
|
||||
{targets: [mapIndx(8)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
if (!emptyArr.includes(cellData)){
|
||||
$(td).html (`<span class="anonymizeIp">
|
||||
<a href="http://${cellData}" class="pointer" target="_blank">
|
||||
${cellData}
|
||||
</a>
|
||||
<a href="https://${cellData}" class="pointer" target="_blank">
|
||||
<i class="fa fa-lock "></i>
|
||||
</a>
|
||||
<span>`);
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
}
|
||||
},
|
||||
// IP address (ordeable)
|
||||
{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>');
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
} },
|
||||
|
||||
// Dates
|
||||
{targets: [mapIndx(6), mapIndx(7)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
var result = cellData.toString(); // Convert to string
|
||||
if (result.includes("+")) { // Check if timezone offset is present
|
||||
result = result.split('+')[0]; // Remove timezone offset
|
||||
}
|
||||
$(td).html (translateHTMLcodes (result));
|
||||
} },
|
||||
|
||||
hideSpinner();
|
||||
// Random MAC
|
||||
{targets: [mapIndx(9)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
// console.log(cellData)
|
||||
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>');
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
} },
|
||||
|
||||
});
|
||||
};
|
||||
// Status color
|
||||
{targets: [mapIndx(10)],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
|
||||
tmp_devPresentLastScan = rowData[mapIndx(24)]
|
||||
tmp_devAlertDown = rowData[mapIndx(25)]
|
||||
|
||||
if (tmp_devPresentLastScan == 1)
|
||||
{
|
||||
css = "green text-white statusOnline"
|
||||
icon = '<i class="fa-solid fa-plug"></i>'
|
||||
} else if (tmp_devPresentLastScan != 1 && tmp_devAlertDown == 1)
|
||||
{
|
||||
css = "red text-white statusDown"
|
||||
icon = '<i class="fa-solid fa-triangle-exclamation"></i>'
|
||||
} else if(tmp_devPresentLastScan != 1)
|
||||
{
|
||||
css = "gray text-white statusOffline"
|
||||
icon = '<i class="fa-solid fa-xmark"></i>'
|
||||
} else
|
||||
{
|
||||
css = "gray text-white statusUnknown"
|
||||
icon = '<i class="fa-solid fa-question"></i>'
|
||||
}
|
||||
|
||||
$(td).html (`<a href="deviceDetails.php?mac=${rowData[mapIndx(11)]}" class="badge bg-${css}">${icon} ${cellData.replace('-', '')}</a>`);
|
||||
} },
|
||||
],
|
||||
|
||||
// Processing
|
||||
'processing' : true,
|
||||
'language' : {
|
||||
emptyTable: 'No data',
|
||||
"lengthMenu": "<?= lang('Device_Tablelenght');?>",
|
||||
"search": "<?= lang('Device_Searchbox');?>: ",
|
||||
"paginate": {
|
||||
"next": "<?= lang('Device_Table_nav_next');?>",
|
||||
"previous": "<?= lang('Device_Table_nav_prev');?>"
|
||||
},
|
||||
"info": "<?= lang('Device_Table_info');?>",
|
||||
},
|
||||
initComplete: function (settings, devices) {
|
||||
// Handle any additional interactions or event listeners as required
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Gets a JSON list of rowID and mac from the displayed table in the UI
|
||||
function getDevicesFromTable(table)
|
||||
{
|
||||
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() //
|
||||
// Save cookie Rows displayed, and Parameters rows & order
|
||||
$('#tableDevices').on( 'length.dt', function ( e, settings, len ) {
|
||||
setCookie ("nax_parTableRows", len, 129600); // save for 90 days
|
||||
} );
|
||||
|
||||
$('#tableDevices').on( 'order.dt', function () {
|
||||
setCookie ("nax_parTableOrder", JSON.stringify (table.order()), 129600); // save for 90 days
|
||||
} );
|
||||
|
||||
result = []
|
||||
// add multi-edit button
|
||||
$('#multiEditPlc').append(
|
||||
`<button type="submit" id="multiEdit" class="btn btn-primary" style="display:none" onclick="multiEditDevices();">
|
||||
<i class="fa fa-pencil pointer" ></i> ${getString("Device_MultiEdit")}
|
||||
</button>`)
|
||||
|
||||
rowIDs.map(function(rowID, index){
|
||||
result.push({
|
||||
"rowid": rowID,
|
||||
"mac" : rowMACs[index],
|
||||
"name" : rowNames[index],
|
||||
"type" : rowTypes[index],
|
||||
"icon" : rowIcons[index],
|
||||
"parentMac" : rowParentMAC[index],
|
||||
"status" : rowStatus[index] })
|
||||
})
|
||||
// Event listener for row selection in DataTable
|
||||
$('#tableDevices').on('click', 'tr', function (e) {
|
||||
setTimeout(function(){
|
||||
// Check if any row is selected
|
||||
var anyRowSelected = $('#tableDevices tr.selected').length > 0;
|
||||
|
||||
return JSON.stringify (result)
|
||||
}
|
||||
// Toggle visibility of element with ID 'multiEdit'
|
||||
$('#multiEdit').toggle(anyRowSelected);
|
||||
}, 100);
|
||||
|
||||
});
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function getNumberOfChildren(mac, devices)
|
||||
{
|
||||
childrenCount = 0;
|
||||
|
||||
$.each(devices, function(index, dev) {
|
||||
|
||||
if(dev.dev_Network_Node_MAC_ADDR != null && dev.dev_Network_Node_MAC_ADDR.trim() == mac.trim())
|
||||
{
|
||||
childrenCount++;
|
||||
}
|
||||
|
||||
hideSpinner();
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return childrenCount;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function handleLoadingDialog(needsReload = false)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ var timerRefreshData = ''
|
||||
|
||||
var emptyArr = ['undefined', "", undefined, null, 'null'];
|
||||
var UI_LANG = "English";
|
||||
const allLanguages = ["en_us", "es_es", "de_de", "fr_fr", "it_it", "ru_ru", "nb_no", "pl_pl", "pt_br", "tr_tr", "zh_cn", "cs_cz", "ar_ar"]; // needs to be same as in lang.php
|
||||
const allLanguages = ["en_us", "es_es", "de_de", "fr_fr", "it_it", "ru_ru", "nb_no", "pl_pl", "pt_br", "tr_tr", "zh_cn", "cs_cz", "ar_ar", "ca_ca"]; // needs to be same as in lang.php
|
||||
var settingsJSON = {}
|
||||
|
||||
|
||||
@@ -336,6 +336,9 @@ function getLangCode() {
|
||||
case 'Arabic (ar_ar)':
|
||||
lang_code = 'ar_ar';
|
||||
break;
|
||||
case 'Catalan (ca_ca)':
|
||||
lang_code = 'ca_ca';
|
||||
break;
|
||||
}
|
||||
|
||||
return lang_code;
|
||||
@@ -686,6 +689,13 @@ function openUrl(urls) {
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// force laod URL in current window with specific anchor
|
||||
function forceLoadUrl(relativeUrl) {
|
||||
window.location.replace(relativeUrl);
|
||||
window.location.reload()
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function navigateToDeviceWithIp (ip) {
|
||||
@@ -698,9 +708,9 @@ function navigateToDeviceWithIp (ip) {
|
||||
|
||||
$.each(devices, function(index, obj) {
|
||||
|
||||
if(obj.dev_LastIP.trim() == ip.trim())
|
||||
if(obj.devLastIP.trim() == ip.trim())
|
||||
{
|
||||
mac = obj.dev_MAC;
|
||||
mac = obj.devMac;
|
||||
|
||||
window.open(window.location.origin +'/deviceDetails.php?mac=' + mac , "_blank");
|
||||
}
|
||||
@@ -711,7 +721,7 @@ function navigateToDeviceWithIp (ip) {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function getNameByMacAddress(macAddress) {
|
||||
return getDeviceDataByMac(macAddress, "dev_Name")
|
||||
return getDeviceDataByMac(macAddress, "devName")
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -877,7 +887,7 @@ function getDeviceDataByMac(macAddress, dbColumn) {
|
||||
const devices = JSON.parse(devicesCache);
|
||||
|
||||
for (const device of devices) {
|
||||
if (device["dev_MAC"].toLowerCase() === macAddress.toLowerCase()) {
|
||||
if (device["devMac"].toLowerCase() === macAddress.toLowerCase()) {
|
||||
|
||||
if(dbColumn)
|
||||
{
|
||||
@@ -967,6 +977,19 @@ function getGuid() {
|
||||
// -----------------------------------------------------------------------------
|
||||
// Loading Spinner overlay
|
||||
// -----------------------------------------------------------------------------
|
||||
spinnerHtml = `
|
||||
<!-- spinner -->
|
||||
<div id="loadingSpinner" style="display: block">
|
||||
<div class="pa_semitransparent-panel"></div>
|
||||
<div class="panel panel-default pa_spinner">
|
||||
<table>
|
||||
<td width="130px" align="middle">_text_</td>
|
||||
<td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
|
||||
function showSpinner(stringKey='Loading')
|
||||
{
|
||||
|
||||
@@ -985,20 +1008,7 @@ function showSpinner(stringKey='Loading')
|
||||
$("#loadingSpinner").show();
|
||||
}
|
||||
else{
|
||||
html = `
|
||||
<!-- spinner -->
|
||||
<div id="loadingSpinner" style="display: block">
|
||||
<div class="pa_semitransparent-panel"></div>
|
||||
<div class="panel panel-default pa_spinner">
|
||||
<table>
|
||||
<td width="130px" align="middle">${text}</td>
|
||||
<td><i class="ion ion-ios-loop-strong fa-spin fa-2x fa-fw"></td>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
|
||||
$(".wrapper").append(html)
|
||||
$(".wrapper").append(spinnerHtml.replace('_text_',text))
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -1257,39 +1267,75 @@ async function handleFirstLoad(callback) {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Execute callback once app initialized
|
||||
function callAfterAppInitialized(callback) {
|
||||
if (!isAppInitialized()) {
|
||||
// Execute callback once the app is initialized and GraphQL server is running
|
||||
async function callAfterAppInitialized(callback) {
|
||||
if (!isAppInitialized() || !(await isGraphQLServerRunning())) {
|
||||
setTimeout(() => {
|
||||
callAfterAppInitialized(callback)
|
||||
callAfterAppInitialized(callback);
|
||||
}, 500);
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Polling function to repeatedly check if the server is running
|
||||
async function waitForGraphQLServer() {
|
||||
const pollInterval = 2000; // 2 seconds between each check
|
||||
let serverRunning = false;
|
||||
|
||||
while (!serverRunning) {
|
||||
serverRunning = await isGraphQLServerRunning();
|
||||
if (!serverRunning) {
|
||||
console.log("GraphQL server not running, retrying in 2 seconds...");
|
||||
await new Promise(resolve => setTimeout(resolve, pollInterval));
|
||||
}
|
||||
}
|
||||
|
||||
console.log("GraphQL server is now running.");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Returns 1 if running, 0 otherwise
|
||||
async function isGraphQLServerRunning() {
|
||||
try {
|
||||
const response = await $.get('api/app_state.json?nocache=' + Date.now());
|
||||
console.log("graphQLServerStarted: " + response["graphQLServerStarted"]);
|
||||
setCache("graphQLServerStarted", response["graphQLServerStarted"]);
|
||||
return response["graphQLServerStarted"];
|
||||
} catch (error) {
|
||||
console.error("Failed to check GraphQL server status:", error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Check if the code has been executed before by checking sessionStorage
|
||||
function isAppInitialized() {
|
||||
// return arraysContainSameValues(getCache("completedCalls").split(',').filter(Boolean), completedCalls_final);
|
||||
|
||||
// loading settings + 1 (or 2 language files if not english) + device cache.
|
||||
completedCallsCount_final = getLangCode() == 'en_us' ? 3 : 4 ;
|
||||
completedCalls = parseInt(getCache("completedCallsCount"));
|
||||
shouldBeCompletedCalls = getLangCode() == 'en_us' ? 3 : 4;
|
||||
|
||||
return (parseInt(getCache("completedCallsCount")) >= completedCallsCount_final);
|
||||
return (
|
||||
completedCalls >= shouldBeCompletedCalls
|
||||
);
|
||||
}
|
||||
|
||||
// Define a function that will execute the code only once
|
||||
// -----------------------------------------------------------------------------
|
||||
// Main execution logic
|
||||
async function executeOnce() {
|
||||
showSpinner();
|
||||
|
||||
if (!isAppInitialized()) {
|
||||
try {
|
||||
console.log("HERE");
|
||||
|
||||
await waitForGraphQLServer(); // Wait for the server to start
|
||||
|
||||
await cacheDevices();
|
||||
await cacheSettings();
|
||||
await cacheStrings();
|
||||
|
||||
await cacheStrings();
|
||||
|
||||
console.log("✅ All AJAX callbacks have completed");
|
||||
onAllCallsComplete();
|
||||
} catch (error) {
|
||||
@@ -1298,6 +1344,7 @@ async function executeOnce() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Function to handle successful completion of an AJAX call
|
||||
const handleSuccess = (callName) => {
|
||||
|
||||
@@ -23,7 +23,7 @@ function initDeviceSelectors(devicesListAll_JSON) {
|
||||
// Loop through the devices list
|
||||
devicesList.forEach(function(device) {
|
||||
|
||||
selectorFieldsHTML += `<option value="${device.dev_MAC}">${device.dev_Name}</option>`;
|
||||
selectorFieldsHTML += `<option value="${device.devMac}">${device.devName}</option>`;
|
||||
});
|
||||
|
||||
selector = `<div class="db_info_table_row col-sm-12" >
|
||||
|
||||
@@ -77,11 +77,11 @@
|
||||
|
||||
settingsData = res["data"];
|
||||
|
||||
excludedColumns = ["NEWDEV_dev_MAC", "NEWDEV_dev_FirstConnection", "NEWDEV_dev_LastConnection", "NEWDEV_dev_LastNotification", "NEWDEV_dev_LastIP", "NEWDEV_dev_StaticIP", "NEWDEV_dev_ScanCycle", "NEWDEV_dev_PresentLastScan" ]
|
||||
excludedColumns = ["NEWDEV_devMac", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devLastNotification", "NEWDEV_devLastIP", "NEWDEV_devStaticIP", "NEWDEV_devScan", "NEWDEV_devPresentLastScan" ]
|
||||
|
||||
const relevantColumns = settingsData.filter(set =>
|
||||
set.Group === "NEWDEV" &&
|
||||
set.Code_Name.includes("_dev_") &&
|
||||
set.Code_Name.includes("_dev") &&
|
||||
!excludedColumns.includes(set.Code_Name) &&
|
||||
!set.Code_Name.includes("__metadata")
|
||||
);
|
||||
@@ -143,13 +143,13 @@
|
||||
|
||||
console.log(columns[j].Code_Name)
|
||||
// Handle Icons as they need a preview
|
||||
if(columns[j].Code_Name == 'NEWDEV_dev_Icon')
|
||||
if(columns[j].Code_Name == 'NEWDEV_devIcon')
|
||||
{
|
||||
input = `
|
||||
<span class="input-group-addon iconPreview" my-customid="NEWDEV_dev_Icon_preview"></span>
|
||||
<span class="input-group-addon iconPreview" my-customid="NEWDEV_devIcon_preview"></span>
|
||||
<select class="form-control"
|
||||
onChange="updateIconPreview(this)"
|
||||
my-customparams="NEWDEV_dev_Icon,NEWDEV_dev_Icon_preview"
|
||||
my-customparams="NEWDEV_devIcon,NEWDEV_devIcon_preview"
|
||||
id="${columns[j].Code_Name}"
|
||||
data-my-column="${columns[j].Code_Name}"
|
||||
data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}" >
|
||||
@@ -283,7 +283,7 @@
|
||||
console.log(columnValue);
|
||||
|
||||
// update selected
|
||||
executeAction('update', 'dev_MAC', selectorMacs(), targetColumns, columnValue )
|
||||
executeAction('update', 'devMac', selectorMacs(), targetColumns, columnValue )
|
||||
|
||||
|
||||
}
|
||||
@@ -333,7 +333,7 @@ function askDeleteSelectedDevices () {
|
||||
function deleteSelectedDevices()
|
||||
{
|
||||
macs_tmp = selectorMacs()
|
||||
executeAction('delete', 'dev_MAC', macs_tmp )
|
||||
executeAction('delete', 'devMac', macs_tmp )
|
||||
write_notification('[Multi edit] Manually deleted devices with MACs:' + macs_tmp, 'info')
|
||||
}
|
||||
|
||||
|
||||
@@ -162,14 +162,14 @@
|
||||
}
|
||||
|
||||
// Get all leafs connected to a node based on the node_mac
|
||||
$func_sql = 'SELECT dev_Network_Node_port as port,
|
||||
dev_MAC as mac,
|
||||
dev_PresentLastScan as online,
|
||||
dev_Name as name,
|
||||
dev_DeviceType as type,
|
||||
dev_LastIP as last_ip,
|
||||
(select dev_DeviceType from Devices a where dev_MAC = "'.$node_mac.'") as node_type
|
||||
FROM Devices WHERE dev_Network_Node_MAC_ADDR = "'.$node_mac.'" order by port, name asc';
|
||||
$func_sql = 'SELECT devParentPort as port,
|
||||
devMac as mac,
|
||||
devPresentLastScan as online,
|
||||
devName as name,
|
||||
devType as type,
|
||||
devLastIP as last_ip,
|
||||
(select devType from Devices a where devMac = "'.$node_mac.'") as node_type
|
||||
FROM Devices WHERE devParentMAC = "'.$node_mac.'" order by port, name asc';
|
||||
|
||||
global $db;
|
||||
$func_result = $db->query($func_sql);
|
||||
@@ -278,21 +278,21 @@
|
||||
$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_Icon as node_icon
|
||||
SELECT a.devName as node_name,
|
||||
a.devMac as node_mac,
|
||||
a.devPresentLastScan as online,
|
||||
a.devType as node_type,
|
||||
a.devParentMAC as parent_mac,
|
||||
a.devIcon as node_icon
|
||||
FROM Devices a
|
||||
WHERE a.dev_DeviceType in (".$networkDeviceTypes.")
|
||||
WHERE a.devType in (".$networkDeviceTypes.")
|
||||
) t1
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT b.dev_Network_Node_MAC_ADDR as node_mac_2,
|
||||
SELECT b.devParentMAC as node_mac_2,
|
||||
count() as node_ports_count
|
||||
FROM Devices b
|
||||
WHERE b.dev_Network_Node_MAC_ADDR NOT NULL group by b.dev_Network_Node_MAC_ADDR
|
||||
WHERE b.devParentMAC NOT NULL group by b.devParentMAC
|
||||
) t2
|
||||
ON (t1.node_mac = t2.node_mac_2);
|
||||
";
|
||||
@@ -360,15 +360,15 @@
|
||||
|
||||
// Get all Unassigned / unconnected nodes
|
||||
$func_sql = 'SELECT
|
||||
dev_MAC AS mac,
|
||||
dev_PresentLastScan AS online,
|
||||
dev_Name AS name,
|
||||
dev_LastIP AS last_ip,
|
||||
dev_Network_Node_MAC_ADDR
|
||||
devMac AS mac,
|
||||
devPresentLastScan AS online,
|
||||
devName AS name,
|
||||
devLastIP AS last_ip,
|
||||
devParentMAC
|
||||
FROM Devices
|
||||
WHERE dev_Network_Node_MAC_ADDR IS NULL
|
||||
OR dev_Network_Node_MAC_ADDR IN ("", " ", "undefined", "null")
|
||||
AND dev_MAC NOT LIKE "%internet%"
|
||||
WHERE devParentMAC IS NULL
|
||||
OR devParentMAC IN ("", " ", "undefined", "null")
|
||||
AND devMac NOT LIKE "%internet%"
|
||||
ORDER BY name ASC;';
|
||||
|
||||
global $db;
|
||||
|
||||
@@ -73,22 +73,22 @@ function getDeviceData() {
|
||||
|
||||
// Device Data
|
||||
$sql = 'SELECT rowid, *,
|
||||
CASE WHEN dev_AlertDeviceDown !=0 AND dev_PresentLastScan=0 THEN "Down"
|
||||
WHEN dev_PresentLastScan=1 THEN "On-line"
|
||||
ELSE "Off-line" END as dev_Status
|
||||
CASE WHEN devAlertDown !=0 AND devPresentLastScan=0 THEN "Down"
|
||||
WHEN devPresentLastScan=1 THEN "On-line"
|
||||
ELSE "Off-line" END as devStatus
|
||||
FROM Devices
|
||||
WHERE dev_MAC="'. $mac .'" or cast(rowid as text)="'. $mac. '"';
|
||||
WHERE devMac="'. $mac .'" or cast(rowid as text)="'. $mac. '"';
|
||||
$result = $db->query($sql);
|
||||
$row = $result -> fetchArray (SQLITE3_ASSOC);
|
||||
$deviceData = $row;
|
||||
$mac = $deviceData['dev_MAC'];
|
||||
$mac = $deviceData['devMac'];
|
||||
|
||||
$deviceData['dev_Network_Node_MAC_ADDR'] = $row['dev_Network_Node_MAC_ADDR'];
|
||||
$deviceData['dev_Network_Node_port'] = $row['dev_Network_Node_port'];
|
||||
$deviceData['dev_FirstConnection'] = formatDate ($row['dev_FirstConnection']); // Date formated
|
||||
$deviceData['dev_LastConnection'] = formatDate ($row['dev_LastConnection']); // Date formated
|
||||
$deviceData['devParentMAC'] = $row['devParentMAC'];
|
||||
$deviceData['devParentPort'] = $row['devParentPort'];
|
||||
$deviceData['devFirstConnection'] = formatDate ($row['devFirstConnection']); // Date formated
|
||||
$deviceData['devLastConnection'] = formatDate ($row['devLastConnection']); // Date formated
|
||||
|
||||
$deviceData['dev_RandomMAC'] = isRandomMAC($mac);
|
||||
$deviceData['devRandomMAC'] = isRandomMAC($mac);
|
||||
|
||||
// Count Totals
|
||||
$condition = ' WHERE eve_MAC="'. $mac .'" AND eve_DateTime >= '. $periodDate;
|
||||
@@ -101,19 +101,19 @@ function getDeviceData() {
|
||||
OR ses_StillConnected = 1 )';
|
||||
$result = $db->query($sql);
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$deviceData['dev_Sessions'] = $row[0];
|
||||
$deviceData['devSessions'] = $row[0];
|
||||
|
||||
// Events
|
||||
$sql = 'SELECT COUNT(*) FROM Events '. $condition .' AND eve_EventType <> "Connected" AND eve_EventType <> "Disconnected" ';
|
||||
$result = $db->query($sql);
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$deviceData['dev_Events'] = $row[0];
|
||||
$deviceData['devEvents'] = $row[0];
|
||||
|
||||
// Down Alerts
|
||||
$sql = 'SELECT COUNT(*) FROM Events '. $condition .' AND eve_EventType = "Device Down"';
|
||||
$result = $db->query($sql);
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$deviceData['dev_DownAlerts'] = $row[0];
|
||||
$deviceData['devDownAlerts'] = $row[0];
|
||||
|
||||
// Get current date using php, sql datetime does not return time respective to timezone.
|
||||
$currentdate = date("Y-m-d H:i:s");
|
||||
@@ -130,7 +130,7 @@ function getDeviceData() {
|
||||
OR ses_StillConnected = 1 )';
|
||||
$result = $db->query($sql);
|
||||
$row = $result -> fetchArray (SQLITE3_NUM);
|
||||
$deviceData['dev_PresenceHours'] = round ($row[0]);
|
||||
$deviceData['devPresenceHours'] = round ($row[0]);
|
||||
|
||||
// Return json
|
||||
echo (json_encode ($deviceData));
|
||||
@@ -145,27 +145,27 @@ function setDeviceData() {
|
||||
|
||||
// sql
|
||||
$sql = 'UPDATE Devices SET
|
||||
dev_Name = "'. quotes($_REQUEST['name']) .'",
|
||||
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']) .'",
|
||||
dev_Comments = "'. quotes($_REQUEST['comments']) .'",
|
||||
dev_Network_Node_MAC_ADDR = "'. quotes($_REQUEST['networknode']).'",
|
||||
dev_Network_Node_port = "'. quotes($_REQUEST['networknodeport']).'",
|
||||
dev_SSID = "'. quotes($_REQUEST['ssid']).'",
|
||||
dev_NetworkSite = "'. quotes($_REQUEST['networksite']).'",
|
||||
dev_StaticIP = "'. quotes($_REQUEST['staticIP']) .'",
|
||||
dev_ScanCycle = "'. quotes($_REQUEST['scancycle']) .'",
|
||||
dev_AlertEvents = "'. quotes($_REQUEST['alertevents']) .'",
|
||||
dev_AlertDeviceDown = "'. quotes($_REQUEST['alertdown']) .'",
|
||||
dev_SkipRepeated = "'. quotes($_REQUEST['skiprepeated']) .'",
|
||||
dev_NewDevice = "'. quotes($_REQUEST['newdevice']) .'",
|
||||
dev_Archived = "'. quotes($_REQUEST['archived']) .'"
|
||||
WHERE dev_MAC="' . $_REQUEST['mac'] .'"';
|
||||
devName = "'. quotes($_REQUEST['name']) .'",
|
||||
devOwner = "'. quotes($_REQUEST['owner']) .'",
|
||||
devType = "'. quotes($_REQUEST['type']) .'",
|
||||
devVendor = "'. quotes($_REQUEST['vendor']) .'",
|
||||
devIcon = "'. quotes($_REQUEST['icon']) .'",
|
||||
devFavorite = "'. quotes($_REQUEST['favorite']) .'",
|
||||
devGroup = "'. quotes($_REQUEST['group']) .'",
|
||||
devLocation = "'. quotes($_REQUEST['location']) .'",
|
||||
devComments = "'. quotes($_REQUEST['comments']) .'",
|
||||
devParentMAC = "'. quotes($_REQUEST['networknode']).'",
|
||||
devParentPort = "'. quotes($_REQUEST['networknodeport']).'",
|
||||
devSSID = "'. quotes($_REQUEST['ssid']).'",
|
||||
devSite = "'. quotes($_REQUEST['networksite']).'",
|
||||
devStaticIP = "'. quotes($_REQUEST['staticIP']) .'",
|
||||
devScan = "'. quotes($_REQUEST['scancycle']) .'",
|
||||
devAlertEvents = "'. quotes($_REQUEST['alertevents']) .'",
|
||||
devAlertDown = "'. quotes($_REQUEST['alertdown']) .'",
|
||||
devSkipRepeated = "'. quotes($_REQUEST['skiprepeated']) .'",
|
||||
devIsNew = "'. quotes($_REQUEST['newdevice']) .'",
|
||||
devIsArchived = "'. quotes($_REQUEST['archived']) .'"
|
||||
WHERE devMac="' . $_REQUEST['mac'] .'"';
|
||||
// update Data
|
||||
$result = $db->query($sql);
|
||||
|
||||
@@ -185,7 +185,7 @@ function deleteDevice() {
|
||||
global $db;
|
||||
|
||||
// sql
|
||||
$sql = 'DELETE FROM Devices WHERE dev_MAC="' . $_REQUEST['mac'] .'"';
|
||||
$sql = 'DELETE FROM Devices WHERE devMac="' . $_REQUEST['mac'] .'"';
|
||||
// execute sql
|
||||
$result = $db->query($sql);
|
||||
|
||||
@@ -204,7 +204,7 @@ function deleteAllWithEmptyMACs() {
|
||||
global $db;
|
||||
|
||||
// sql
|
||||
$sql = 'DELETE FROM Devices WHERE dev_MAC=""';
|
||||
$sql = 'DELETE FROM Devices WHERE devMac=""';
|
||||
// execute sql
|
||||
$result = $db->query($sql);
|
||||
|
||||
@@ -223,7 +223,7 @@ function deleteUnknownDevices() {
|
||||
global $db;
|
||||
|
||||
// sql
|
||||
$sql = 'DELETE FROM Devices WHERE dev_Name="(unknown)" OR dev_Name="(name not found)"';
|
||||
$sql = 'DELETE FROM Devices WHERE devName="(unknown)" OR devName="(name not found)"';
|
||||
// execute sql
|
||||
$result = $db->query($sql);
|
||||
|
||||
@@ -598,30 +598,30 @@ function getDevicesList() {
|
||||
|
||||
// This object is used to map from the old order ( second parameter, first number) to the new mapping, that is represented by the 3rd parameter (Second number)
|
||||
$columnOrderMapping = array(
|
||||
array("dev_Name", 0, 0),
|
||||
array("dev_Owner", 1, 1),
|
||||
array("dev_DeviceType", 2, 2),
|
||||
array("dev_Icon", 3, 3),
|
||||
array("dev_Favorite", 4, 4),
|
||||
array("dev_Group", 5, 5),
|
||||
array("dev_FirstConnection", 6, 6),
|
||||
array("dev_LastConnection", 7, 7),
|
||||
array("dev_LastIP", 8, 8),
|
||||
array("dev_MAC", 9, 9),
|
||||
array("dev_Status", 10, 10),
|
||||
array("dev_MAC_full", 11, 11),
|
||||
array("dev_LastIP_orderable", 12, 12),
|
||||
array("devName", 0, 0),
|
||||
array("devOwner", 1, 1),
|
||||
array("devType", 2, 2),
|
||||
array("devIcon", 3, 3),
|
||||
array("devFavorite", 4, 4),
|
||||
array("devGroup", 5, 5),
|
||||
array("devFirstConnection", 6, 6),
|
||||
array("devLastConnection", 7, 7),
|
||||
array("devLastIP", 8, 8),
|
||||
array("devMac", 9, 9),
|
||||
array("devStatus", 10, 10),
|
||||
array("devMac_full", 11, 11),
|
||||
array("devLastIP_orderable", 12, 12),
|
||||
array("rowid", 13, 13),
|
||||
array("dev_Network_Node_MAC_ADDR", 14, 14),
|
||||
array("devParentMAC", 14, 14),
|
||||
array("connected_devices", 15, 15),
|
||||
array("dev_Location", 16, 16),
|
||||
array("dev_Vendor", 17, 17),
|
||||
array("dev_Network_Node_port", 18, 18),
|
||||
array("dev_GUID", 19, 19),
|
||||
array("dev_SyncHubNodeName", 20, 20),
|
||||
array("dev_NetworkSite", 21, 21),
|
||||
array("dev_SSID", 22, 22),
|
||||
array("dev_SourcePlugin", 23, 23)
|
||||
array("devLocation", 16, 16),
|
||||
array("devVendor", 17, 17),
|
||||
array("devParentPort", 18, 18),
|
||||
array("devGUID", 19, 19),
|
||||
array("devSyncHubNode", 20, 20),
|
||||
array("devSite", 21, 21),
|
||||
array("devSSID", 22, 22),
|
||||
array("devSourcePlugin", 23, 23)
|
||||
);
|
||||
|
||||
if($forceDefaultOrder == FALSE)
|
||||
@@ -650,19 +650,19 @@ function getDevicesList() {
|
||||
|
||||
$sql = 'SELECT * FROM (
|
||||
SELECT rowid, *, CASE
|
||||
WHEN t1.dev_AlertDeviceDown !=0 AND t1.dev_PresentLastScan=0 THEN "Down"
|
||||
WHEN t1.dev_NewDevice=1 THEN "New"
|
||||
WHEN t1.dev_PresentLastScan=1 THEN "On-line"
|
||||
ELSE "Off-line" END AS dev_Status
|
||||
WHEN t1.devAlertDown !=0 AND t1.devPresentLastScan=0 THEN "Down"
|
||||
WHEN t1.devIsNew=1 THEN "New"
|
||||
WHEN t1.devPresentLastScan=1 THEN "On-line"
|
||||
ELSE "Off-line" END AS devStatus
|
||||
FROM Devices t1 '.$condition.') t3
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT dev_Network_Node_MAC_ADDR as dev_Network_Node_MAC_ADDR_t2, dev_MAC as dev_MAC_t2,
|
||||
SELECT devParentMAC as devParentMAC_t2, devMac as devMac_t2,
|
||||
count() as connected_devices
|
||||
FROM Devices b
|
||||
WHERE b.dev_Network_Node_MAC_ADDR NOT NULL group by b.dev_Network_Node_MAC_ADDR
|
||||
WHERE b.devParentMAC NOT NULL group by b.devParentMAC
|
||||
) t2
|
||||
ON (t3.dev_MAC = t2.dev_Network_Node_MAC_ADDR_t2);';
|
||||
ON (t3.devMac = t2.devParentMAC_t2);';
|
||||
|
||||
$result = $db->query($sql);
|
||||
|
||||
@@ -671,31 +671,31 @@ function getDevicesList() {
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
|
||||
$defaultOrder = array (
|
||||
$row['dev_Name'],
|
||||
$row['dev_Owner'],
|
||||
handleNull($row['dev_DeviceType']),
|
||||
handleNull($row['dev_Icon'], "PGkgY2xhc3M9J2ZhIGZhLWxhcHRvcCc+PC9pPg=="), // laptop icon
|
||||
$row['dev_Favorite'],
|
||||
$row['dev_Group'],
|
||||
$row['devName'],
|
||||
$row['devOwner'],
|
||||
handleNull($row['devType']),
|
||||
handleNull($row['devIcon'], "PGkgY2xhc3M9J2ZhIGZhLWxhcHRvcCc+PC9pPg=="), // laptop icon
|
||||
$row['devFavorite'],
|
||||
$row['devGroup'],
|
||||
// ----
|
||||
formatDate ($row['dev_FirstConnection']),
|
||||
formatDate ($row['dev_LastConnection']),
|
||||
$row['dev_LastIP'],
|
||||
( isRandomMAC($row['dev_MAC']) ),
|
||||
$row['dev_Status'],
|
||||
$row['dev_MAC'], // MAC (hidden)
|
||||
formatIPlong ($row['dev_LastIP']), // IP orderable
|
||||
formatDate ($row['devFirstConnection']),
|
||||
formatDate ($row['devLastConnection']),
|
||||
$row['devLastIP'],
|
||||
( isRandomMAC($row['devMac']) ),
|
||||
$row['devStatus'],
|
||||
$row['devMac'], // MAC (hidden)
|
||||
formatIPlong ($row['devLastIP']), // IP orderable
|
||||
$row['rowid'], // Rowid (hidden)
|
||||
handleNull($row['dev_Network_Node_MAC_ADDR']),
|
||||
handleNull($row['devParentMAC']),
|
||||
handleNull($row['connected_devices']),
|
||||
handleNull($row['dev_Location']),
|
||||
handleNull($row['dev_Vendor']),
|
||||
handleNull($row['dev_Network_Node_port']),
|
||||
handleNull($row['dev_GUID']),
|
||||
handleNull($row['dev_SyncHubNodeName']),
|
||||
handleNull($row['dev_NetworkSite']),
|
||||
handleNull($row['dev_SSID']),
|
||||
handleNull($row['dev_SourcePlugin'])
|
||||
handleNull($row['devLocation']),
|
||||
handleNull($row['devVendor']),
|
||||
handleNull($row['devParentPort']),
|
||||
handleNull($row['devGUID']),
|
||||
handleNull($row['devSyncHubNode']),
|
||||
handleNull($row['devSite']),
|
||||
handleNull($row['devSSID']),
|
||||
handleNull($row['devSourcePlugin'])
|
||||
);
|
||||
|
||||
$newOrder = array();
|
||||
@@ -758,13 +758,13 @@ function getDevicesListCalendar() {
|
||||
// arrays of rows
|
||||
$tableData = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
if ($row['dev_Favorite'] == 1) {
|
||||
$row['dev_Name'] = '<span class="text-yellow">★</span> '. $row['dev_Name'];
|
||||
if ($row['devFavorite'] == 1) {
|
||||
$row['devName'] = '<span class="text-yellow">★</span> '. $row['devName'];
|
||||
}
|
||||
|
||||
$tableData[] = array ('id' => $row['dev_MAC'],
|
||||
'title' => $row['dev_Name'],
|
||||
'favorite' => $row['dev_Favorite']);
|
||||
$tableData[] = array ('id' => $row['devMac'],
|
||||
'title' => $row['devName'],
|
||||
'favorite' => $row['devFavorite']);
|
||||
}
|
||||
|
||||
// Return json
|
||||
@@ -781,14 +781,14 @@ function getIcons() {
|
||||
global $db;
|
||||
|
||||
// Device Data
|
||||
$sql = 'select dev_Icon from Devices group by dev_Icon';
|
||||
$sql = 'select devIcon from Devices group by devIcon';
|
||||
|
||||
$result = $db->query($sql);
|
||||
|
||||
// arrays of rows
|
||||
$tableData = array();
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
$icon = handleNull($row['dev_Icon'], "<i class='fa fa-laptop'></i>");
|
||||
$icon = handleNull($row['devIcon'], "<i class='fa fa-laptop'></i>");
|
||||
// Push row data
|
||||
$tableData[] = array('id' => $icon,
|
||||
'name' => $icon );
|
||||
@@ -821,7 +821,7 @@ function getDevices() {
|
||||
global $db;
|
||||
|
||||
// Device Data
|
||||
$sql = 'select dev_MAC, dev_Name from Devices';
|
||||
$sql = 'select devMac, devName from Devices';
|
||||
|
||||
$result = $db->query($sql);
|
||||
|
||||
@@ -829,8 +829,8 @@ function getDevices() {
|
||||
$tableData = array();
|
||||
|
||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||
$name = handleNull($row['dev_Name'], "(unknown)");
|
||||
$mac = handleNull($row['dev_MAC'], "(unknown)");
|
||||
$name = handleNull($row['devName'], "(unknown)");
|
||||
$mac = handleNull($row['devMac'], "(unknown)");
|
||||
// Push row data
|
||||
$tableData[] = array('id' => $mac,
|
||||
'name' => $name );
|
||||
@@ -858,7 +858,7 @@ function updateNetworkLeaf()
|
||||
{
|
||||
global $db;
|
||||
// sql
|
||||
$sql = 'UPDATE Devices SET "dev_Network_Node_MAC_ADDR" = "'. $nodeMac .'" WHERE "dev_MAC"="' . $leafMac.'"' ;
|
||||
$sql = 'UPDATE Devices SET "devParentMAC" = "'. $nodeMac .'" WHERE "devMac"="' . $leafMac.'"' ;
|
||||
// update Data
|
||||
$result = $db->query($sql);
|
||||
|
||||
@@ -885,7 +885,7 @@ function overwriteIconType()
|
||||
{
|
||||
global $db;
|
||||
// sql
|
||||
$sql = 'UPDATE Devices SET "dev_Icon" = "'. $icon .'" where dev_DeviceType in (select dev_DeviceType from Devices where dev_MAC = "' . $mac.'")' ;
|
||||
$sql = 'UPDATE Devices SET "devIcon" = "'. $icon .'" where devType in (select devType from Devices where devMac = "' . $mac.'")' ;
|
||||
// update Data
|
||||
$result = $db->query($sql);
|
||||
|
||||
@@ -935,19 +935,19 @@ function copyFromDevice() {
|
||||
$result = $db->query($sql);
|
||||
|
||||
// create temporary table with the source data
|
||||
$sql = "CREATE TABLE temp_devices AS SELECT * FROM Devices WHERE dev_MAC = '". $MAC_FROM . "';";
|
||||
$sql = "CREATE TABLE temp_devices AS SELECT * FROM Devices WHERE devMac = '". $MAC_FROM . "';";
|
||||
$result = $db->query($sql);
|
||||
|
||||
// update temporary table with the correct target MAC
|
||||
$sql = "UPDATE temp_devices SET dev_MAC = '". $MAC_TO . "';";
|
||||
$sql = "UPDATE temp_devices SET devMac = '". $MAC_TO . "';";
|
||||
$result = $db->query($sql);
|
||||
|
||||
// delete previous entry
|
||||
$sql = "DELETE FROM Devices WHERE dev_MAC = '". $MAC_TO . "';";
|
||||
$sql = "DELETE FROM Devices WHERE devMac = '". $MAC_TO . "';";
|
||||
$result = $db->query($sql);
|
||||
|
||||
// insert new entry with the correct target MAC from the temporary table
|
||||
$sql = "INSERT INTO Devices SELECT * FROM temp_devices WHERE dev_MAC = '".$MAC_TO."'";
|
||||
$sql = "INSERT INTO Devices SELECT * FROM temp_devices WHERE devMac = '".$MAC_TO."'";
|
||||
$result = $db->query($sql);
|
||||
|
||||
// clean-up temporary table
|
||||
@@ -968,13 +968,13 @@ function copyFromDevice() {
|
||||
//------------------------------------------------------------------------------
|
||||
function getDeviceCondition ($deviceStatus) {
|
||||
switch ($deviceStatus) {
|
||||
case 'all': return 'WHERE dev_Archived=0'; break;
|
||||
case 'my': return 'WHERE dev_Archived=0'; break;
|
||||
case 'connected': return 'WHERE dev_Archived=0 AND dev_PresentLastScan=1'; break;
|
||||
case 'favorites': return 'WHERE dev_Archived=0 AND dev_Favorite=1'; break;
|
||||
case 'new': return 'WHERE dev_Archived=0 AND dev_NewDevice=1'; break;
|
||||
case 'down': return 'WHERE dev_Archived=0 AND dev_AlertDeviceDown !=0 AND dev_PresentLastScan=0'; break;
|
||||
case 'archived': return 'WHERE dev_Archived=1'; break;
|
||||
case 'all': return 'WHERE devIsArchived=0'; break;
|
||||
case 'my': return 'WHERE devIsArchived=0'; break;
|
||||
case 'connected': return 'WHERE devIsArchived=0 AND devPresentLastScan=1'; break;
|
||||
case 'favorites': return 'WHERE devIsArchived=0 AND devFavorite=1'; break;
|
||||
case 'new': return 'WHERE devIsArchived=0 AND devIsNew=1'; break;
|
||||
case 'down': return 'WHERE devIsArchived=0 AND devAlertDown !=0 AND devPresentLastScan=0'; break;
|
||||
case 'archived': return 'WHERE devIsArchived=1'; break;
|
||||
default: return 'WHERE 1=0'; break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,12 +108,12 @@ function getEvents() {
|
||||
$periodDate = getDateFromPeriod();
|
||||
|
||||
// SQL
|
||||
$SQL1 = 'SELECT eve_DateTime AS eve_DateTimeOrder, dev_name, dev_owner, eve_DateTime, eve_EventType, NULL, NULL, NULL, NULL, eve_IP, NULL, eve_AdditionalInfo, NULL, Dev_MAC, eve_PendingAlertEmail
|
||||
$SQL1 = 'SELECT eve_DateTime AS eve_DateTimeOrder, devName, devOwner, eve_DateTime, eve_EventType, NULL, NULL, NULL, NULL, eve_IP, NULL, eve_AdditionalInfo, NULL, devMac, eve_PendingAlertEmail
|
||||
FROM Events_Devices
|
||||
WHERE eve_DateTime >= '. $periodDate;
|
||||
|
||||
$SQL2 = 'SELECT IFNULL (ses_DateTimeConnection, ses_DateTimeDisconnection) ses_DateTimeOrder,
|
||||
dev_name, dev_owner, Null, Null, ses_DateTimeConnection, ses_DateTimeDisconnection, NULL, NULL, ses_IP, NULL, ses_AdditionalInfo, ses_StillConnected, Dev_MAC
|
||||
devName, devOwner, Null, Null, ses_DateTimeConnection, ses_DateTimeDisconnection, NULL, NULL, ses_IP, NULL, ses_AdditionalInfo, ses_StillConnected, devMac
|
||||
FROM Sessions_Devices ';
|
||||
|
||||
// SQL Variations for status
|
||||
|
||||
84
front/php/server/query_graphql.php
Executable file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
// ---- IMPORTS ----
|
||||
//------------------------------------------------------------------------------
|
||||
// Check if authenticated
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||
// Get init.php
|
||||
require dirname(__FILE__).'/../server/init.php';
|
||||
// ---- IMPORTS ----
|
||||
|
||||
|
||||
// Helper function to get GraphQL URL (you can replace this with environment variables)
|
||||
function getGraphQLUrl() {
|
||||
$port = getSettingValue("GRAPHQL_PORT"); // Port for the GraphQL server
|
||||
return "0.0.0.0:$port/graphql"; // Full URL to the GraphQL endpoint
|
||||
}
|
||||
|
||||
// Function to make a GraphQL query
|
||||
function queryGraphQL($query, $variables = null) {
|
||||
$url = getGraphQLUrl();
|
||||
|
||||
// Prepare the request data
|
||||
$data = [
|
||||
'query' => $query
|
||||
];
|
||||
|
||||
// prepare header
|
||||
$api_token = getSettingValue("API_TOKEN");
|
||||
$headers = [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer ' . $api_token // Add Authorization header
|
||||
];
|
||||
|
||||
|
||||
// Add variables if provided
|
||||
if ($variables) {
|
||||
$data['variables'] = $variables;
|
||||
}
|
||||
|
||||
// Encode the data as JSON
|
||||
$dataJson = json_encode($data);
|
||||
|
||||
// Initialize cURL
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataJson);
|
||||
|
||||
// Execute the request and handle errors
|
||||
$response = curl_exec($ch);
|
||||
if ($response === false) {
|
||||
error_log('GraphQL Request Error: ' . curl_error($ch));
|
||||
return ["error" => "Request failed (GraphQL server might be down). URL: " .$url . " Error: ". curl_error($ch)];
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
return json_decode($response, true); // Decode and return the JSON response
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Handle incoming requests
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// Decode the JSON input from the AJAX request
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
// Ensure the query is set
|
||||
if (!isset($input['query'])) {
|
||||
echo json_encode(['error' => 'No query provided']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Extract the query and variables
|
||||
$query = $input['query'];
|
||||
$variables = isset($input['variables']) ? $input['variables'] : null;
|
||||
|
||||
// Call the GraphQL function
|
||||
$result = queryGraphQL($query, $variables);
|
||||
|
||||
// Send the response back to the client
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($result);
|
||||
}
|
||||
?>
|
||||
@@ -548,36 +548,36 @@ function decodeSpecialChars($str) {
|
||||
// -------------------------------------------------------------------------------------------
|
||||
function getDevicesColumns(){
|
||||
|
||||
$columns = ["dev_MAC",
|
||||
"dev_Name",
|
||||
"dev_Owner",
|
||||
"dev_DeviceType",
|
||||
"dev_Vendor",
|
||||
"dev_Favorite",
|
||||
"dev_Group",
|
||||
"dev_Comments",
|
||||
"dev_FirstConnection",
|
||||
"dev_LastConnection",
|
||||
"dev_LastIP",
|
||||
"dev_StaticIP",
|
||||
"dev_ScanCycle",
|
||||
"dev_LogEvents",
|
||||
"dev_AlertEvents",
|
||||
"dev_AlertDeviceDown",
|
||||
"dev_SkipRepeated",
|
||||
"dev_LastNotification",
|
||||
"dev_PresentLastScan",
|
||||
"dev_NewDevice",
|
||||
"dev_Location",
|
||||
"dev_Archived",
|
||||
"dev_Network_Node_port",
|
||||
"dev_Network_Node_MAC_ADDR",
|
||||
"dev_Icon",
|
||||
"dev_GUID",
|
||||
"dev_SyncHubNodeName",
|
||||
"dev_NetworkSite",
|
||||
"dev_SSID",
|
||||
"dev_SourcePlugin"
|
||||
$columns = ["devMac",
|
||||
"devName",
|
||||
"devOwner",
|
||||
"devType",
|
||||
"devVendor",
|
||||
"devFavorite",
|
||||
"devGroup",
|
||||
"devComments",
|
||||
"devFirstConnection",
|
||||
"devLastConnection",
|
||||
"devLastIP",
|
||||
"devStaticIP",
|
||||
"devScan",
|
||||
"devLogEvents",
|
||||
"devAlertEvents",
|
||||
"devAlertDown",
|
||||
"devSkipRepeated",
|
||||
"devLastNotification",
|
||||
"devPresentLastScan",
|
||||
"devIsNew",
|
||||
"devLocation",
|
||||
"devIsArchived",
|
||||
"devParentPort",
|
||||
"devParentMAC",
|
||||
"devIcon",
|
||||
"devGUID",
|
||||
"devSyncHubNode",
|
||||
"devSite",
|
||||
"devSSID",
|
||||
"devSourcePlugin"
|
||||
];
|
||||
|
||||
return $columns;
|
||||
|
||||
@@ -255,28 +255,28 @@
|
||||
</a>
|
||||
<ul class="treeview-menu" style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('devices.php', 'deviceDetails.php') ) ){ echo 'block'; } else {echo 'none';} ?>;">
|
||||
<li>
|
||||
<a href="devices.php#my" onclick="initializeDatatable('my')" > <?= lang("Device_Shortcut_AllDevices");?> </a>
|
||||
<a href="devices.php#my_devices" onclick="forceLoadUrl('devices.php#my_devices')" > <?= lang("Device_Shortcut_AllDevices");?> </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="devices.php#connected" onclick="initializeDatatable('connected')" > <?= lang("Device_Shortcut_Connected");?> </a>
|
||||
<a href="devices.php#connected" onclick="forceLoadUrl('devices.php#connected')" > <?= lang("Device_Shortcut_Connected");?> </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="devices.php#favorites" onclick="initializeDatatable('favorites')" > <?= lang("Device_Shortcut_Favorites");?> </a>
|
||||
<a href="devices.php#favorites" onclick="forceLoadUrl('devices.php#favorites')" > <?= lang("Device_Shortcut_Favorites");?> </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="devices.php#new" onclick="initializeDatatable('new')" > <?= lang("Device_Shortcut_NewDevices");?> </a>
|
||||
<a href="devices.php#new" onclick="forceLoadUrl('devices.php#new')" > <?= lang("Device_Shortcut_NewDevices");?> </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="devices.php#down" onclick="initializeDatatable('down')" > <?= lang("Device_Shortcut_DownOnly");?> </a>
|
||||
<a href="devices.php#down" onclick="forceLoadUrl('devices.php#down')" > <?= lang("Device_Shortcut_DownOnly");?> </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="devices.php#offline" onclick="initializeDatatable('offline')" > <?= lang("Gen_Offline");?> </a>
|
||||
<a href="devices.php#offline" onclick="forceLoadUrl('devices.php#offline')" > <?= lang("Gen_Offline");?> </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="devices.php#archived" onclick="initializeDatatable('archived')" > <?= lang("Device_Shortcut_Archived");?> </a>
|
||||
<a href="devices.php#archived" onclick="forceLoadUrl('devices.php#archived')" > <?= lang("Device_Shortcut_Archived");?> </a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<!-- Monitoring menu item -->
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "",
|
||||
"API_CUSTOM_SQL_name": "",
|
||||
"API_TOKEN_description": "",
|
||||
"API_TOKEN_name": "",
|
||||
"API_display_name": "",
|
||||
"API_icon": "",
|
||||
"About_Design": "",
|
||||
@@ -197,6 +199,7 @@
|
||||
"Device_Shortcut_Favorites": "",
|
||||
"Device_Shortcut_NewDevices": "",
|
||||
"Device_Shortcut_OnlineChart": "",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "",
|
||||
"Device_TableHead_Favorite": "",
|
||||
"Device_TableHead_FirstSession": "",
|
||||
@@ -214,6 +217,7 @@
|
||||
"Device_TableHead_Owner": "",
|
||||
"Device_TableHead_Parent_MAC": "",
|
||||
"Device_TableHead_Port": "",
|
||||
"Device_TableHead_PresentLastScan": "",
|
||||
"Device_TableHead_RowID": "",
|
||||
"Device_TableHead_Rowid": "",
|
||||
"Device_TableHead_SSID": "",
|
||||
@@ -270,6 +274,8 @@
|
||||
"Events_Tablelenght": "",
|
||||
"Events_Tablelenght_all": "",
|
||||
"Events_Title": "",
|
||||
"GRAPHQL_PORT_description": "",
|
||||
"GRAPHQL_PORT_name": "",
|
||||
"Gen_Action": "",
|
||||
"Gen_Add": "",
|
||||
"Gen_Add_All": "",
|
||||
@@ -705,6 +711,7 @@
|
||||
"settings_publishers_icon": "",
|
||||
"settings_publishers_info": "",
|
||||
"settings_publishers_label": "",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "",
|
||||
"settings_system_icon": "",
|
||||
"settings_system_label": "",
|
||||
|
||||
721
front/php/templates/language/ca_ca.json
Executable file
@@ -0,0 +1,721 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Pots especificar una consulta SQL personalitzada que generarà un fitxer JSON i el mostrarà mitjançant <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> file endpoint</a>.",
|
||||
"API_CUSTOM_SQL_name": "Punt final personalitzat",
|
||||
"API_TOKEN_description": "",
|
||||
"API_TOKEN_name": "",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "",
|
||||
"About_Design": "Dissenyat per:",
|
||||
"About_Exit": "Sortir",
|
||||
"About_Title": "",
|
||||
"AppEvents_DateTimeCreated": "",
|
||||
"AppEvents_Extra": "Extra",
|
||||
"AppEvents_GUID": "",
|
||||
"AppEvents_Helper1": "Ajudant 1",
|
||||
"AppEvents_Helper2": "Ajudant 2",
|
||||
"AppEvents_Helper3": "Ajudant 3",
|
||||
"AppEvents_ObjectForeignKey": "Clau forana",
|
||||
"AppEvents_ObjectIndex": "Índex",
|
||||
"AppEvents_ObjectIsArchived": "",
|
||||
"AppEvents_ObjectIsNew": "",
|
||||
"AppEvents_ObjectPlugin": "",
|
||||
"AppEvents_ObjectPrimaryID": "ID primari",
|
||||
"AppEvents_ObjectSecondaryID": "ID secundari",
|
||||
"AppEvents_ObjectStatus": "",
|
||||
"AppEvents_ObjectStatusColumn": "Columna d'estat",
|
||||
"AppEvents_ObjectType": "Tipus d'objecte",
|
||||
"AppEvents_Plugin": "",
|
||||
"AppEvents_Type": "Tipus",
|
||||
"BackDevDetail_Actions_Ask_Run": "Vol executar aquesta comanda?",
|
||||
"BackDevDetail_Actions_Not_Registered": "Comanda no registrada: ",
|
||||
"BackDevDetail_Actions_Title_Run": "Executar la comanda",
|
||||
"BackDevDetail_Copy_Ask": "",
|
||||
"BackDevDetail_Copy_Title": "Copiar detalls",
|
||||
"BackDevDetail_Tools_WOL_error": "La comanda NO s'ha executat.",
|
||||
"BackDevDetail_Tools_WOL_okay": "La comanda s'ha executat.",
|
||||
"BackDevices_Arpscan_disabled": "Arp-Scan Desactivat",
|
||||
"BackDevices_Arpscan_enabled": "Arp-Scan Activat",
|
||||
"BackDevices_Backup_CopError": "La base de dades original no s'ha pogut guardar.",
|
||||
"BackDevices_Backup_Failed": "",
|
||||
"BackDevices_Backup_okay": "La còpia de seguretat s'ha executat en un nou arxiu",
|
||||
"BackDevices_DBTools_DelDevError_a": "Error esborrant el Dispositiu",
|
||||
"BackDevices_DBTools_DelDevError_b": "Error esborrant els Dispositius",
|
||||
"BackDevices_DBTools_DelDev_a": "Dispositiu esborrat",
|
||||
"BackDevices_DBTools_DelDev_b": "Dispositius esborrats",
|
||||
"BackDevices_DBTools_DelEvents": "Esdeveniments esborrats",
|
||||
"BackDevices_DBTools_DelEventsError": "Error esborrant Esdeveniments",
|
||||
"BackDevices_DBTools_ImportCSV": "Els dispositius del fitxer CSV s'han importat correctament.",
|
||||
"BackDevices_DBTools_ImportCSVError": "El fitxer CSV no s'ha pogut importar. Comprovi que el format és correcte.",
|
||||
"BackDevices_DBTools_ImportCSVMissing": "No es pot trobar el fitxer CSV a la ubicació <b>/config/devices.csv.</b>",
|
||||
"BackDevices_DBTools_Purge": "Les còpies de seguretat més antigues s'han esborrat",
|
||||
"BackDevices_DBTools_UpdDev": "Dispositiu actualitzat correctament",
|
||||
"BackDevices_DBTools_UpdDevError": "Error actualitzant el dispositiu",
|
||||
"BackDevices_DBTools_Upgrade": "Base de dades actualitzada correctament",
|
||||
"BackDevices_DBTools_UpgradeError": "Actualització de la base de dades fallida",
|
||||
"BackDevices_Device_UpdDevError": "Error actualitzant dispositius, intenti-ho més endavant. Potser la base de dades està bloquejada per una altra tasca.",
|
||||
"BackDevices_Restore_CopError": "La base de dades original no s'ha pogut guardar.",
|
||||
"BackDevices_Restore_Failed": "Ha fallat la restauració. Si us plau faci una restauració manual de la còpia de seguretat.",
|
||||
"BackDevices_Restore_okay": "Restauració completada correctament.",
|
||||
"BackDevices_darkmode_disabled": "Mode fosc Desactivat",
|
||||
"BackDevices_darkmode_enabled": "Mode fosc Activat",
|
||||
"CLEAR_NEW_FLAG_description": "",
|
||||
"CLEAR_NEW_FLAG_name": "Netejar indicador de nou",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Això és una configuració de manteniment. Especifica el nombre de dies que es conservaran els esdeveniments. Els esdeveniments antics s'esborraran periòdicament. També aplica als esdeveniments dels Connectors (Plugins).",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Esborrar esdeveniments més vells de",
|
||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copiar detalls des del dispositiu",
|
||||
"DevDetail_Copy_Device_Tooltip": "Copiar detalls del dispositius des de la llista desplegable. Tot el d'aquesta pàgina es sobre-escriurà",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Alertes",
|
||||
"DevDetail_EveandAl_AlertDown": "",
|
||||
"DevDetail_EveandAl_Archived": "Arxivat",
|
||||
"DevDetail_EveandAl_NewDevice": "Nou Dispositiu",
|
||||
"DevDetail_EveandAl_NewDevice_Tooltip": "Es mostrarà el nou estat del dispositiu i s'inclourà a les llistes quan el filtre New Devices estigui actiu. No afecta les notificacions.",
|
||||
"DevDetail_EveandAl_RandomMAC": "MAC aleatori",
|
||||
"DevDetail_EveandAl_ScanCycle": "Dispositiu d'escaneig",
|
||||
"DevDetail_EveandAl_ScanCycle_a": "Dispositiu d'escaneig",
|
||||
"DevDetail_EveandAl_ScanCycle_z": "No Escanejar Dispositiu",
|
||||
"DevDetail_EveandAl_Skip": "Omet notificacions repetides per",
|
||||
"DevDetail_EveandAl_Title": "<i class=\"fa fa-bolt\"></i> Configuració de Successos i Alertes",
|
||||
"DevDetail_Events_CheckBox": "Amagar successos de connexió",
|
||||
"DevDetail_GoToNetworkNode": "Navegació a la pàgina de la Xarxa del node donat.",
|
||||
"DevDetail_Icon": "Icona",
|
||||
"DevDetail_Icon_Descr": "",
|
||||
"DevDetail_Loading": "",
|
||||
"DevDetail_MainInfo_Comments": "",
|
||||
"DevDetail_MainInfo_Favorite": "",
|
||||
"DevDetail_MainInfo_Group": "",
|
||||
"DevDetail_MainInfo_Location": "",
|
||||
"DevDetail_MainInfo_Name": "",
|
||||
"DevDetail_MainInfo_Network": "",
|
||||
"DevDetail_MainInfo_Network_Port": "",
|
||||
"DevDetail_MainInfo_Network_Site": "",
|
||||
"DevDetail_MainInfo_Network_Title": "",
|
||||
"DevDetail_MainInfo_Owner": "",
|
||||
"DevDetail_MainInfo_SSID": "",
|
||||
"DevDetail_MainInfo_Title": "",
|
||||
"DevDetail_MainInfo_Type": "",
|
||||
"DevDetail_MainInfo_Vendor": "Venedor",
|
||||
"DevDetail_MainInfo_mac": "MAC",
|
||||
"DevDetail_Network_Node_hover": "",
|
||||
"DevDetail_Network_Port_hover": "El port on el dispositiu està connectat al dispositiu de xarxa del pare. Si es deixa buit, sortirà una icona wifi a la representació de la Xarxa.",
|
||||
"DevDetail_Nmap_Scans": "Escaneig manual Nmap",
|
||||
"DevDetail_Nmap_Scans_desc": "Aquí podeu executar les exploracions NMAP manuals. També podeu programar les exploracions NMAP automàtiques a través del connector Serveis i Ports (NMAP). Ves a <a href='/settings.php' target='_blank'>Configuració</a> per saber-ne més",
|
||||
"DevDetail_Nmap_buttonDefault": "Escaneig predeterminat",
|
||||
"DevDetail_Nmap_buttonDefault_text": "Escaneig predeterminat: Nmap escaneja els 1000 ports superiors per a cada protocol d'exploració sol·licitat. El 93% dels ports TCP i el 49% dels ports UDP. (uns 5 segons)",
|
||||
"DevDetail_Nmap_buttonDetail": "Escaneig Detallat",
|
||||
"DevDetail_Nmap_buttonDetail_text": "Escaneig detallat: Escaneig predeterminat amb detecció del sistema operatiu habilitat, detecció de versions, escaneig i traça (fins a 30 segons o més)",
|
||||
"DevDetail_Nmap_buttonFast": "Escaneig ràpid",
|
||||
"DevDetail_Nmap_buttonFast_text": "Escaneig ràpid: Escaneig de menys ports (100) que l'exploració predeterminada (uns pocs segons)",
|
||||
"DevDetail_Nmap_buttonSkipDiscovery": "Ometre el descobriment de Hosts",
|
||||
"DevDetail_Nmap_buttonSkipDiscovery_text": "Omet descobriment de Host (-Pn opció): exploració predeterminada sense descobriment de host",
|
||||
"DevDetail_Nmap_resultsLink": "Podeu sortir d'aquesta pàgina després d'iniciar una exploració. Els resultats també estaran disponibles al fitxer <code>app_front.log</code>.",
|
||||
"DevDetail_Owner_hover": "Titular d'aquest dispositiu. Camp de text lliure.",
|
||||
"DevDetail_Periodselect_All": "Tota la informació",
|
||||
"DevDetail_Periodselect_LastMonth": "Darrer Mes",
|
||||
"DevDetail_Periodselect_LastWeek": "Darrera setmana",
|
||||
"DevDetail_Periodselect_LastYear": "Últim any",
|
||||
"DevDetail_Periodselect_today": "Avui",
|
||||
"DevDetail_Run_Actions_Title": "<i class=\"fa fa-play\"></i> Executar l'acció al dispositiu",
|
||||
"DevDetail_Run_Actions_Tooltip": "Executar una acció al dispositiu actual des de la llista desplegable.",
|
||||
"DevDetail_SessionInfo_FirstSession": "Primera Sessió",
|
||||
"DevDetail_SessionInfo_LastIP": "Darrera IP",
|
||||
"DevDetail_SessionInfo_LastSession": "Últim Fora de línia",
|
||||
"DevDetail_SessionInfo_StaticIP": "IP estàtica",
|
||||
"DevDetail_SessionInfo_Status": "Estat",
|
||||
"DevDetail_SessionInfo_Title": "<i class=\"fa fa-calendar\"></i> Informació de la sessió",
|
||||
"DevDetail_SessionTable_Additionalinfo": "Informació addicional",
|
||||
"DevDetail_SessionTable_Connection": "Connexió",
|
||||
"DevDetail_SessionTable_Disconnection": "Desconnexió",
|
||||
"DevDetail_SessionTable_Duration": "Durada",
|
||||
"DevDetail_SessionTable_IP": "IP",
|
||||
"DevDetail_SessionTable_Order": "Ordre",
|
||||
"DevDetail_Shortcut_CurrentStatus": "Estat actual",
|
||||
"DevDetail_Shortcut_DownAlerts": "",
|
||||
"DevDetail_Shortcut_Presence": "Presència",
|
||||
"DevDetail_Shortcut_Sessions": "Sessions",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detalls",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Esdeveniments",
|
||||
"DevDetail_Tab_EventsTableDate": "Data",
|
||||
"DevDetail_Tab_EventsTableEvent": "Tipus d'esdeveniment",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
"DevDetail_Tab_EventsTableInfo": "Informació addicional",
|
||||
"DevDetail_Tab_Nmap": "<i class=\"fa fa-ethernet\"></i> Nmap",
|
||||
"DevDetail_Tab_NmapEmpty": "Cap port detectat amb Nmap en aquest dispositiu.",
|
||||
"DevDetail_Tab_NmapTableExtra": "Extra",
|
||||
"DevDetail_Tab_NmapTableHeader": "Resultats de la exploració programada",
|
||||
"DevDetail_Tab_NmapTableIndex": "Índex",
|
||||
"DevDetail_Tab_NmapTablePort": "Port",
|
||||
"DevDetail_Tab_NmapTableService": "Servei",
|
||||
"DevDetail_Tab_NmapTableState": "Estat",
|
||||
"DevDetail_Tab_NmapTableText": "Configurar un calendari a <a href=\"/settings.php#NMAP_ACTIVE\">Configuració</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Temps",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"></i> Connectors (Plugins)",
|
||||
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Presència",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessions",
|
||||
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Eines",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Description": "L'eina d'informació d'Internet mostra informació sobre la connexió a Internet, com ara adreça IP, ciutat, país, codi d'àrea i zona horària.",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Error": "S'ha produït un error",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Inici Informació d'Internet",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Title": "Informació d'Internet",
|
||||
"DevDetail_Tab_Tools_Nslookup_Description": "Nslookup és una eina de línia de comandes utilitzada per consultar el sistema de noms de domini (DNS). DNS és un sistema que tradueix noms de domini, com www.google.com, a adreces d'IP, com 172.217.0.142.",
|
||||
"DevDetail_Tab_Tools_Nslookup_Error": "Error: l'adreça IP no és vàlida",
|
||||
"DevDetail_Tab_Tools_Nslookup_Start": "Iniciar Nslookup",
|
||||
"DevDetail_Tab_Tools_Nslookup_Title": "Nslookup",
|
||||
"DevDetail_Tab_Tools_Speedtest_Description": "L'eina Speedtest mesura la velocitat de descàrrega, la velocitat de pujada i la latència de la connexió a Internet.",
|
||||
"DevDetail_Tab_Tools_Speedtest_Start": "Iniciar Speedtest",
|
||||
"DevDetail_Tab_Tools_Speedtest_Title": "Speedtest Online",
|
||||
"DevDetail_Tab_Tools_Traceroute_Description": "Traceroute és una ordre de diagnòstic de xarxa utilitzada per traçar el camí que els paquets de dades prenen d'un amfitrió a un altre.<br><br> L'ordre utilitza el protocol de missatges de control d'Internet (ICMP) per enviar paquets a nodes intermedis de la ruta, cada node intermedi respon amb un paquet de temps de sortida ICMP (TTL a temps).<br><br> La sortida de l'ordre traceroute mostra l'adreça IP de cada node intermedi de la ruta.<br><br> L'ordre traceroute es pot utilitzar per diagnosticar problemes de xarxa, com ara retards, pèrdua de paquets i rutes bloquejades.<br><br> També es pot utilitzar per identificar la localització d’un node intermedi en una xarxa.",
|
||||
"DevDetail_Tab_Tools_Traceroute_Error": "Error: l'adreça IP no és vàlida",
|
||||
"DevDetail_Tab_Tools_Traceroute_Start": "Inici Traceroute",
|
||||
"DevDetail_Tab_Tools_Traceroute_Title": "Traceroute",
|
||||
"DevDetail_Tools_WOL": "Enviar comanda WoL a ",
|
||||
"DevDetail_Tools_WOL_noti": "Wake-on-LAN",
|
||||
"DevDetail_Tools_WOL_noti_text": "L'ordre Wake-on-LAN s'envia a l'adreça de difusió. Si l'objectiu no és a la subxarxa/VLAN de NetAlertX, el dispositiu objectiu no respondrà.",
|
||||
"DevDetail_Type_hover": "Tipus del dispositiu. Si seleccioneu qualsevol dels dispositius de xarxa predefinits (per exemple: AP, Firewall, Router, Switch...) es mostrarà a la configuració de Xarxa com a possible node de xarxa mare.",
|
||||
"DevDetail_Vendor_hover": "El venedor ha de ser autodetectat. Pots sobreescriure o afegir el teu valor personalitzat.",
|
||||
"DevDetail_WOL_Title": "<i class=\"fa fa-power-off\"></i> Wake-on-LAN",
|
||||
"DevDetail_button_AddIcon": "Afegir nova icona",
|
||||
"DevDetail_button_AddIcon_Help": "Enganxeu en una etiqueta html SVG o en una icona etiqueta html Font Awesome. Llegir el <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md\" target=\"_blank\">Icons docs</a> per a més detalls.",
|
||||
"DevDetail_button_AddIcon_Tooltip": "Afegir una nova Icona a aquest dispositiu que encara no està disponible al desplegable.",
|
||||
"DevDetail_button_Delete": "Eliminar dispositiu",
|
||||
"DevDetail_button_DeleteEvents": "Eliminar Esdeveniments",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Estàs segur que vols eliminar tots els esdeveniments d'aquest dispositiu?<br><br>(això esborrarà la <b>Historial d'esdeveniments</b> i la <b>Sessions</b> i pot ajudar amb les notificacions constants (persistents)",
|
||||
"DevDetail_button_OverwriteIcons": "Sobreescriure icones",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Sobreescriure icones de tots els dispositius amb el mateix tipus de dispositiu",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Estàs segur que vols sobreescriure totes les icones de tots els dispositius amb el mateix tipus de dispositiu que el tipus de dispositiu actual?",
|
||||
"DevDetail_button_Reset": "Restablir canvis",
|
||||
"DevDetail_button_Save": "Guardar",
|
||||
"Device_MultiEdit": "Multi-edició",
|
||||
"Device_MultiEdit_Backup": "Atenció, entrar valors incorrectes a continuació trencarà la configuració. Si us plau, abans feu còpia de seguretat la vostra base de dades o configuració de Dispositius (<a href=\"php/server/devices.php?action=ExportCSV\">clic per descarregar <i class=\"fa-solid fa-download fa-bounce\"></i></a>). Llegiu com per recuperar Dispositius des d'aquest fitxer dins el <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/BACKUPS.md#scenario-2-corrupted-database\" target=\"_blank\">documentació de Còpies de seguretat</a>.",
|
||||
"Device_MultiEdit_Fields": "Editar camps:",
|
||||
"Device_MultiEdit_MassActions": "Accions massives:",
|
||||
"Device_MultiEdit_Tooltip": "Atenció. Si feu clic a això s'aplicarà el valor de l'esquerra a tots els dispositius seleccionats a dalt.",
|
||||
"Device_Searchbox": "Cerca",
|
||||
"Device_Shortcut_AllDevices": "Els meus dispositius",
|
||||
"Device_Shortcut_Archived": "Arxivat",
|
||||
"Device_Shortcut_Connected": "Connectat",
|
||||
"Device_Shortcut_Devices": "Dispositius",
|
||||
"Device_Shortcut_DownAlerts": "Aturat i Fora de línia",
|
||||
"Device_Shortcut_DownOnly": "Aturat",
|
||||
"Device_Shortcut_Favorites": "Favorits",
|
||||
"Device_Shortcut_NewDevices": "Nous dispositius",
|
||||
"Device_Shortcut_OnlineChart": "Presència de dispositius",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "Connexions",
|
||||
"Device_TableHead_Favorite": "Favorit",
|
||||
"Device_TableHead_FirstSession": "Primera Sessió",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
"Device_TableHead_Group": "Grup",
|
||||
"Device_TableHead_Icon": "Icona",
|
||||
"Device_TableHead_LastIP": "Darrera IP",
|
||||
"Device_TableHead_LastIPOrder": "Últim Ordre d'IP",
|
||||
"Device_TableHead_LastSession": "Últim Offline",
|
||||
"Device_TableHead_Location": "Ubicació",
|
||||
"Device_TableHead_MAC": "MAC aleatori",
|
||||
"Device_TableHead_MAC_full": "MAC complet",
|
||||
"Device_TableHead_Name": "Nom",
|
||||
"Device_TableHead_NetworkSite": "Network Site",
|
||||
"Device_TableHead_Owner": "Propietari",
|
||||
"Device_TableHead_Parent_MAC": "MAC del node pare",
|
||||
"Device_TableHead_Port": "Port",
|
||||
"Device_TableHead_PresentLastScan": "",
|
||||
"Device_TableHead_RowID": "ID de fila",
|
||||
"Device_TableHead_Rowid": "ID de fila",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_SourcePlugin": "Connector(Plugin) font",
|
||||
"Device_TableHead_Status": "Estat",
|
||||
"Device_TableHead_SyncHubNodeName": "Node Sync",
|
||||
"Device_TableHead_Type": "Tipus",
|
||||
"Device_TableHead_Vendor": "Venedor",
|
||||
"Device_Table_Not_Network_Device": "No configurat com a dispositiu de xarxa",
|
||||
"Device_Table_info": "Mostrant _INICI_ a_FINAL_ d'entrades_ TOTALS",
|
||||
"Device_Table_nav_next": "Següent",
|
||||
"Device_Table_nav_prev": "Anterior",
|
||||
"Device_Tablelenght": "Veure_entrades_MENU",
|
||||
"Device_Tablelenght_all": "Tot",
|
||||
"Device_Title": "Dispositius",
|
||||
"Donations_Others": "Altres",
|
||||
"Donations_Platforms": "Plataformes patrocinadores",
|
||||
"Donations_Text": "Hola 👋! </br> Gràcies per fer clic en aquest element de menú 😅 </br> </br> Estic intentant recollir algunes donacions per fer un millor programari. També, m'ajudaria per cremar-me, i així recolzar aquesta aplicació més temps. Qualsevol petit (recurrent o no) patrocini em farà posar més esforç a aquesta aplicació. </br> M'agradaria escurçar la meva setmana de feina i en el temps restant enfocar-me en el NetAlertX. Així rebries més funcionalitat, una aplicació més neta i menys bugs. </br> </br> Gràcies per llegir-ho - Agraeixo qualsevol suport ❤🙏 </br> </br> TL;DR: Pel teu suport reps: </br> </br> <ul><li>Actualitzacions regulars per seguir les vostres dades i mantenir la família segura 🔄</li><li>Menys bugs 🐛🔫</li><li>Millor i més funcionalitat➕</li><li>Que no m'arribi el \"burn out\" 🔥🤯</li><li>Menys actualitzacions d'emergència 💨</li><li>Millors documentacions📚</li><li>Suport més ràpid i millor amb les incidències 🆘</li></ul> </br> 📧Correu electrònic <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> si vols contactar o si hauria d'afegir altres programes de patrocini. </br>",
|
||||
"Donations_Title": "Donacions",
|
||||
"ENABLE_PLUGINS_description": "Habilita la <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">connectors</a> funcionalitat. Carregar els connectors requereix més recursos de maquinari així podries voler desactivar-los en un sistema de baixos recursos.",
|
||||
"ENABLE_PLUGINS_name": "Activa els connectors(Plugins)",
|
||||
"Email_display_name": "Correu electrònic",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Carregant ...",
|
||||
"Events_Periodselect_All": "Tota la informació",
|
||||
"Events_Periodselect_LastMonth": "Darrer Mes",
|
||||
"Events_Periodselect_LastWeek": "Darrera setmana",
|
||||
"Events_Periodselect_LastYear": "Últim Any",
|
||||
"Events_Periodselect_today": "Avui",
|
||||
"Events_Searchbox": "",
|
||||
"Events_Shortcut_AllEvents": "Tots els esdeveniments",
|
||||
"Events_Shortcut_DownAlerts": "Aturar alertes",
|
||||
"Events_Shortcut_Events": "Esdeveniments",
|
||||
"Events_Shortcut_MissSessions": "",
|
||||
"Events_Shortcut_NewDevices": "Nous dispositius",
|
||||
"Events_Shortcut_Sessions": "Sessions",
|
||||
"Events_Shortcut_VoidSessions": "Sessions Anulades",
|
||||
"Events_TableHead_AdditionalInfo": "Informació addicional",
|
||||
"Events_TableHead_Connection": "Connexió",
|
||||
"Events_TableHead_Date": "Data",
|
||||
"Events_TableHead_Device": "Dispositiu",
|
||||
"Events_TableHead_Disconnection": "Desconnexió",
|
||||
"Events_TableHead_Duration": "Durada",
|
||||
"Events_TableHead_DurationOrder": "",
|
||||
"Events_TableHead_EventType": "Tipus d'esdeveniment",
|
||||
"Events_TableHead_IP": "IP",
|
||||
"Events_TableHead_IPOrder": "",
|
||||
"Events_TableHead_Order": "",
|
||||
"Events_TableHead_Owner": "Propietari",
|
||||
"Events_TableHead_PendingAlert": "Alerta pendent",
|
||||
"Events_Table_info": "Mostrant _INICI_ a_FINAL_ d'entrades_ TOTALS",
|
||||
"Events_Table_nav_next": "Següent",
|
||||
"Events_Table_nav_prev": "Anterior",
|
||||
"Events_Tablelenght": "Veure_entrades_MENU",
|
||||
"Events_Tablelenght_all": "Tot",
|
||||
"Events_Title": "Esdeveniments",
|
||||
"GRAPHQL_PORT_description": "El número de port del servidor GraphQL.",
|
||||
"GRAPHQL_PORT_name": "Port GraphQL",
|
||||
"Gen_Action": "Acció",
|
||||
"Gen_Add": "Afegir",
|
||||
"Gen_Add_All": "Afegeix tot",
|
||||
"Gen_All_Devices": "Tots els dispositius",
|
||||
"Gen_AreYouSure": "Estàs segur?",
|
||||
"Gen_Backup": "Executar Backup",
|
||||
"Gen_Cancel": "Cancel·lar",
|
||||
"Gen_Change": "Canviar",
|
||||
"Gen_Copy": "Executar",
|
||||
"Gen_DataUpdatedUITakesTime": "D'acord - Pot passar una estona perquè la interfície d'usuari s'actualitzi si s'està executant una exploració.",
|
||||
"Gen_Delete": "Esborrar",
|
||||
"Gen_DeleteAll": "Esborrar tot",
|
||||
"Gen_Description": "Descripció",
|
||||
"Gen_Error": "Error",
|
||||
"Gen_Filter": "Filtrar",
|
||||
"Gen_Generate": "Generar",
|
||||
"Gen_LockedDB": "ERROR - DB podria estar bloquejada - Fes servir F12 Eines desenvolupament -> Consola o provar-ho més tard.",
|
||||
"Gen_Offline": "Fora de línia",
|
||||
"Gen_Okay": "Ok",
|
||||
"Gen_Purge": "Elimina",
|
||||
"Gen_ReadDocs": "Llegit més dins el docs.",
|
||||
"Gen_Remove_All": "Esborra tot",
|
||||
"Gen_Remove_Last": "Esborra el darrer",
|
||||
"Gen_Restore": "Executar Restaurar",
|
||||
"Gen_Run": "Executar",
|
||||
"Gen_Save": "Guardar",
|
||||
"Gen_Saved": "Guardat",
|
||||
"Gen_Search": "",
|
||||
"Gen_SelectToPreview": "Seleccioneu la vista prèvia",
|
||||
"Gen_Selected_Devices": "Dispositius seleccionats:",
|
||||
"Gen_Switch": "Switch",
|
||||
"Gen_Upd": "Actualitzat correctament",
|
||||
"Gen_Upd_Fail": "Actualització fallida",
|
||||
"Gen_Update": "Actualitza",
|
||||
"Gen_Update_Value": "Actualitzar Valor",
|
||||
"Gen_Warning": "Advertència",
|
||||
"Gen_Work_In_Progress": "Work in progress, un bon moment per retroalimentació a https://github.com/jokob-sk/NetAlertX/issues",
|
||||
"General_display_name": "General",
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Això és un paràmetre de manteniment <b>ELIMINANT dispositius</b>. Si s'activa (<code>0</code> està desactivat), els dispositius marcats com <b>Dispositiu Nou</b> seran eliminats si el temps de <b>Primera Sessió</b> es més vell que les hores especificades en aquest paràmetre. Faci servir aquest paràmetre si vol auto-eliminar <b>Nous Dispositius</b> després de <code>X</code> hores.",
|
||||
"HRS_TO_KEEP_NEWDEV_name": "Eliminar nous dispositius després de",
|
||||
"HRS_TO_KEEP_OFFDEV_description": "Això és un paràmetre de manteniment <b>ELIMINANT dispositius</b>. Si s'activa (<code>0</code> està desactivat), els dispositius que estan <b>Offline</b> i el seu temps <b>Last Offline</b> es més vell que les hores especificades en aquest paràmetre, s'esborraran. Faci servir aquest paràmetre si vol auto-eliminar <b>Dispositius Offline</b> després de <code>X</code> hores sense connexió.",
|
||||
"HRS_TO_KEEP_OFFDEV_name": "Eliminar dispositius fora de línia després",
|
||||
"HelpFAQ_Cat_Detail": "Detalls",
|
||||
"HelpFAQ_Cat_Detail_300_head": "Què significa ",
|
||||
"HelpFAQ_Cat_Detail_300_text_a": "significa un dispositiu de xarxa (un dispositiu del tipus AP, Gateway, Firewall, Hypervisor, Powerline, Switch, WLAN, PLC, router, adaptador LAN USB, adaptador WIFI USB, o Internet). Els tipus personalitzats es poden afegir a través de la configuració <code>NETWORK_DEVICE_TYPES</code>.",
|
||||
"HelpFAQ_Cat_Detail_300_text_b": "designa el número de port on el dispositiu que s'està editant està connectat al dispositiu de xarxa. Llegir <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md\">aquesta guia</a> per a més informació.",
|
||||
"HelpFAQ_Cat_Detail_301_head_a": "",
|
||||
"HelpFAQ_Cat_Detail_301_head_b": " diu 1min però el gràfic mostra intervals de 5min.",
|
||||
"HelpFAQ_Cat_Detail_301_text": "L'interval de temps entre les exploracions es defineix per la \"Cronjob\", que s'estableix a 5min per defecte. La denominació \"1min\" fa referència a la durada prevista de l'exploració. Segons la configuració de la xarxa, aquesta vegada pot variar. Per editar el cronjob, podeu utilitzar l'ordre següent al terminal/consol <span class=\"text-danger help_faq_code\">crontab -e</span> i canviar l'interval.",
|
||||
"HelpFAQ_Cat_Detail_302_head_a": "Què significa ",
|
||||
"HelpFAQ_Cat_Detail_302_head_b": "i per què no puc seleccionar això?",
|
||||
"HelpFAQ_Cat_Detail_302_text": "Alguns dispositius moderns generen adreça MAC aleatòria per a raons de privacitat, ja no es poden associar amb els fabricants i canvien amb cada connexió nova. NetAlertX detecta si és aquest tipus d'adreça MAC aleatoria i activa aquest \"camp\" automàticament. Per desactivar aquesta conducta has de mirar en el vostre dispositiu com desactivar la randomització d'adreça MAC.",
|
||||
"HelpFAQ_Cat_Detail_303_head": "Què és Nmap i perquè serveix?",
|
||||
"HelpFAQ_Cat_Detail_303_text": "Nmap és un escàner de xarxa amb múltiples capacitats.<br> Quan un nou dispositiu apareix a la seva llista, vostè té la possibilitat d'obtenir informació més detallada sobre el dispositiu mitjançant l'exploració Nmap.",
|
||||
"HelpFAQ_Cat_Device_200_head": "Tinc dispositius en la meva llista que no conec. Després de suprimir-los, sempre tornen a aparèixer.",
|
||||
"HelpFAQ_Cat_Device_200_text": "Si utilitzes Pi-hole, per favor recorda que NetAlertX recupera informació des de Pi-hole. Pausa NetAlertX, ves a la pàgina de paràmetres en Pi-hole i elimina en les concessions DHCP si és necessari. També al Pi-hole, sota Eines -> Xarxa revisa si pots trobar amfitrions recurrents allà. Si n'hi ha, elimina'ls allà també. Després pots tornar a arrencar NetAlertX. Ara el(s) dispositiu(s) no hauria d'aparèixer més.",
|
||||
"HelpFAQ_Cat_General": "General",
|
||||
"HelpFAQ_Cat_General_100_head": "El rellotge a la part dreta superior i el temps dels esdeveniments no son correctes (diferència de temps).",
|
||||
"HelpFAQ_Cat_General_100_text_a": "En el seu PC la següent zona horària s'ha establert per a l'entorn PHP:",
|
||||
"HelpFAQ_Cat_General_100_text_b": "Si no és la zona horària en la qual es troba, ha de canviar la zona horària en el fitxer de configuració PHP. Podeu trobar-lo en aquest directori:",
|
||||
"HelpFAQ_Cat_General_100_text_c": "Cerca en aquest fitxer per a l'entrada \"date.timezone\", traieu el líder \";\" si cal i introduïu la zona horària desitjada. Podeu trobar una llista amb les zones horàries suportades aquí (<a href=\"https://www.php.net/manual/en/timezones.php\" target=\"blank\">Link</a>)",
|
||||
"HelpFAQ_Cat_General_101_head": "La meva xarxa sembla alentir, streaming es congela.",
|
||||
"HelpFAQ_Cat_General_101_text": "Pot ser que els dispositius de baixa potència arribin als seus límits de rendiment per la manera que NetalertX detecta nous dispositius a la xarxa. Això s'amplifica encara més, si aquests dispositius comuniquen amb la xarxa via WLAN. Les solucions aquí serien canviar a una connexió per cable si és possible o, si el dispositiu s'utilitza per un període limitat de temps, per usar el scan arp, aturar el scan arp a la pàgina de manteniment.",
|
||||
"HelpFAQ_Cat_General_102_head": "Rebo el missatge que la base de dades és només de lectura.",
|
||||
"HelpFAQ_Cat_General_102_text": "Comprova dins del directori NetAlertX si la carpeta de base de dades (db) té assignats els permisos correctes:<br> <span class=\"text-danger help_faq_code\">drwxrwx--- 2 (el vostre username) www-dada</span><br> Si el permís no és correcte, el pots posar de nou amb les ordres següents en la terminal o la consola:<br> <span class=\"text-danger help_faq_code\">sudo chgrp -R www-aplicació /de dades/db<br>chmod -R 770 /aplicació/db</span><br>Si la base de dades és encara només de lectura, prova reinstal·lar o restaurar una còpia de seguretat de base de dades des de la pàgina de manteniment.",
|
||||
"HelpFAQ_Cat_General_102docker_head": "Assumptes de base de dades (AJAX errors, només de lectura, no trobat)",
|
||||
"HelpFAQ_Cat_General_102docker_text": "Comprova si has seguit el <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/dockerfiles\">dockerfile readme (informació més actual)</a>. <br/> <br/> <ul data-sourcepos=\"49:4-52:146\" dir=\"auto\"><li data-sourcepos=\"49:4-49:106\">Descarrega la <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/db/app.db\"> base de dades original des de GitHub</a>.</li><li data-sourcepos=\"50:4-50:195\">Mapeja el <code>app.db</code> fitxer (<g-emoji class=\"g-emoji\" alias=\"warning\" fallback-src=\"https://github.githubassets.com/images/icons/emoji/unicode/26a0.png\">⚠</g-emoji> not folder) des de sobre a <code>/app/db/app.db</code> (veure <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/dockerfiles#-examples\">Exemples</a> per detalls).</li><li data-sourcepos=\"51:4-51:161\">Si trobes problemes (AJAX errors, que no es pot escriure a DB, etc,) assegura que els permisos s'han posat correctament, alternativament comprova els registres a <code>/app/front/log</code>.</li><li data-sourcepos=\"52:4-52:146\">Per solucionar els permisos també pot intentar crear un DB còpia de seguretat i llavors executar una restauració DB via la secció <strong>Manteniment > Backup/Restaurar</strong> .</li><li data-sourcepos=\"53:4-53:228\">Si la base de dades esta en mode només de lectura, pots solucionar això configuranr el propietari i el grup amb l'ordre següent en el sistema amfitrió: <code>docker exec netalertx chown -R www-data:www-data /app/db/app.db</code>.</li></ul>",
|
||||
"HelpFAQ_Cat_General_103_head": "La pàgina de login no apareix, fins i tot després de canviar la contrasenya.",
|
||||
"HelpFAQ_Cat_General_103_text": "A més de la contrasenya, el fitxer de configuració ha de contenir <span class=\"text-danger help_faq_code\">/app/config/app.conf</span> també el paràmetre <span class=\"text-danger help_faq_code\">PIALERT_WEB_PROTECTION</span> i s'ha d'establir a <span class=\"text-danger help_faq_code\">True</span>.",
|
||||
"HelpFAQ_Cat_Network_600_head": "Per a què serveix aquesta pàgina?",
|
||||
"HelpFAQ_Cat_Network_600_text": "Aquesta pàgina t'hauria d'oferir la possibilitat de mapejar l'assignació dels vostres dispositius de xarxa. Per a aquest propòsit, pots crear un o més switch, WLANs, enrutadors, etc., proporciona'ls un número de port si és necessari i assigna'ls dispositius ja detectats. Aquesta assignació es fa dins la vista detallada del dispositiu. Així és possible determinar ràpidament a quin port s'ha connectat un host i si està en línia. Llegir <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md\">aquesta guia</a> per més informació.",
|
||||
"HelpFAQ_Cat_Network_601_head": "Hi ha altres documents?",
|
||||
"HelpFAQ_Cat_Network_601_text": "Sí, hi ha! <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/\">tots els documents</a> per a més informació.",
|
||||
"HelpFAQ_Cat_Presence_400_head": "Els dispositius són mostrats amb un marcador groc i la nota \"succés desaparegut\".",
|
||||
"HelpFAQ_Cat_Presence_400_text": "Si això passa, tens l'opció d'esborrar els esdeveniments del dispositiu en qüestió (veure detalls). Una altra possibilitat seria canviar el dispositiu i esperar fins que NetAlertX detecti el dispositiu com \"en línia\" amb la següent exploració i, a continuació, simplement torneu a activar el dispositiu. NetAlert X ha de tenir en compte l'estat del dispositiu a la base de dades amb la següent exploració.",
|
||||
"HelpFAQ_Cat_Presence_401_head": "Un dispositiu és mostrat tan present tot i que és Fora de línia \"\".",
|
||||
"HelpFAQ_Cat_Presence_401_text": "Si això passa, tens la possibilitat d'esborrar els esdeveniments del dispositiu en qüestió (veure detalls). Una altra possibilitat seria canviar el dispositiu i esperar fins a NetAlert X reconeix el dispositiu com a \"en línia\" amb la següent exploració i, a continuació, simplement torneu a desactivar el dispositiu. NetAlert X ha de tenir en compte l'estat del dispositiu a la base de dades amb la següent exploració.",
|
||||
"HelpFAQ_Title": "Ajuda / FAQ",
|
||||
"LOADED_PLUGINS_description": "Quins Connectors(Plugins) carregar. Afegir connectors podria alentir l'aplicació. Llegir més sobre quins connectors necessiten estar habilitats, tipus, o opcions d'escanejar dins del <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme\">documents de connectors</a>. Els connectors descarregats perdran els vostres paràmetres. Només <code>desactivats</code> es poden eliminar els connectors.",
|
||||
"LOADED_PLUGINS_name": "Connectors carregats",
|
||||
"LOG_LEVEL_description": "Aquest paràmetre permetrà un registre més verbal. Útil per a la depuració d'esdeveniments escrivint a la base de dades.",
|
||||
"LOG_LEVEL_name": "Imprimeix el registre addicional",
|
||||
"Loading": "Carregant ...",
|
||||
"Login_Box": "Introduïu la vostra contrasenya",
|
||||
"Login_Default_PWD": "Contrasenya per defecte \"123456\" encara és activa.",
|
||||
"Login_Info": "Les contrasenyes es canvien al connector(plugin) Configurar Contrasenya. Comprova el <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins/set_password\">SETPWD docs</a> si tens dubtes fent logging.",
|
||||
"Login_Psw-box": "Contrasenya",
|
||||
"Login_Psw_alert": "Alerta de contrasenya!",
|
||||
"Login_Psw_folder": "a la carpeta config.",
|
||||
"Login_Psw_new": "new_password",
|
||||
"Login_Psw_run": "Per canviar la contrasenya:",
|
||||
"Login_Remember": "Recorda",
|
||||
"Login_Remember_small": "(vàlid per 7 dies)",
|
||||
"Login_Submit": "Inici de sessió",
|
||||
"Login_Toggle_Alert_headline": "Alerta de contrasenya!",
|
||||
"Login_Toggle_Info": "Informació de contrasenya",
|
||||
"Login_Toggle_Info_headline": "Informació de contrasenya",
|
||||
"Maint_PurgeLog": "Registre de purga",
|
||||
"Maint_RestartServer": "Reinici del servidor",
|
||||
"Maint_Restart_Server_noti_text": "Estàs segur que vols reiniciar el servidor backend? Això pot causar incongruència a l'aplicació. Abans fes còpia de seguretat de la vostra configuració. <br/> <br/> Nota: Això pot durar uns quants minuts.",
|
||||
"Maintenance_Running_Version": "Versió instal·lada",
|
||||
"Maintenance_Status": "Estat",
|
||||
"Maintenance_Title": "Eines de manteniment",
|
||||
"Maintenance_Tool_ExportCSV": "CSV Exportació",
|
||||
"Maintenance_Tool_ExportCSV_noti": "CSV Exportació",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Estàs segur que vols generar un fitxer CSV?",
|
||||
"Maintenance_Tool_ExportCSV_text": "Genera un fitxer CSV (comma separated value) que conté la llista dels dispositius incloent les relacions de Xarxa entre Nodes i dispositius connectats. També pots disparar-ho accedint a la URL <code>el vostre NetAlertX url/php/server/devices.php?acció=ExportCSV</code> o activant el connector <a href=\"settings.php#CSVBCKP_header\">CSV Còpia de seguretat</a>.",
|
||||
"Maintenance_Tool_ImportCSV": "CSV Importació",
|
||||
"Maintenance_Tool_ImportCSV_noti": "CSV Importació",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Estàs segur que vols importar el fitxer CSV? Això <b> sobreescriurà</b> completament els dispositius de la seva base de dades.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Abans d'utilitzar aquesta funció, fes una còpia de seguretat, si us plau. Importa un CSV (comma separated value) el fitxer que conté la llista dels dispositius que inclouen les relacions de Xarxa entre Nodes i dispositius connectats. Per fer-ho col·loca el CSV el fitxer anomenat <b>devices.csv</b> a la vostra <b>/config</b> carpeta.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "CSV Import (Paste)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "Estàs segur que vols importar el CSV copiat? Això <b> sobreescriurà</b> completament els dispositius de la base de dades.",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "Abans d'utilitzar aquesta funció, feu una còpia de seguretat. Importar un fitxer CSV (comma separated value) que contingui la llista de dispositius, incloent les relacions de xarxa entre els nodes i els dispositius connectats.",
|
||||
"Maintenance_Tool_arpscansw": "Conmuta arp-Scan (on/off)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Conmuta arp-Scan on or off",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Quan l'escàner ha estat canviat a off es queda off fins que és activat de bell nou.",
|
||||
"Maintenance_Tool_arpscansw_text": "Canviant el arp-escàner on o off. Quan el scan ha estat canviat off es queda off fins que és activat de bell nou. Els escàners actius no són anul·lats.",
|
||||
"Maintenance_Tool_backup": "DB Còpia de seguretat",
|
||||
"Maintenance_Tool_backup_noti": "Preguntes Freqüents - FAQ",
|
||||
"Maintenance_Tool_backup_noti_text": "Estàs segur que vols executar el Backup DB? Assegura't que no hi ha exploració en funcionament.",
|
||||
"Maintenance_Tool_backup_text": "Les còpies de seguretat de la base de dades es troben al directori de bases de dades com a arxiu zip, anomenat amb la data de creació. No hi ha un nombre màxim de còpies de seguretat.",
|
||||
"Maintenance_Tool_check_visible": "Desmarqueu-ho per amagar la columna.",
|
||||
"Maintenance_Tool_darkmode": "Canvia Modes (Fosc/Clar)",
|
||||
"Maintenance_Tool_darkmode_noti": "Canvia Modes",
|
||||
"Maintenance_Tool_darkmode_noti_text": "Després del canvi de tema, la pàgina intenta recarregar-se per activar el canvi. Si és necessari, s'ha de netejar la memòria cau.",
|
||||
"Maintenance_Tool_darkmode_text": "Canvia entre mode fosc i mode clar. Si el canvi no funciona correctament, prova per netejar la memòria cau de navegador. El canvi té lloc en el cantó de servidor, així que afecta tots dispositius en ús.",
|
||||
"Maintenance_Tool_del_ActHistory": "Eliminant l'activitat de xarxa",
|
||||
"Maintenance_Tool_del_ActHistory_noti": "Eliminar l'activitat de xarxa",
|
||||
"Maintenance_Tool_del_ActHistory_noti_text": "Estàs segur que vols restablir l’activitat de la xarxa?",
|
||||
"Maintenance_Tool_del_ActHistory_text": "El gràfic d’activitat de la xarxa es reinicialitzarà. No afecta als esdeveniments.",
|
||||
"Maintenance_Tool_del_alldev": "Eliminar tots els dispositius",
|
||||
"Maintenance_Tool_del_alldev_noti": "Eliminar dispositius",
|
||||
"Maintenance_Tool_del_alldev_noti_text": "Estàs segur que vols eliminar tots els dispositius?",
|
||||
"Maintenance_Tool_del_alldev_text": "Abans d'utilitzar aquesta funció, feu una còpia de seguretat. La supressió no es pot desfer. Tots els dispositius s'eliminaran de la base de dades.",
|
||||
"Maintenance_Tool_del_allevents": "Suprimeix esdeveniments (Elimina presència)",
|
||||
"Maintenance_Tool_del_allevents30": "Suprimeix tots els esdeveniments més vells que 30 dies",
|
||||
"Maintenance_Tool_del_allevents30_noti": "Eliminar Esdeveniments",
|
||||
"Maintenance_Tool_del_allevents30_noti_text": "T'és segur vols eliminar tot els successos més vells que 30 dies? Això elimina la Presencia de tots els Dispositius.",
|
||||
"Maintenance_Tool_del_allevents30_text": "Abans d'utilitzar aquesta funció, feu una còpia de seguretat. La supressió no es pot desfer. S'eliminaran tots els esdeveniments mes vells de 30 dies a la base de dades. També es restablirà la presència de tots els dispositius. Això pot portar a sessions no vàlides. Això significa que els dispositius es mostren com a \"present\" encara que estiguin fora de línia. Una anàlisi mentre el dispositiu en qüestió està en línia resol el problema.",
|
||||
"Maintenance_Tool_del_allevents_noti": "Eliminar Esdeveniments",
|
||||
"Maintenance_Tool_del_allevents_noti_text": "Estàs segur que vols eliminar tots els esdeveniments? Això reinicialització Presència de tots els dispositius.",
|
||||
"Maintenance_Tool_del_allevents_text": "",
|
||||
"Maintenance_Tool_del_empty_macs": "",
|
||||
"Maintenance_Tool_del_empty_macs_noti": "",
|
||||
"Maintenance_Tool_del_empty_macs_noti_text": "",
|
||||
"Maintenance_Tool_del_empty_macs_text": "",
|
||||
"Maintenance_Tool_del_selecteddev": "",
|
||||
"Maintenance_Tool_del_selecteddev_text": "",
|
||||
"Maintenance_Tool_del_unknowndev": "",
|
||||
"Maintenance_Tool_del_unknowndev_noti": "",
|
||||
"Maintenance_Tool_del_unknowndev_noti_text": "",
|
||||
"Maintenance_Tool_del_unknowndev_text": "",
|
||||
"Maintenance_Tool_displayed_columns_text": "",
|
||||
"Maintenance_Tool_drag_me": "",
|
||||
"Maintenance_Tool_order_columns_text": "",
|
||||
"Maintenance_Tool_purgebackup": "",
|
||||
"Maintenance_Tool_purgebackup_noti": "",
|
||||
"Maintenance_Tool_purgebackup_noti_text": "",
|
||||
"Maintenance_Tool_purgebackup_text": "",
|
||||
"Maintenance_Tool_restore": "",
|
||||
"Maintenance_Tool_restore_noti": "",
|
||||
"Maintenance_Tool_restore_noti_text": "",
|
||||
"Maintenance_Tool_restore_text": "",
|
||||
"Maintenance_Tool_upgrade_database_noti": "",
|
||||
"Maintenance_Tool_upgrade_database_noti_text": "",
|
||||
"Maintenance_Tool_upgrade_database_text": "",
|
||||
"Maintenance_Tools_Tab_BackupRestore": "",
|
||||
"Maintenance_Tools_Tab_Logging": "",
|
||||
"Maintenance_Tools_Tab_Settings": "",
|
||||
"Maintenance_Tools_Tab_Tools": "",
|
||||
"Maintenance_Tools_Tab_UISettings": "",
|
||||
"Maintenance_arp_status": "",
|
||||
"Maintenance_arp_status_off": "",
|
||||
"Maintenance_arp_status_on": "",
|
||||
"Maintenance_built_on": "",
|
||||
"Maintenance_current_version": "",
|
||||
"Maintenance_database_backup": "",
|
||||
"Maintenance_database_backup_found": "",
|
||||
"Maintenance_database_backup_total": "",
|
||||
"Maintenance_database_lastmod": "",
|
||||
"Maintenance_database_path": "",
|
||||
"Maintenance_database_rows": "",
|
||||
"Maintenance_database_size": "",
|
||||
"Maintenance_lang_selector_apply": "",
|
||||
"Maintenance_lang_selector_empty": "",
|
||||
"Maintenance_lang_selector_lable": "",
|
||||
"Maintenance_lang_selector_text": "",
|
||||
"Maintenance_new_version": "",
|
||||
"Maintenance_themeselector_apply": "",
|
||||
"Maintenance_themeselector_empty": "",
|
||||
"Maintenance_themeselector_lable": "",
|
||||
"Maintenance_themeselector_text": "",
|
||||
"Maintenance_version": "",
|
||||
"NETWORK_DEVICE_TYPES_description": "",
|
||||
"NETWORK_DEVICE_TYPES_name": "",
|
||||
"Navigation_About": "",
|
||||
"Navigation_Devices": "",
|
||||
"Navigation_Donations": "",
|
||||
"Navigation_Events": "",
|
||||
"Navigation_HelpFAQ": "",
|
||||
"Navigation_Integrations": "",
|
||||
"Navigation_Maintenance": "",
|
||||
"Navigation_Monitoring": "",
|
||||
"Navigation_Network": "",
|
||||
"Navigation_Notifications": "",
|
||||
"Navigation_Plugins": "",
|
||||
"Navigation_Presence": "",
|
||||
"Navigation_Report": "",
|
||||
"Navigation_Settings": "",
|
||||
"Navigation_SystemInfo": "",
|
||||
"Navigation_Workflows": "",
|
||||
"Network_Assign": "",
|
||||
"Network_Cant_Assign": "",
|
||||
"Network_Configuration_Error": "",
|
||||
"Network_Connected": "",
|
||||
"Network_ManageAdd": "",
|
||||
"Network_ManageAdd_Name": "",
|
||||
"Network_ManageAdd_Name_text": "",
|
||||
"Network_ManageAdd_Port": "",
|
||||
"Network_ManageAdd_Port_text": "",
|
||||
"Network_ManageAdd_Submit": "",
|
||||
"Network_ManageAdd_Type": "",
|
||||
"Network_ManageAdd_Type_text": "",
|
||||
"Network_ManageAssign": "",
|
||||
"Network_ManageDel": "",
|
||||
"Network_ManageDel_Name": "",
|
||||
"Network_ManageDel_Name_text": "",
|
||||
"Network_ManageDel_Submit": "",
|
||||
"Network_ManageDevices": "",
|
||||
"Network_ManageEdit": "",
|
||||
"Network_ManageEdit_ID": "",
|
||||
"Network_ManageEdit_ID_text": "",
|
||||
"Network_ManageEdit_Name": "",
|
||||
"Network_ManageEdit_Name_text": "",
|
||||
"Network_ManageEdit_Port": "",
|
||||
"Network_ManageEdit_Port_text": "",
|
||||
"Network_ManageEdit_Submit": "",
|
||||
"Network_ManageEdit_Type": "",
|
||||
"Network_ManageEdit_Type_text": "",
|
||||
"Network_ManageLeaf": "",
|
||||
"Network_ManageUnassign": "",
|
||||
"Network_NoAssignedDevices": "",
|
||||
"Network_NoDevices": "",
|
||||
"Network_Node": "",
|
||||
"Network_Node_Name": "",
|
||||
"Network_Parent": "",
|
||||
"Network_Root": "",
|
||||
"Network_Root_Not_Configured": "",
|
||||
"Network_Root_Unconfigurable": "",
|
||||
"Network_Table_Hostname": "",
|
||||
"Network_Table_IP": "",
|
||||
"Network_Table_State": "",
|
||||
"Network_Title": "",
|
||||
"Network_UnassignedDevices": "",
|
||||
"Notifications_All": "",
|
||||
"Notifications_Mark_All_Read": "",
|
||||
"PIALERT_WEB_PASSWORD_description": "",
|
||||
"PIALERT_WEB_PASSWORD_name": "",
|
||||
"PIALERT_WEB_PROTECTION_description": "",
|
||||
"PIALERT_WEB_PROTECTION_name": "",
|
||||
"PLUGINS_KEEP_HIST_description": "",
|
||||
"PLUGINS_KEEP_HIST_name": "",
|
||||
"Plugins_DeleteAll": "",
|
||||
"Plugins_Filters_Mac": "",
|
||||
"Plugins_History": "",
|
||||
"Plugins_Obj_DeleteListed": "",
|
||||
"Plugins_Objects": "",
|
||||
"Plugins_Out_of": "",
|
||||
"Plugins_Unprocessed_Events": "",
|
||||
"Plugins_no_control": "",
|
||||
"Presence_CalHead_day": "",
|
||||
"Presence_CalHead_lang": "",
|
||||
"Presence_CalHead_month": "",
|
||||
"Presence_CalHead_quarter": "",
|
||||
"Presence_CalHead_week": "",
|
||||
"Presence_CalHead_year": "",
|
||||
"Presence_CallHead_Devices": "",
|
||||
"Presence_Key_OnlineNow": "",
|
||||
"Presence_Key_OnlineNow_desc": "",
|
||||
"Presence_Key_OnlinePast": "",
|
||||
"Presence_Key_OnlinePastMiss": "",
|
||||
"Presence_Key_OnlinePastMiss_desc": "",
|
||||
"Presence_Key_OnlinePast_desc": "",
|
||||
"Presence_Loading": "",
|
||||
"Presence_Shortcut_AllDevices": "",
|
||||
"Presence_Shortcut_Archived": "",
|
||||
"Presence_Shortcut_Connected": "",
|
||||
"Presence_Shortcut_Devices": "",
|
||||
"Presence_Shortcut_DownAlerts": "",
|
||||
"Presence_Shortcut_Favorites": "",
|
||||
"Presence_Shortcut_NewDevices": "",
|
||||
"Presence_Title": "",
|
||||
"REPORT_DASHBOARD_URL_description": "",
|
||||
"REPORT_DASHBOARD_URL_name": "",
|
||||
"REPORT_ERROR": "",
|
||||
"REPORT_MAIL_description": "",
|
||||
"REPORT_MAIL_name": "",
|
||||
"REPORT_TITLE": "",
|
||||
"RandomMAC_hover": "",
|
||||
"Reports_Sent_Log": "",
|
||||
"SCAN_SUBNETS_description": "",
|
||||
"SCAN_SUBNETS_name": "",
|
||||
"SYSTEM_TITLE": "",
|
||||
"Setting_Override": "",
|
||||
"Setting_Override_Description": "",
|
||||
"Settings_Metadata_Toggle": "",
|
||||
"Settings_Show_Description": "",
|
||||
"Settings_device_Scanners_desync": "",
|
||||
"Settings_device_Scanners_desync_popup": "",
|
||||
"Speedtest_Results": "",
|
||||
"Systeminfo_CPU": "",
|
||||
"Systeminfo_CPU_Cores": "",
|
||||
"Systeminfo_CPU_Name": "",
|
||||
"Systeminfo_CPU_Speed": "",
|
||||
"Systeminfo_CPU_Temp": "",
|
||||
"Systeminfo_CPU_Vendor": "",
|
||||
"Systeminfo_Client_Resolution": "",
|
||||
"Systeminfo_Client_User_Agent": "",
|
||||
"Systeminfo_General": "",
|
||||
"Systeminfo_General_Date": "",
|
||||
"Systeminfo_General_Date2": "",
|
||||
"Systeminfo_General_Full_Date": "",
|
||||
"Systeminfo_General_TimeZone": "",
|
||||
"Systeminfo_Memory": "",
|
||||
"Systeminfo_Memory_Total_Memory": "",
|
||||
"Systeminfo_Memory_Usage": "",
|
||||
"Systeminfo_Memory_Usage_Percent": "",
|
||||
"Systeminfo_Motherboard": "",
|
||||
"Systeminfo_Motherboard_BIOS": "",
|
||||
"Systeminfo_Motherboard_BIOS_Date": "",
|
||||
"Systeminfo_Motherboard_BIOS_Vendor": "",
|
||||
"Systeminfo_Motherboard_Manufactured": "",
|
||||
"Systeminfo_Motherboard_Name": "",
|
||||
"Systeminfo_Motherboard_Revision": "",
|
||||
"Systeminfo_Network": "",
|
||||
"Systeminfo_Network_Accept_Encoding": "",
|
||||
"Systeminfo_Network_Accept_Language": "",
|
||||
"Systeminfo_Network_Connection_Port": "",
|
||||
"Systeminfo_Network_HTTP_Host": "",
|
||||
"Systeminfo_Network_HTTP_Referer": "",
|
||||
"Systeminfo_Network_HTTP_Referer_String": "",
|
||||
"Systeminfo_Network_Hardware": "",
|
||||
"Systeminfo_Network_Hardware_Interface_Mask": "",
|
||||
"Systeminfo_Network_Hardware_Interface_Name": "",
|
||||
"Systeminfo_Network_Hardware_Interface_RX": "",
|
||||
"Systeminfo_Network_Hardware_Interface_TX": "",
|
||||
"Systeminfo_Network_IP": "",
|
||||
"Systeminfo_Network_IP_Connection": "",
|
||||
"Systeminfo_Network_IP_Server": "",
|
||||
"Systeminfo_Network_MIME": "",
|
||||
"Systeminfo_Network_Request_Method": "",
|
||||
"Systeminfo_Network_Request_Time": "",
|
||||
"Systeminfo_Network_Request_URI": "",
|
||||
"Systeminfo_Network_Secure_Connection": "",
|
||||
"Systeminfo_Network_Secure_Connection_String": "",
|
||||
"Systeminfo_Network_Server_Name": "",
|
||||
"Systeminfo_Network_Server_Name_String": "",
|
||||
"Systeminfo_Network_Server_Query": "",
|
||||
"Systeminfo_Network_Server_Query_String": "",
|
||||
"Systeminfo_Network_Server_Version": "",
|
||||
"Systeminfo_Services": "",
|
||||
"Systeminfo_Services_Description": "",
|
||||
"Systeminfo_Services_Name": "",
|
||||
"Systeminfo_Storage": "",
|
||||
"Systeminfo_Storage_Device": "",
|
||||
"Systeminfo_Storage_Mount": "",
|
||||
"Systeminfo_Storage_Size": "",
|
||||
"Systeminfo_Storage_Type": "",
|
||||
"Systeminfo_Storage_Usage": "",
|
||||
"Systeminfo_Storage_Usage_Free": "",
|
||||
"Systeminfo_Storage_Usage_Mount": "",
|
||||
"Systeminfo_Storage_Usage_Total": "",
|
||||
"Systeminfo_Storage_Usage_Used": "",
|
||||
"Systeminfo_System": "",
|
||||
"Systeminfo_System_AVG": "",
|
||||
"Systeminfo_System_Architecture": "",
|
||||
"Systeminfo_System_Kernel": "",
|
||||
"Systeminfo_System_OSVersion": "",
|
||||
"Systeminfo_System_Running_Processes": "",
|
||||
"Systeminfo_System_System": "",
|
||||
"Systeminfo_System_Uname": "",
|
||||
"Systeminfo_System_Uptime": "",
|
||||
"Systeminfo_This_Client": "",
|
||||
"Systeminfo_USB_Devices": "",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "",
|
||||
"TIMEZONE_description": "",
|
||||
"TIMEZONE_name": "",
|
||||
"UI_DEV_SECTIONS_description": "",
|
||||
"UI_DEV_SECTIONS_name": "",
|
||||
"UI_ICONS_description": "",
|
||||
"UI_ICONS_name": "",
|
||||
"UI_LANG_description": "",
|
||||
"UI_LANG_name": "",
|
||||
"UI_MY_DEVICES_description": "",
|
||||
"UI_MY_DEVICES_name": "",
|
||||
"UI_NOT_RANDOM_MAC_description": "",
|
||||
"UI_NOT_RANDOM_MAC_name": "",
|
||||
"UI_PRESENCE_description": "",
|
||||
"UI_PRESENCE_name": "",
|
||||
"UI_REFRESH_description": "",
|
||||
"UI_REFRESH_name": "",
|
||||
"VERSION_description": "",
|
||||
"VERSION_name": "",
|
||||
"devices_old": "",
|
||||
"general_event_description": "",
|
||||
"general_event_title": "",
|
||||
"report_guid": "",
|
||||
"report_guid_missing": "",
|
||||
"report_select_format": "",
|
||||
"report_time": "",
|
||||
"run_event_icon": "",
|
||||
"run_event_tooltip": "",
|
||||
"settings_core_icon": "",
|
||||
"settings_core_label": "",
|
||||
"settings_device_scanners": "",
|
||||
"settings_device_scanners_icon": "",
|
||||
"settings_device_scanners_info": "",
|
||||
"settings_device_scanners_label": "",
|
||||
"settings_enabled": "",
|
||||
"settings_enabled_icon": "",
|
||||
"settings_expand_all": "",
|
||||
"settings_imported": "",
|
||||
"settings_imported_label": "",
|
||||
"settings_missing": "",
|
||||
"settings_missing_block": "",
|
||||
"settings_old": "",
|
||||
"settings_other_scanners": "",
|
||||
"settings_other_scanners_icon": "",
|
||||
"settings_other_scanners_label": "",
|
||||
"settings_publishers": "",
|
||||
"settings_publishers_icon": "",
|
||||
"settings_publishers_info": "",
|
||||
"settings_publishers_label": "",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "",
|
||||
"settings_system_icon": "",
|
||||
"settings_system_label": "",
|
||||
"settings_update_item_warning": "",
|
||||
"test_event_icon": "",
|
||||
"test_event_tooltip": ""
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "",
|
||||
"API_CUSTOM_SQL_name": "",
|
||||
"API_TOKEN_description": "",
|
||||
"API_TOKEN_name": "",
|
||||
"API_display_name": "",
|
||||
"API_icon": "",
|
||||
"About_Design": "",
|
||||
@@ -197,6 +199,7 @@
|
||||
"Device_Shortcut_Favorites": "",
|
||||
"Device_Shortcut_NewDevices": "",
|
||||
"Device_Shortcut_OnlineChart": "",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "",
|
||||
"Device_TableHead_Favorite": "",
|
||||
"Device_TableHead_FirstSession": "",
|
||||
@@ -214,6 +217,7 @@
|
||||
"Device_TableHead_Owner": "",
|
||||
"Device_TableHead_Parent_MAC": "",
|
||||
"Device_TableHead_Port": "",
|
||||
"Device_TableHead_PresentLastScan": "",
|
||||
"Device_TableHead_RowID": "",
|
||||
"Device_TableHead_Rowid": "",
|
||||
"Device_TableHead_SSID": "",
|
||||
@@ -270,6 +274,8 @@
|
||||
"Events_Tablelenght": "",
|
||||
"Events_Tablelenght_all": "",
|
||||
"Events_Title": "",
|
||||
"GRAPHQL_PORT_description": "",
|
||||
"GRAPHQL_PORT_name": "",
|
||||
"Gen_Action": "",
|
||||
"Gen_Add": "",
|
||||
"Gen_Add_All": "",
|
||||
@@ -705,6 +711,7 @@
|
||||
"settings_publishers_icon": "",
|
||||
"settings_publishers_info": "",
|
||||
"settings_publishers_label": "",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "",
|
||||
"settings_system_icon": "",
|
||||
"settings_system_label": "",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Benutzerdefinierte SQL-Abfrage, welche eine JSON-Datei generiert und diese mit dem <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\">Dateiendpunkt <code>table_custom_endpoint.json</code></a> zur Verfügung stellt.",
|
||||
"API_CUSTOM_SQL_name": "Benutzerdefinierte SQL-Abfrage",
|
||||
"API_TOKEN_description": "",
|
||||
"API_TOKEN_name": "",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"APPRISE_HOST_description": "Apprise host URL starting with <code>http://</code> or <code>https://</code>. (do not forget to include <code>/notify</code> at the end)",
|
||||
@@ -209,6 +211,7 @@
|
||||
"Device_Shortcut_Favorites": "Favoriten",
|
||||
"Device_Shortcut_NewDevices": "Neue Geräte",
|
||||
"Device_Shortcut_OnlineChart": "Gerätepräsenz im Laufe der Zeit",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "Verbindungen",
|
||||
"Device_TableHead_Favorite": "Favorit",
|
||||
"Device_TableHead_FirstSession": "Erste Sitzung",
|
||||
@@ -226,6 +229,7 @@
|
||||
"Device_TableHead_Owner": "Eigentümer",
|
||||
"Device_TableHead_Parent_MAC": "Übergeordnete MAC",
|
||||
"Device_TableHead_Port": "Port",
|
||||
"Device_TableHead_PresentLastScan": "",
|
||||
"Device_TableHead_RowID": "Zeilen ID",
|
||||
"Device_TableHead_Rowid": "Zeilennummer",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
@@ -282,6 +286,8 @@
|
||||
"Events_Tablelenght": "Zeige _MENU_ Einträge",
|
||||
"Events_Tablelenght_all": "Alle",
|
||||
"Events_Title": "Ereignisse",
|
||||
"GRAPHQL_PORT_description": "",
|
||||
"GRAPHQL_PORT_name": "",
|
||||
"Gen_Action": "Action",
|
||||
"Gen_Add": "Hinzufügen",
|
||||
"Gen_Add_All": "Alle hinzufügen",
|
||||
@@ -786,6 +792,7 @@
|
||||
"settings_publishers_icon": "",
|
||||
"settings_publishers_info": "Lade mehr Veröffentlicher mit den <a href=\"/settings.php#LOADED_PLUGINS\">geladene Plugins</a>-Einstellungen",
|
||||
"settings_publishers_label": "Veröffentlicher",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "<br/>Einstellungen gespeichert. <br/> Wird geladen... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
|
||||
"settings_system_icon": "",
|
||||
"settings_system_label": "System",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "You can specify a custom SQL query which will generate a JSON file and then expose it via the <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> file endpoint</a>.",
|
||||
"API_CUSTOM_SQL_name": "Custom endpoint",
|
||||
"API_TOKEN_description": "API token to secure communication, you can generate one or enter any value. It's sent in the request header. Used in the <code>SYNC</code> plugin, GraphQL server.",
|
||||
"API_TOKEN_name": "API token",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"About_Design": "Designed for:",
|
||||
@@ -197,6 +199,7 @@
|
||||
"Device_Shortcut_Favorites": "Favorites",
|
||||
"Device_Shortcut_NewDevices": "New Devices",
|
||||
"Device_Shortcut_OnlineChart": "Device presence",
|
||||
"Device_TableHead_AlertDown": "Alert Down",
|
||||
"Device_TableHead_Connected_Devices": "Connections",
|
||||
"Device_TableHead_Favorite": "Favorite",
|
||||
"Device_TableHead_FirstSession": "First Session",
|
||||
@@ -214,6 +217,7 @@
|
||||
"Device_TableHead_Owner": "Owner",
|
||||
"Device_TableHead_Parent_MAC": "Parent node MAC",
|
||||
"Device_TableHead_Port": "Port",
|
||||
"Device_TableHead_PresentLastScan": "Presence",
|
||||
"Device_TableHead_RowID": "Row ID",
|
||||
"Device_TableHead_Rowid": "Row ID",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
@@ -270,6 +274,8 @@
|
||||
"Events_Tablelenght": "Show _MENU_ entries",
|
||||
"Events_Tablelenght_all": "All",
|
||||
"Events_Title": "Events",
|
||||
"GRAPHQL_PORT_description": "The port number of the GraphQL server.",
|
||||
"GRAPHQL_PORT_name": "GraphQL port",
|
||||
"Gen_Action": "Action",
|
||||
"Gen_Add": "Add",
|
||||
"Gen_Add_All": "Add all",
|
||||
@@ -311,7 +317,7 @@
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "This is a maintenance setting <b>DELETING devices</b>. If enabled (<code>0</code> is disabled), devices marked as <b>New Device</b> will be deleted if their <b>First Session</b> time was older than the specified hours in this setting. Use this setting if you want to auto-delete <b>New Devices</b> after <code>X</code> hours.",
|
||||
"HRS_TO_KEEP_NEWDEV_name": "Delete new devices after",
|
||||
"HRS_TO_KEEP_OFFDEV_description": "This is a maintenance setting <b>DELETING devices</b>. If enabled (<code>0</code> is disabled), devices that are <b>Offline</b> and their <b>Last Offline</b> date time is older than the specified hours in this setting. Use this setting if you want to auto-delete <b>Offline Devices</b> after <code>X</code> hours being offline.",
|
||||
"HRS_TO_KEEP_OFFDEV_description": "This is a maintenance setting <b>DELETING devices</b>. If enabled (<code>0</code> is disabled), devices that are <b>Offline</b> and their <b>Last Offline</b> date time is older than the specified hours in this setting, will be deleted. Use this setting if you want to auto-delete <b>Offline Devices</b> after <code>X</code> hours being offline.",
|
||||
"HRS_TO_KEEP_OFFDEV_name": "Delete offline devices after",
|
||||
"HelpFAQ_Cat_Detail": "Details",
|
||||
"HelpFAQ_Cat_Detail_300_head": "What means ",
|
||||
@@ -705,6 +711,7 @@
|
||||
"settings_publishers_icon": "fa-solid fa-paper-plane",
|
||||
"settings_publishers_info": "Load more Publishers with the <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a> setting",
|
||||
"settings_publishers_label": "Publishers",
|
||||
"settings_readonly": "Can't READ or WRITE <code>app.conf</code>. Try restarting the container and read the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/FILE_PERMISSIONS.md\" target=\"_blank\">file permissions documentation</a>",
|
||||
"settings_saved": "<br/>Settings saved. <br/> Reloading... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
|
||||
"settings_system_icon": "fa-solid fa-gear",
|
||||
"settings_system_label": "System",
|
||||
|
||||
13
front/php/templates/language/es_es.json
Executable file → Normal file
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Puede especificar una consulta SQL personalizada que generará un archivo JSON y luego lo expondrá a través del <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\">archivo <code>table_custom_endpoint.json</code ></a>.",
|
||||
"API_CUSTOM_SQL_name": "Endpoint personalizado",
|
||||
"API_TOKEN_description": "Token de API para asegurar la comunicación, puede generar uno o introducir cualquier valor. Se envía en el encabezado de solicitud. Se utiliza en el plugin <code>SYNC</code> del servidor GraphQL.",
|
||||
"API_TOKEN_name": "Token de la API",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"APPRISE_HOST_description": "URL del host de Apprise que comienza con <code>http://</code> o <code>https://</code>. (no olvide incluir <code>/notify</code> al final)",
|
||||
@@ -72,7 +74,7 @@
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Eliminar eventos anteriores a",
|
||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copiar detalles del dispositivo",
|
||||
"DevDetail_Copy_Device_Tooltip": "Copiar detalles del dispositivo de la lista desplegable. Todo en esta página se sobrescribirá",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Alerta a todos los eventos",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Notificaciones de eventos",
|
||||
"DevDetail_EveandAl_AlertDown": "Alerta de caída",
|
||||
"DevDetail_EveandAl_Archived": "Archivada",
|
||||
"DevDetail_EveandAl_NewDevice": "Nuevo dispositivo",
|
||||
@@ -207,6 +209,7 @@
|
||||
"Device_Shortcut_Favorites": "Favorito(s)",
|
||||
"Device_Shortcut_NewDevices": "Nuevo(s)",
|
||||
"Device_Shortcut_OnlineChart": "Presencia del dispositivo a lo largo del tiempo",
|
||||
"Device_TableHead_AlertDown": "Alerta desactivada",
|
||||
"Device_TableHead_Connected_Devices": "Conexiones",
|
||||
"Device_TableHead_Favorite": "Favorito",
|
||||
"Device_TableHead_FirstSession": "1ra. sesión",
|
||||
@@ -224,6 +227,7 @@
|
||||
"Device_TableHead_Owner": "Propietario",
|
||||
"Device_TableHead_Parent_MAC": "Nodo principal de la MAC",
|
||||
"Device_TableHead_Port": "Puerto",
|
||||
"Device_TableHead_PresentLastScan": "Historial",
|
||||
"Device_TableHead_RowID": "Row ID",
|
||||
"Device_TableHead_Rowid": "Row ID",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
@@ -280,6 +284,8 @@
|
||||
"Events_Tablelenght": "Mostrando entradas del MENÚ",
|
||||
"Events_Tablelenght_all": "Todos",
|
||||
"Events_Title": "Eventos",
|
||||
"GRAPHQL_PORT_description": "El número de puerto del servidor GraphQL.",
|
||||
"GRAPHQL_PORT_name": "Puerto GraphQL",
|
||||
"Gen_Action": "Acción",
|
||||
"Gen_Add": "Añadir",
|
||||
"Gen_Add_All": "Añadir todo",
|
||||
@@ -321,7 +327,7 @@
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Se trata de una configuración de mantenimiento <b>BORRAR dispositivos</b>. Si está activado (<code>0</code> está desactivado), los dispositivos marcados como <b>Nuevo dispositivo</b> se eliminarán si su fecha de <b>primera sesión</b> es anterior a las horas especificadas en este ajuste. Use este ajuste si desea eliminar automáticamente <b>Nuevos dispositivos</b> después de <code>X</code> horas.",
|
||||
"HRS_TO_KEEP_NEWDEV_name": "Eliminar nuevos dispositivos después",
|
||||
"HRS_TO_KEEP_OFFDEV_description": "Se trata de una configuración de mantenimiento <b>BORRAR dispositivos</b>. Si está activado (<code>0</code> está desactivado), los dispositivos que están <b>sin conexión</b> y su fecha de <b>última conexión</b> son anteriores a las horas especificadas en este ajuste. Use este ajuste si desea eliminar automáticamente <b>los dispositivos sin conexión</b> después de que el <code>X</code> horas esté sin conexión.",
|
||||
"HRS_TO_KEEP_OFFDEV_description": "Se trata de una configuración de mantenimiento <b>BORRAR dispositivos</b>. Si está activado (<code>0</code> está desactivado), los dispositivos que están <b>sin conexión</b> y su fecha de <b>última conexión</b> es anterior a las horas especificadas en este ajuste se eliminarán. Use este ajuste si desea eliminar automáticamente <b>los dispositivos sin conexión</b> después de que el <code>X</code> horas esté sin conexión.",
|
||||
"HRS_TO_KEEP_OFFDEV_name": "Borrar dispositivos sin conexión después de",
|
||||
"HelpFAQ_Cat_Detail": "Detalles",
|
||||
"HelpFAQ_Cat_Detail_300_head": "¿Qué significa? ",
|
||||
@@ -784,10 +790,11 @@
|
||||
"settings_publishers_icon": "fa-solid fa-paper-plane",
|
||||
"settings_publishers_info": "Cargue más editor@s con el ajuste <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
|
||||
"settings_publishers_label": "Editores",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "<br/>Ajustes guardados. <br/><br/> Recargando... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
|
||||
"settings_system_icon": "fa-solid fa-gear",
|
||||
"settings_system_label": "Sistema",
|
||||
"settings_update_item_warning": "Actualice el valor a continuación. Tenga cuidado de seguir el formato anterior. <b>O la validación no se realiza.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Guarda tus cambios antes de probar nuevos ajustes."
|
||||
}
|
||||
}
|
||||
|
||||
9
front/php/templates/language/fr_fr.json
Executable file → Normal file
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Vous pouvez spécifier votre propre requête SQL qui retournera un fichier JSON et l'exposer via <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> le point de terminaison de fichier</a>.",
|
||||
"API_CUSTOM_SQL_name": "Point de terminaison personnalisé",
|
||||
"API_TOKEN_description": "Vous pouvez renseigner ou générer un jeton API pour sécuriser les échanges. Il est transmis dans le header de la requête. C'est utilisé dans le plugin <code>SYNC</code> du serveur GraphQL.",
|
||||
"API_TOKEN_name": "Jeton d'API",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"About_Design": "Conçu pour :",
|
||||
@@ -197,6 +199,7 @@
|
||||
"Device_Shortcut_Favorites": "Favoris",
|
||||
"Device_Shortcut_NewDevices": "Nouveaux appareils",
|
||||
"Device_Shortcut_OnlineChart": "Présence de l'appareil",
|
||||
"Device_TableHead_AlertDown": "Alerter si En panne",
|
||||
"Device_TableHead_Connected_Devices": "Connexions",
|
||||
"Device_TableHead_Favorite": "Favori",
|
||||
"Device_TableHead_FirstSession": "Première session",
|
||||
@@ -214,6 +217,7 @@
|
||||
"Device_TableHead_Owner": "Propriétaire",
|
||||
"Device_TableHead_Parent_MAC": "MAC du nœud principal",
|
||||
"Device_TableHead_Port": "Port",
|
||||
"Device_TableHead_PresentLastScan": "Présence",
|
||||
"Device_TableHead_RowID": "ID de colonne",
|
||||
"Device_TableHead_Rowid": "ID de colonne",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
@@ -270,6 +274,8 @@
|
||||
"Events_Tablelenght": "Afficher _MENU_ entrées",
|
||||
"Events_Tablelenght_all": "Tous",
|
||||
"Events_Title": "Évènements",
|
||||
"GRAPHQL_PORT_description": "Le numéro de port du serveur GraphQL.",
|
||||
"GRAPHQL_PORT_name": "Port GraphQL",
|
||||
"Gen_Action": "Action",
|
||||
"Gen_Add": "Ajouter",
|
||||
"Gen_Add_All": "Ajouter tous",
|
||||
@@ -705,10 +711,11 @@
|
||||
"settings_publishers_icon": "fa-solid fa-paper-plane",
|
||||
"settings_publishers_info": "Charger plus de passerelles de publication avec le paramètre <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
|
||||
"settings_publishers_label": "Passerelles de publication",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "<br/>Paramètres enregistrés. <br/> Rechargement... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
|
||||
"settings_system_icon": "fa-solid fa-gear",
|
||||
"settings_system_label": "Système",
|
||||
"settings_update_item_warning": "Mettre à jour la valeur ci-dessous. Veillez à bien suivre le même format qu'auparavant. <b>Il n'y a pas de pas de contrôle.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Enregistrer d'abord vos modifications avant de tester vôtre paramétrage."
|
||||
}
|
||||
}
|
||||
|
||||
11
front/php/templates/language/it_it.json
Executable file → Normal file
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Puoi specificare una query SQL personalizzata che genererà un file JSON e quindi lo esporrà tramite l'<a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code>endpoint del file</a>.",
|
||||
"API_CUSTOM_SQL_name": "Endpoint personalizzato",
|
||||
"API_TOKEN_description": "Token API per proteggere la comunicazione, puoi generarne uno o inserire qualsiasi valore. Viene inviato nell'intestazione della richiesta. Usato nel plugin <code>SYNC</code>, server GraphQL.",
|
||||
"API_TOKEN_name": "Token API",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"About_Design": "Progettato per:",
|
||||
@@ -197,6 +199,7 @@
|
||||
"Device_Shortcut_Favorites": "Preferiti",
|
||||
"Device_Shortcut_NewDevices": "Nuovi dispositivi",
|
||||
"Device_Shortcut_OnlineChart": "Presenza dispositivo",
|
||||
"Device_TableHead_AlertDown": "Avviso disconnessione",
|
||||
"Device_TableHead_Connected_Devices": "Connessioni",
|
||||
"Device_TableHead_Favorite": "Preferito",
|
||||
"Device_TableHead_FirstSession": "Prima sessione",
|
||||
@@ -214,6 +217,7 @@
|
||||
"Device_TableHead_Owner": "Proprietario",
|
||||
"Device_TableHead_Parent_MAC": "MAC del nodo principale",
|
||||
"Device_TableHead_Port": "Porta",
|
||||
"Device_TableHead_PresentLastScan": "Presenza",
|
||||
"Device_TableHead_RowID": "ID riga",
|
||||
"Device_TableHead_Rowid": "ID riga",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
@@ -270,6 +274,8 @@
|
||||
"Events_Tablelenght": "Mostra _MENU_ elementi",
|
||||
"Events_Tablelenght_all": "Tutti",
|
||||
"Events_Title": "Eventi",
|
||||
"GRAPHQL_PORT_description": "Il numero di porta del server GraphQL.",
|
||||
"GRAPHQL_PORT_name": "Porta GraphQL",
|
||||
"Gen_Action": "Azione",
|
||||
"Gen_Add": "Aggiungi",
|
||||
"Gen_Add_All": "Aggiungi tutti",
|
||||
@@ -311,7 +317,7 @@
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Questa è un'impostazione di manutenzione <b>ELIMINAZIONE dispositivi</b>. Se abilitata (<code>0</code> è disabilitata), tutti i dispositivi marcati con <b>Nuovo dispositivo</b> verranno eliminati se l'orario della <b>Prima sessione</b> è precedente all'orario di questa impostazione. Usa questa impostazione se vuoi eliminare automaticamente i <b>Nuovi dispositivi</b> dopo <code>X</code> ore.",
|
||||
"HRS_TO_KEEP_NEWDEV_name": "Elimina nuovi dispositivi dopo",
|
||||
"HRS_TO_KEEP_OFFDEV_description": "Questa è un'impostazione di manutenzione <b>ELIMINAZIONE dispositivi</b>. Se abilitata (<code>0</code> è disabilitata), i dispositivi che sono <b>Offline</b> e la loro data e ora <b>Ultima offline</b> sono più vecchi delle ore specificate in questa impostazione. Usa questa impostazione se vuoi eliminare automaticamente <b>Dispositivi offline</b> dopo <code>X</code> ore trascorse offline.",
|
||||
"HRS_TO_KEEP_OFFDEV_description": "Questa è un'impostazione di manutenzione <b>ELIMINAZIONE dispositivi</b>. Se abilitata (<code>0</code> è disabilitata), i dispositivi che sono <b>Offline</b> e la loro data e ora <b>Ultima offline</b> sono più vecchi delle ore specificate in questa impostazione saranno eliminati. Usa questa impostazione se vuoi eliminare automaticamente <b>Dispositivi offline</b> dopo <code>X</code> ore trascorse offline.",
|
||||
"HRS_TO_KEEP_OFFDEV_name": "Elimina dispositivi offline dopo",
|
||||
"HelpFAQ_Cat_Detail": "Dettagli",
|
||||
"HelpFAQ_Cat_Detail_300_head": "Cosa significa ",
|
||||
@@ -705,10 +711,11 @@
|
||||
"settings_publishers_icon": "fa-solid fa-paper-plane",
|
||||
"settings_publishers_info": "Carica più editori con l'impostazione <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
|
||||
"settings_publishers_label": "Editori",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "<br/>Impostazioni salvate. <br/> Aggiornamento in corso... <br/> <i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
|
||||
"settings_system_icon": "fa-solid fa-gear",
|
||||
"settings_system_label": "Sistema",
|
||||
"settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. <b>La convalida non viene eseguita.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// ###################################
|
||||
|
||||
$defaultLang = "en_us";
|
||||
$allLanguages = ["en_us", "es_es", "de_de", "fr_fr", "it_it", "ru_ru", "nb_no", "pl_pl", "pt_br", "tr_tr", "zh_cn", "cs_cz", "ar_ar"];
|
||||
$allLanguages = ["en_us", "es_es", "de_de", "fr_fr", "it_it", "ru_ru", "nb_no", "pl_pl", "pt_br", "tr_tr", "zh_cn", "cs_cz", "ar_ar", "ca_ca"];
|
||||
|
||||
|
||||
global $db;
|
||||
@@ -26,6 +26,7 @@ switch($result){
|
||||
case 'Chinese (zh_cn)': $pia_lang_selected = 'zh_cn'; break;
|
||||
case 'Czech (cs_cz)': $pia_lang_selected = 'cs_cz'; break;
|
||||
case 'Arabic (ar_ar)': $pia_lang_selected = 'ar_ar'; break;
|
||||
case 'Catalan (ca_ca)': $pia_lang_selected = 'ca_ca'; break;
|
||||
default: $pia_lang_selected = 'en_us'; break;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,6 @@ def merge_translations(main_file, other_files):
|
||||
if __name__ == "__main__":
|
||||
current_path = os.path.dirname(os.path.abspath(__file__))
|
||||
# language codes can be found here: http://www.lingoes.net/en/translator/langcode.htm
|
||||
json_files = ["en_us.json", "de_de.json", "es_es.json", "fr_fr.json", "nb_no.json", "ru_ru.json", "it_it.json", "pt_br.json", "pl_pl.json", "zh_cn.json", "tr_tr.json", "cs_cz.json", "ar_ar.json"]
|
||||
json_files = ["en_us.json", "de_de.json", "es_es.json", "fr_fr.json", "nb_no.json", "ru_ru.json", "it_it.json", "pt_br.json", "pl_pl.json", "zh_cn.json", "tr_tr.json", "cs_cz.json", "ar_ar.json", "ca_ca.json"]
|
||||
file_paths = [os.path.join(current_path, file) for file in json_files]
|
||||
merge_translations(file_paths[0], file_paths[1:])
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Du kan spesifisere en egendefinert SQL-Spørring som vil generere en JSON-fil og deretter eksponere den via <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> file endpoint</a>.",
|
||||
"API_CUSTOM_SQL_name": "Egendefinert endepunkt",
|
||||
"API_TOKEN_description": "",
|
||||
"API_TOKEN_name": "",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"About_Design": "Designet for:",
|
||||
@@ -197,6 +199,7 @@
|
||||
"Device_Shortcut_Favorites": "Favoritter",
|
||||
"Device_Shortcut_NewDevices": "Nye Enheter",
|
||||
"Device_Shortcut_OnlineChart": "Enhetens tilstedeværelse",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "Tilkoblinger",
|
||||
"Device_TableHead_Favorite": "Favoritt",
|
||||
"Device_TableHead_FirstSession": "Første Økt",
|
||||
@@ -214,6 +217,7 @@
|
||||
"Device_TableHead_Owner": "Eier",
|
||||
"Device_TableHead_Parent_MAC": "Overordnet node MAC",
|
||||
"Device_TableHead_Port": "Port",
|
||||
"Device_TableHead_PresentLastScan": "",
|
||||
"Device_TableHead_RowID": "Rad ID",
|
||||
"Device_TableHead_Rowid": "Rad ID",
|
||||
"Device_TableHead_SSID": "",
|
||||
@@ -270,6 +274,8 @@
|
||||
"Events_Tablelenght": "Show _MENU_ entries",
|
||||
"Events_Tablelenght_all": "Alle",
|
||||
"Events_Title": "Hendelser",
|
||||
"GRAPHQL_PORT_description": "",
|
||||
"GRAPHQL_PORT_name": "",
|
||||
"Gen_Action": "Handling",
|
||||
"Gen_Add": "Legg til",
|
||||
"Gen_Add_All": "Legg til alle",
|
||||
@@ -705,6 +711,7 @@
|
||||
"settings_publishers_icon": "fa-solid fa-paper-plane",
|
||||
"settings_publishers_info": "",
|
||||
"settings_publishers_label": "Utgivere",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "<br/>Innstillinger lagret. <br/> Laster inn på nytt... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i><br/>",
|
||||
"settings_system_icon": "fa-solid fa-gear",
|
||||
"settings_system_label": "System",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Możesz określić własne zapytanie SQL które będzie generowało plik JSON i udostępnić je poprzez plik typu endpoint <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> </a>.",
|
||||
"API_CUSTOM_SQL_name": "Własny endpoint",
|
||||
"API_TOKEN_description": "",
|
||||
"API_TOKEN_name": "",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"About_Design": "Zaprojektowany dla:",
|
||||
@@ -197,6 +199,7 @@
|
||||
"Device_Shortcut_Favorites": "Ulubione",
|
||||
"Device_Shortcut_NewDevices": "Nowe Urządzenia",
|
||||
"Device_Shortcut_OnlineChart": "Obecność urządzenia",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "Połączenia",
|
||||
"Device_TableHead_Favorite": "Ulubione",
|
||||
"Device_TableHead_FirstSession": "Pierwsza Sesja",
|
||||
@@ -214,6 +217,7 @@
|
||||
"Device_TableHead_Owner": "Właściciel",
|
||||
"Device_TableHead_Parent_MAC": "MAC rodzica węzła",
|
||||
"Device_TableHead_Port": "Port",
|
||||
"Device_TableHead_PresentLastScan": "",
|
||||
"Device_TableHead_RowID": "ID wiersza",
|
||||
"Device_TableHead_Rowid": "ID wiersza",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
@@ -270,6 +274,8 @@
|
||||
"Events_Tablelenght": "Pokaż_wpisy_MENU",
|
||||
"Events_Tablelenght_all": "Wszystkie",
|
||||
"Events_Title": "Wydarzenia",
|
||||
"GRAPHQL_PORT_description": "",
|
||||
"GRAPHQL_PORT_name": "",
|
||||
"Gen_Action": "Akcja",
|
||||
"Gen_Add": "Dodaj",
|
||||
"Gen_Add_All": "Dodaj wszystko",
|
||||
@@ -705,6 +711,7 @@
|
||||
"settings_publishers_icon": "fa-solid fa-paper-plane",
|
||||
"settings_publishers_info": "",
|
||||
"settings_publishers_label": "Wydawcy",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "<br/>Ustawienia zapisane.<br/>Przeładowanie...<br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i><br/>",
|
||||
"settings_system_icon": "fa-solid fa-gear",
|
||||
"settings_system_label": "System",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Você pode especificar uma consulta SQL personalizada que irá gerar um arquivo JSON e, em seguida, expô-lo por meio do <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> endpoint do arquivo</a>.",
|
||||
"API_CUSTOM_SQL_name": "Endpoint customizado",
|
||||
"API_TOKEN_description": "",
|
||||
"API_TOKEN_name": "",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"About_Design": "Desenvolvido por:",
|
||||
@@ -197,6 +199,7 @@
|
||||
"Device_Shortcut_Favorites": "Favoritos",
|
||||
"Device_Shortcut_NewDevices": "Novos dispositivos",
|
||||
"Device_Shortcut_OnlineChart": "Presença do dispositivo",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "Conexões",
|
||||
"Device_TableHead_Favorite": "Favorito",
|
||||
"Device_TableHead_FirstSession": "Primeira sessão",
|
||||
@@ -214,6 +217,7 @@
|
||||
"Device_TableHead_Owner": "Proprietário",
|
||||
"Device_TableHead_Parent_MAC": "Nó pai MAC",
|
||||
"Device_TableHead_Port": "Porta",
|
||||
"Device_TableHead_PresentLastScan": "",
|
||||
"Device_TableHead_RowID": "ID da linha",
|
||||
"Device_TableHead_Rowid": "ID da linha",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
@@ -270,6 +274,8 @@
|
||||
"Events_Tablelenght": "Mostrar entradas do _MENU_",
|
||||
"Events_Tablelenght_all": "Todos",
|
||||
"Events_Title": "Eventos",
|
||||
"GRAPHQL_PORT_description": "",
|
||||
"GRAPHQL_PORT_name": "",
|
||||
"Gen_Action": "Ação",
|
||||
"Gen_Add": "Adicionar",
|
||||
"Gen_Add_All": "Adicionar todos",
|
||||
@@ -705,6 +711,7 @@
|
||||
"settings_publishers_icon": "",
|
||||
"settings_publishers_info": "",
|
||||
"settings_publishers_label": "",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "",
|
||||
"settings_system_icon": "",
|
||||
"settings_system_label": "",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Вы можете указать собственный SQL-запрос, который будет генерировать файл JSON, а затем предоставлять его через конечную точку файла <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code></a>.",
|
||||
"API_CUSTOM_SQL_name": "Пользовательская конечная точка",
|
||||
"API_TOKEN_description": "API-токен для защиты соединения. Вы можете сгенерировать его или ввести любое значение. Он отправляется в заголовке запроса. Используется в плагине <code>SYNC</code> и GraphQL сервере.",
|
||||
"API_TOKEN_name": "API token",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"About_Design": "Разработан:",
|
||||
@@ -62,7 +64,7 @@
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Удалить события старше",
|
||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Скопировать данные с устройства",
|
||||
"DevDetail_Copy_Device_Tooltip": "Скопируйте данные с устройства из раскрывающегося списка. Все на этой странице будет перезаписано",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Оповещение о всех событиях",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Оповещения о событиях",
|
||||
"DevDetail_EveandAl_AlertDown": "Оповещение о доступности",
|
||||
"DevDetail_EveandAl_Archived": "Архив",
|
||||
"DevDetail_EveandAl_NewDevice": "Новое устройство",
|
||||
@@ -197,6 +199,7 @@
|
||||
"Device_Shortcut_Favorites": "Избранные",
|
||||
"Device_Shortcut_NewDevices": "Новые устройства",
|
||||
"Device_Shortcut_OnlineChart": "Присутствие устройств",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "Соединения",
|
||||
"Device_TableHead_Favorite": "Избранное",
|
||||
"Device_TableHead_FirstSession": "Первый сеанс",
|
||||
@@ -214,10 +217,11 @@
|
||||
"Device_TableHead_Owner": "Владелец",
|
||||
"Device_TableHead_Parent_MAC": "MAC род. узла",
|
||||
"Device_TableHead_Port": "Порт",
|
||||
"Device_TableHead_PresentLastScan": "",
|
||||
"Device_TableHead_RowID": "ID строки",
|
||||
"Device_TableHead_Rowid": "ID строки",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_SourcePlugin": "",
|
||||
"Device_TableHead_SourcePlugin": "Исходный плагин",
|
||||
"Device_TableHead_Status": "Статус",
|
||||
"Device_TableHead_SyncHubNodeName": "Узел синхронизации",
|
||||
"Device_TableHead_Type": "Тип",
|
||||
@@ -270,6 +274,8 @@
|
||||
"Events_Tablelenght": "Показать _MENU_ записей",
|
||||
"Events_Tablelenght_all": "Все",
|
||||
"Events_Title": "События",
|
||||
"GRAPHQL_PORT_description": "Номер порта сервера GraphQL.",
|
||||
"GRAPHQL_PORT_name": "Порт GraphQL",
|
||||
"Gen_Action": "Действия",
|
||||
"Gen_Add": "Добавить",
|
||||
"Gen_Add_All": "Добавить все",
|
||||
@@ -285,7 +291,7 @@
|
||||
"Gen_Description": "Описание",
|
||||
"Gen_Error": "Ошибка",
|
||||
"Gen_Filter": "Фильтр",
|
||||
"Gen_Generate": "",
|
||||
"Gen_Generate": "Генерировать",
|
||||
"Gen_LockedDB": "ОШИБКА - Возможно, база данных заблокирована. Проверьте инструменты разработчика F12 -> Консоль или повторите попытку позже.",
|
||||
"Gen_Offline": "Оффлайн",
|
||||
"Gen_Okay": "OK",
|
||||
@@ -311,8 +317,8 @@
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "Это настройка обслуживания <b>УДАЛЕНИЕ устройств</b>. Если этот параметр включен (<code>0</code> отключен), устройства, помеченные как <b>Новое устройство</b>, будут удалены, если время их <b>Первого сеанса</b> было старше указанных в этой настройке часов. Используйте этот параметр, если вы хотите автоматически удалять <b>Новые устройства</b> через <code>X</code> часов.",
|
||||
"HRS_TO_KEEP_NEWDEV_name": "Удалить новые устройства после",
|
||||
"HRS_TO_KEEP_OFFDEV_description": "",
|
||||
"HRS_TO_KEEP_OFFDEV_name": "",
|
||||
"HRS_TO_KEEP_OFFDEV_description": "Это настройка обслуживания <b>УДАЛЕНИЕ устройств</b>. Если этот параметр включен (<code>0</code> отключен), устройства, которые находятся <b>в Offline</b> и их дата и время <b>последнего Offline</b> старше, чем часы, указанные в этом параметре. Используйте этот параметр, если вы хотите автоматически удалять <b>Offline устройства</b> после <code>X</code> часов отсутствия в сети.",
|
||||
"HRS_TO_KEEP_OFFDEV_name": "Удалить устройства Offline после",
|
||||
"HelpFAQ_Cat_Detail": "Подробности",
|
||||
"HelpFAQ_Cat_Detail_300_head": "Что значит ",
|
||||
"HelpFAQ_Cat_Detail_300_text_a": "означает сетевое устройство (типа AP, шлюз, межсетевой экран, гипервизор, Powerline, коммутатор, WLAN, PLC, маршрутизатор, USB-адаптер локальной сети, USB-адаптер Wi-Fi или Интернет). Пользовательские типы можно добавить с помощью параметра <code>NETWORK_DEVICE_TYPES</code>.",
|
||||
@@ -374,12 +380,12 @@
|
||||
"Maintenance_Running_Version": "Установленная версия",
|
||||
"Maintenance_Status": "Статус",
|
||||
"Maintenance_Title": "Инструменты обслуживания",
|
||||
"Maintenance_Tool_ExportCSV": "CSV Экспорт",
|
||||
"Maintenance_Tool_ExportCSV_noti": "CSV Экспорт",
|
||||
"Maintenance_Tool_ExportCSV": "Экспорт CSV",
|
||||
"Maintenance_Tool_ExportCSV_noti": "Экспорт CSV",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Вы уверены, что хотите создать файл CSV?",
|
||||
"Maintenance_Tool_ExportCSV_text": "Создайте файл CSV (значения, разделенные запятыми), содержащий список устройств, включая сетевые отношения между сетевыми узлами и подключенными устройствами. Вы также можете открыть этот URL-адрес <code> URL Вашего NetAlertX/php/server/devices.php?action=ExportCSV</code> или включить плагин <a href=\"settings.php#CSVBCKP_header\">Резервное копирование в CSV</a>.",
|
||||
"Maintenance_Tool_ImportCSV": "CSV Импорт",
|
||||
"Maintenance_Tool_ImportCSV_noti": "CSV Импорт",
|
||||
"Maintenance_Tool_ImportCSV": "Импорт CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Импорт CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Вы уверены, что хотите импортировать файл CSV? Это полностью <b>перезапишет</b> устройства в вашей базе данных.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Импортируйте файл CSV (значения, разделенные запятыми), содержащий список устройств, включая сетевые отношения между сетевыми узлами и подключенными устройствами. Для этого поместите файл CSV с именем <b>devices.csv</b> в папку <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Импорт CSV (вставка)",
|
||||
@@ -420,8 +426,8 @@
|
||||
"Maintenance_Tool_del_empty_macs_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Все устройства без MAC-адресов будут удалены из базы данных.",
|
||||
"Maintenance_Tool_del_selecteddev": "Удалить выбранные устройства",
|
||||
"Maintenance_Tool_del_selecteddev_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Выбранные устройства будут удалены из базы данных.",
|
||||
"Maintenance_Tool_del_unknowndev": "Удалить неизвестные устройства",
|
||||
"Maintenance_Tool_del_unknowndev_noti": "Удалить (неизвестные) устройства",
|
||||
"Maintenance_Tool_del_unknowndev": "Удалить неизвест. устр-ва",
|
||||
"Maintenance_Tool_del_unknowndev_noti": "Удалить неизвест. устр-ва",
|
||||
"Maintenance_Tool_del_unknowndev_noti_text": "Вы уверены, что хотите удалить все (неизвестные) и (имя не найдено) устройства?",
|
||||
"Maintenance_Tool_del_unknowndev_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Все названные устройства (неизвестные) будут удалены из базы данных.",
|
||||
"Maintenance_Tool_displayed_columns_text": "Измените видимость и порядок столбцов на странице <a href=\"devices.php\"><b> <i class=\"fa fa-laptop\"></i> Устройства</b></a>.",
|
||||
@@ -549,12 +555,12 @@
|
||||
"Presence_CalHead_week": "неделя",
|
||||
"Presence_CalHead_year": "год",
|
||||
"Presence_CallHead_Devices": "Устройства",
|
||||
"Presence_Key_OnlineNow": "",
|
||||
"Presence_Key_OnlineNow_desc": "",
|
||||
"Presence_Key_OnlinePast": "",
|
||||
"Presence_Key_OnlinePastMiss": "",
|
||||
"Presence_Key_OnlinePastMiss_desc": "",
|
||||
"Presence_Key_OnlinePast_desc": "",
|
||||
"Presence_Key_OnlineNow": "Сейчас в сети",
|
||||
"Presence_Key_OnlineNow_desc": "Устройство, обнаруженное при последнем сканировании как подключенное к сети.",
|
||||
"Presence_Key_OnlinePast": "В прошлом в сети",
|
||||
"Presence_Key_OnlinePastMiss": "В прошлом в сети (несовпадение)",
|
||||
"Presence_Key_OnlinePastMiss_desc": "Устройство в прошлом было подключено к сети, но сейчас находится в автономном режиме, однако стартовый сеанс может отсутствовать или иметь противоречивые данные. (Возможно, это ошибка — отправьте PR, если знаете, как это исправить — здесь я немного запутался в коде)",
|
||||
"Presence_Key_OnlinePast_desc": "Устройство раньше было в сети, но в настоящее время не в сети.",
|
||||
"Presence_Loading": "Загрузка...",
|
||||
"Presence_Shortcut_AllDevices": "Мои устройства",
|
||||
"Presence_Shortcut_Archived": "Архив",
|
||||
@@ -705,6 +711,7 @@
|
||||
"settings_publishers_icon": "fa-solid fa-paper-plane",
|
||||
"settings_publishers_info": "Загрузите больше нотификаторов с помощью настройки <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a>",
|
||||
"settings_publishers_label": "Уведомления",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "<br/>Настройки сохранены. <br/> Перезагрузка... <br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
|
||||
"settings_system_icon": "fa-solid fa-gear",
|
||||
"settings_system_label": "Система",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "",
|
||||
"API_CUSTOM_SQL_name": "",
|
||||
"API_TOKEN_description": "",
|
||||
"API_TOKEN_name": "",
|
||||
"API_display_name": "",
|
||||
"API_icon": "",
|
||||
"About_Design": "",
|
||||
@@ -197,6 +199,7 @@
|
||||
"Device_Shortcut_Favorites": "Favoriler",
|
||||
"Device_Shortcut_NewDevices": "Yeni Cİhazlar",
|
||||
"Device_Shortcut_OnlineChart": "",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "Bağlantılar",
|
||||
"Device_TableHead_Favorite": "",
|
||||
"Device_TableHead_FirstSession": "İlk Oturum",
|
||||
@@ -214,6 +217,7 @@
|
||||
"Device_TableHead_Owner": "",
|
||||
"Device_TableHead_Parent_MAC": "",
|
||||
"Device_TableHead_Port": "",
|
||||
"Device_TableHead_PresentLastScan": "",
|
||||
"Device_TableHead_RowID": "",
|
||||
"Device_TableHead_Rowid": "",
|
||||
"Device_TableHead_SSID": "",
|
||||
@@ -270,6 +274,8 @@
|
||||
"Events_Tablelenght": "",
|
||||
"Events_Tablelenght_all": "",
|
||||
"Events_Title": "",
|
||||
"GRAPHQL_PORT_description": "",
|
||||
"GRAPHQL_PORT_name": "",
|
||||
"Gen_Action": "Komut",
|
||||
"Gen_Add": "Ekle",
|
||||
"Gen_Add_All": "Tümünü ekle",
|
||||
@@ -705,6 +711,7 @@
|
||||
"settings_publishers_icon": "",
|
||||
"settings_publishers_info": "",
|
||||
"settings_publishers_label": "",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "",
|
||||
"settings_system_icon": "",
|
||||
"settings_system_label": "Sistem",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "您可以指定一个自定义 SQL 查询,它将生成一个 JSON 文件,然后通过 <a href=\"/api/table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> 文件端点</a> 公开它。",
|
||||
"API_CUSTOM_SQL_name": "自定义终点",
|
||||
"API_TOKEN_description": "",
|
||||
"API_TOKEN_name": "",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"About_Design": "设计用于:",
|
||||
@@ -197,6 +199,7 @@
|
||||
"Device_Shortcut_Favorites": "收藏",
|
||||
"Device_Shortcut_NewDevices": "新设备",
|
||||
"Device_Shortcut_OnlineChart": "设备统计",
|
||||
"Device_TableHead_AlertDown": "",
|
||||
"Device_TableHead_Connected_Devices": "链接",
|
||||
"Device_TableHead_Favorite": "收藏",
|
||||
"Device_TableHead_FirstSession": "加入",
|
||||
@@ -214,6 +217,7 @@
|
||||
"Device_TableHead_Owner": "所有者",
|
||||
"Device_TableHead_Parent_MAC": "父节点",
|
||||
"Device_TableHead_Port": "端口",
|
||||
"Device_TableHead_PresentLastScan": "",
|
||||
"Device_TableHead_RowID": "排行",
|
||||
"Device_TableHead_Rowid": "排行",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
@@ -270,6 +274,8 @@
|
||||
"Events_Tablelenght": "",
|
||||
"Events_Tablelenght_all": "全部",
|
||||
"Events_Title": "事件",
|
||||
"GRAPHQL_PORT_description": "",
|
||||
"GRAPHQL_PORT_name": "",
|
||||
"Gen_Action": "动作",
|
||||
"Gen_Add": "增加",
|
||||
"Gen_Add_All": "全部添加",
|
||||
@@ -705,6 +711,7 @@
|
||||
"settings_publishers_icon": "",
|
||||
"settings_publishers_info": "使用 <a href=\"/settings.php#LOADED_PLUGINS\">LOADED_PLUGINS</a> 设置加载更多发布商",
|
||||
"settings_publishers_label": "出版商",
|
||||
"settings_readonly": "",
|
||||
"settings_saved": "<br/>设置已保存。<br/> 正在加载...<br/><i class=\"ion ion-ios-loop-strong fa-spin fa-2x fa-fw\"></i> <br/>",
|
||||
"settings_system_icon": "",
|
||||
"settings_system_label": "系统",
|
||||
|
||||
@@ -55,7 +55,7 @@ $configLines = file(CONFIG_PATH);
|
||||
// Handle web protection and password
|
||||
$nax_WebProtection = strtolower(trim(getConfigLine('/^SETPWD_enable_password.*=/', $configLines)[1] ?? 'false'));
|
||||
$nax_Password = getConfigValue('/^SETPWD_password.*=/', $configLines);
|
||||
$api_token = getConfigValue('/^SYNC_api_token.*=/', $configLines, "'");
|
||||
$api_token = getConfigValue('/^API_TOKEN.*=/', $configLines, "'");
|
||||
|
||||
$expectedToken = 'Bearer ' . $api_token;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from email.header import Header
|
||||
from email.utils import parseaddr
|
||||
from email.utils import formatdate
|
||||
import smtplib
|
||||
import socket
|
||||
import ssl
|
||||
@@ -118,6 +119,8 @@ def send(pHTML, pText):
|
||||
msg['Subject'] = subject
|
||||
msg['From'] = from_email
|
||||
msg['To'] = to_email
|
||||
msg['Date'] = formatdate(localtime=True)
|
||||
|
||||
msg.attach (MIMEText (message_text, 'plain'))
|
||||
msg.attach (MIMEText (message_html, 'html'))
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
{
|
||||
"name": "devices",
|
||||
"type": "sql",
|
||||
"value": "SELECT dev_LastIP from DEVICES",
|
||||
"value": "SELECT devLastIP from DEVICES",
|
||||
"timeoutMultiplier": true
|
||||
}
|
||||
],
|
||||
@@ -740,7 +740,7 @@
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "select rowid, * from Devices where dev_Name not in ({s-quote}null{s-quote}, {s-quote}(name not found){s-quote}, {s-quote}(unknown){s-quote})",
|
||||
"default_value": "select rowid, * from Devices where devName not in ({s-quote}null{s-quote}, {s-quote}(name not found){s-quote}, {s-quote}(unknown){s-quote})",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
|
||||
@@ -443,49 +443,49 @@ def mqtt_start(db):
|
||||
for device in devices:
|
||||
|
||||
# # debug statement START 🔻
|
||||
# if 'Moto' not in device["dev_Name"]:
|
||||
# if 'Moto' not in device["devName"]:
|
||||
# continue
|
||||
# # debug statement END 🔺
|
||||
|
||||
# Create devices in Home Assistant - send config messages
|
||||
deviceId = 'mac_' + device["dev_MAC"].replace(" ", "").replace(":", "_").lower()
|
||||
deviceId = 'mac_' + device["devMac"].replace(" ", "").replace(":", "_").lower()
|
||||
# Normalize the string and remove unwanted characters
|
||||
devDisplayName = re.sub('[^a-zA-Z0-9-_\\s]', '', normalize_string(device["dev_Name"]))
|
||||
devDisplayName = re.sub('[^a-zA-Z0-9-_\\s]', '', normalize_string(device["devName"]))
|
||||
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'last_ip', 'ip-network', device["dev_MAC"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'mac_address', 'folder-key-network', device["dev_MAC"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'is_new', 'bell-alert-outline', device["dev_MAC"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'vendor', 'cog', device["dev_MAC"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'first_connection', 'calendar-start', device["dev_MAC"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'last_connection', 'calendar-end', device["dev_MAC"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'last_ip', 'ip-network', device["devMac"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'mac_address', 'folder-key-network', device["devMac"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'is_new', 'bell-alert-outline', device["devMac"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'vendor', 'cog', device["devMac"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'first_connection', 'calendar-start', device["devMac"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'last_connection', 'calendar-end', device["devMac"])
|
||||
|
||||
|
||||
devJson = {
|
||||
"last_ip": device["dev_LastIP"],
|
||||
"is_new": str(device["dev_NewDevice"]),
|
||||
"vendor": sanitize_string(device["dev_Vendor"]),
|
||||
"mac_address": str(device["dev_MAC"]),
|
||||
"last_ip": device["devLastIP"],
|
||||
"is_new": str(device["devIsNew"]),
|
||||
"vendor": sanitize_string(device["devVendor"]),
|
||||
"mac_address": str(device["devMac"]),
|
||||
"model": devDisplayName,
|
||||
"last_connection": prepTimeStamp(str(device["dev_LastConnection"])),
|
||||
"first_connection": prepTimeStamp(str(device["dev_FirstConnection"])) }
|
||||
"last_connection": prepTimeStamp(str(device["devLastConnection"])),
|
||||
"first_connection": prepTimeStamp(str(device["devFirstConnection"])) }
|
||||
|
||||
# bulk update device sensors in home assistant
|
||||
publish_mqtt(mqtt_client, sensorConfig.state_topic, devJson)
|
||||
|
||||
# create and update is_present sensor
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'binary_sensor', 'is_present', 'wifi', device["dev_MAC"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'binary_sensor', 'is_present', 'wifi', device["devMac"])
|
||||
publish_mqtt(mqtt_client, sensorConfig.state_topic,
|
||||
{
|
||||
"is_present": to_binary_sensor(str(device["dev_PresentLastScan"]))
|
||||
"is_present": to_binary_sensor(str(device["devPresentLastScan"]))
|
||||
}
|
||||
)
|
||||
|
||||
# handle device_tracker
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'device_tracker', 'is_home', 'home', device["dev_MAC"])
|
||||
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'device_tracker', 'is_home', 'home', device["devMac"])
|
||||
|
||||
# <away|home> are only valid states
|
||||
state = 'away'
|
||||
if to_binary_sensor(str(device["dev_PresentLastScan"])) == "ON":
|
||||
if to_binary_sensor(str(device["devPresentLastScan"])) == "ON":
|
||||
state = 'home'
|
||||
|
||||
publish_mqtt(mqtt_client, sensorConfig.state_topic, state)
|
||||
|
||||
@@ -112,7 +112,7 @@ def execute_arpscan(userSubnets):
|
||||
re_ip = r'(?P<ip>((2[0-5]|1[0-9]|[0-9])?[0-9]\.){3}((2[0-5]|1[0-9]|[0-9])?[0-9]))'
|
||||
re_mac = r'(?P<mac>([0-9a-fA-F]{2}[:-]){5}([0-9a-fA-F]{2}))'
|
||||
re_hw = r'(?P<hw>.*)'
|
||||
re_pattern = re.compile (re_ip + '\s+' + re_mac + '\s' + re_hw)
|
||||
re_pattern = re.compile(rf"{re_ip}\s+{re_mac}\s{re_hw}")
|
||||
|
||||
devices_list_tmp = [
|
||||
{**device.groupdict(), "interface": interface}
|
||||
|
||||
@@ -56,9 +56,9 @@ def main():
|
||||
|
||||
# Mock list of devices (replace with actual device_handler.getUnknown() in production)
|
||||
# unknown_devices = [
|
||||
# {'dev_MAC': '00:11:22:33:44:55', 'dev_LastIP': '192.168.1.121'},
|
||||
# {'dev_MAC': '00:11:22:33:44:56', 'dev_LastIP': '192.168.1.9'},
|
||||
# {'dev_MAC': '00:11:22:33:44:57', 'dev_LastIP': '192.168.1.82'},
|
||||
# {'devMac': '00:11:22:33:44:55', 'devLastIP': '192.168.1.121'},
|
||||
# {'devMac': '00:11:22:33:44:56', 'devLastIP': '192.168.1.9'},
|
||||
# {'devMac': '00:11:22:33:44:57', 'devLastIP': '192.168.1.82'},
|
||||
# ]
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] Unknown devices count: {len(unknown_devices)}'])
|
||||
@@ -68,20 +68,20 @@ def main():
|
||||
ensure_avahi_running()
|
||||
|
||||
for device in unknown_devices:
|
||||
domain_name = execute_name_lookup(device['dev_LastIP'], timeout)
|
||||
domain_name = execute_name_lookup(device['devLastIP'], timeout)
|
||||
|
||||
# check if found and not a timeout ('to')
|
||||
if domain_name != '' and domain_name != 'to':
|
||||
plugin_objects.add_object(
|
||||
# "MAC", "IP", "Server", "Name"
|
||||
primaryId = device['dev_MAC'],
|
||||
secondaryId = device['dev_LastIP'],
|
||||
primaryId = device['devMac'],
|
||||
secondaryId = device['devLastIP'],
|
||||
watched1 = '', # You can add any relevant info here if needed
|
||||
watched2 = domain_name,
|
||||
watched3 = '',
|
||||
watched4 = '',
|
||||
extra = '',
|
||||
foreignKey = device['dev_MAC'])
|
||||
foreignKey = device['devMac'])
|
||||
|
||||
plugin_objects.write_result_file()
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
{
|
||||
"name": "ips",
|
||||
"type": "sql",
|
||||
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC",
|
||||
"value": "SELECT devLastIP from DEVICES order by devMac",
|
||||
"timeoutMultiplier": true
|
||||
}
|
||||
],
|
||||
@@ -79,7 +79,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "When the plugin should be executed. If enabled this will execute the scan until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Setting this to <code>on_new_device</code> or a daily <code>schedule</code> is recommended."
|
||||
"string": "When the plugin should be executed. If enabled this will execute the scan until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Setting this to <code>before_name_updates</code> is recommended."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -141,7 +141,7 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP
|
||||
# Cleanup New Devices
|
||||
if HRS_TO_KEEP_NEWDEV != 0:
|
||||
mylog('verbose', [f'[{pluginName}] Devices: Delete all New Devices older than {str(HRS_TO_KEEP_NEWDEV)} hours (HRS_TO_KEEP_NEWDEV setting)'])
|
||||
query = f"""DELETE FROM Devices WHERE dev_NewDevice = 1 AND dev_FirstConnection < date('now', '-{str(HRS_TO_KEEP_NEWDEV)} hour')"""
|
||||
query = f"""DELETE FROM Devices WHERE devIsNew = 1 AND devFirstConnection < date('now', '-{str(HRS_TO_KEEP_NEWDEV)} hour')"""
|
||||
mylog('verbose', [f'[{pluginName}] Query: {query} '])
|
||||
cursor.execute (query)
|
||||
|
||||
@@ -149,7 +149,7 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP
|
||||
# Cleanup Offline Devices
|
||||
if HRS_TO_KEEP_OFFDEV != 0:
|
||||
mylog('verbose', [f'[{pluginName}] Devices: Delete all New Devices older than {str(HRS_TO_KEEP_OFFDEV)} hours (HRS_TO_KEEP_OFFDEV setting)'])
|
||||
query = f"""DELETE FROM Devices WHERE dev_PresentLastScan = 0 AND dev_LastConnection < date('now', '-{str(HRS_TO_KEEP_OFFDEV)} hour'))"""
|
||||
query = f"""DELETE FROM Devices WHERE devPresentLastScan = 0 AND devLastConnection < date('now', '-{str(HRS_TO_KEEP_OFFDEV)} hour'))"""
|
||||
mylog('verbose', [f'[{pluginName}] Query: {query} '])
|
||||
cursor.execute (query)
|
||||
|
||||
@@ -157,8 +157,8 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP
|
||||
# Clear New Flag
|
||||
if CLEAR_NEW_FLAG != 0:
|
||||
mylog('verbose', [f'[{pluginName}] Devices: Clear "New Device" flag for all devices older than {str(CLEAR_NEW_FLAG)} hours (CLEAR_NEW_FLAG setting)'])
|
||||
query = f"""UPDATE Devices SET dev_NewDevice = 0 WHERE dev_NewDevice = 1 AND date(dev_FirstConnection, '+{str(CLEAR_NEW_FLAG)} hour') < date('now')"""
|
||||
# select * from Devices where dev_NewDevice = 1 AND date(dev_FirstConnection, '+3 hour' ) < date('now')
|
||||
query = f"""UPDATE Devices SET devIsNew = 0 WHERE devIsNew = 1 AND date(devFirstConnection, '+{str(CLEAR_NEW_FLAG)} hour') < date('now')"""
|
||||
# select * from Devices where devIsNew = 1 AND date(devFirstConnection, '+3 hour' ) < date('now')
|
||||
mylog('verbose', [f'[{pluginName}] Query: {query} '])
|
||||
cursor.execute(query)
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
{
|
||||
"name": "prev_ip",
|
||||
"type": "sql",
|
||||
"value": "SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet' "
|
||||
"value": "SELECT devLastIP FROM Devices WHERE devMac = 'Internet' "
|
||||
},
|
||||
{
|
||||
"name": "DDNS_UPDATE_URL",
|
||||
|
||||
@@ -1,967 +0,0 @@
|
||||
{
|
||||
"code_name": "events_notifications",
|
||||
"plugin_type": "flow",
|
||||
"template_type": "database-entry",
|
||||
"unique_prefix": "EVNTNTF",
|
||||
"enabled": true,
|
||||
"data_source": "template",
|
||||
"show_ui": false,
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"display_name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Known Devices"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The template used for known devices."
|
||||
}
|
||||
],
|
||||
"icon": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "<i class=\"fa fa-check\"></i>"
|
||||
}
|
||||
],
|
||||
"params": [
|
||||
{
|
||||
"name": "target_macs",
|
||||
"type": "setting",
|
||||
"value": "KNWN_target_macs"
|
||||
},
|
||||
{
|
||||
"name": "dev_AlertDeviceDown",
|
||||
"type": "setting",
|
||||
"value": "KNWN_dev_AlertDeviceDown"
|
||||
},
|
||||
{
|
||||
"name": "dev_AlertEvents",
|
||||
"type": "setting",
|
||||
"value": "KNWN_dev_AlertEvents"
|
||||
},
|
||||
{
|
||||
"name": "trigger_ids",
|
||||
"type": "array",
|
||||
"value": "trigger.Object_PrimaryID"
|
||||
},
|
||||
{
|
||||
"name": "trigger_objects",
|
||||
"type": "array",
|
||||
"value": "trigger"
|
||||
}
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"function": "FLOW",
|
||||
"type": "json",
|
||||
"default_value": [
|
||||
{
|
||||
"name": "send_notification",
|
||||
"trigger": [
|
||||
{
|
||||
"object_event": "new",
|
||||
"object_filter": "",
|
||||
"object": "Events_Notifications"
|
||||
}
|
||||
],
|
||||
"steps": [
|
||||
{
|
||||
"step_type": "wait",
|
||||
"params": [
|
||||
{
|
||||
"days": 0,
|
||||
"hours": 0,
|
||||
"minutes": 0,
|
||||
"seconds": 30
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"step_type": "condition",
|
||||
"params": [
|
||||
{
|
||||
"left": {
|
||||
"value": "triggers[0].object['dev_DeviceID']",
|
||||
"use_quotes": true,
|
||||
"js_template": "'{value}'.toString()"
|
||||
},
|
||||
"operator": {
|
||||
"value": "==",
|
||||
"data_type": "string"
|
||||
},
|
||||
"right": {
|
||||
"value": "device_id_param",
|
||||
"use_quotes": false,
|
||||
"js_template": "'{value}'.toString()"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"step_type": "condition",
|
||||
"params": [
|
||||
{
|
||||
"left": {
|
||||
"value": "check_event_repetition(device_id_param, event_type_param, repetition_count_param)",
|
||||
"use_quotes": false,
|
||||
"js_template": "{value}"
|
||||
},
|
||||
"operator": {
|
||||
"value": "==",
|
||||
"data_type": "boolean"
|
||||
},
|
||||
"right": {
|
||||
"value": true,
|
||||
"use_quotes": false,
|
||||
"js_template": "{value}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"step_type": "action",
|
||||
"params": [
|
||||
{
|
||||
"type": "run_plugin",
|
||||
"params": {
|
||||
"unique_prefix": "webhook"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"step_type": "action",
|
||||
"params": [
|
||||
{
|
||||
"type": "run_plugin",
|
||||
"params": {
|
||||
"unique_prefix": "mqtt"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
{
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device ID Parameter"
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "1",
|
||||
"localized": ["name"]
|
||||
},
|
||||
{
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Event Type Parameter"
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "device_down",
|
||||
"localized": ["name"]
|
||||
},
|
||||
{
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Repetition Count Parameter"
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 3,
|
||||
"localized": ["name"]
|
||||
}
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Plugin flow"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "This flow sends a notification after 30s every time a new event is logged."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "target_macs",
|
||||
"type": "list.readonly",
|
||||
"maxLength": 50,
|
||||
"default_value": [],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Target devices"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The MAC address of the devices to update. Uneditable. This parameter is dynamically updated via a Flow."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "UPDATE Devices SET dev_AlertDeviceDown = {KNWN_dev_AlertDeviceDown}, dev_AlertEvents = {KNWN_dev_AlertEvents} WHERE dev_MAC in ({target_macs})",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "UPDATE SQL"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "This SQL query is used to update target devices."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Name",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "(unknown)",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Name"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The name of the device. Uneditable as internal functionality is dependent on specific new device names."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Owner",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 30,
|
||||
"default_value": "House",
|
||||
"override_value": {
|
||||
"override": false
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Owner"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The owner of the device."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_DeviceType",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 30,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Type"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The type of the device."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Vendor",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 250,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Vendor"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The vendor of the device. Uneditable - Autodetected."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Favorite",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"override_value": {
|
||||
"override": false
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Favorite Device"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether the device is marked as a favorite."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Group",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 10,
|
||||
"default_value": "",
|
||||
"override_value": {
|
||||
"override": false
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Group"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The group to which the device belongs."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Comments",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Comments"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Additional comments or notes about the device."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_FirstConnection",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "First Connection"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The date and time of the first connection with the device. Uneditable - Autodetected."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_LastConnection",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Last Connection"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The date and time of the last connection with the device. Uneditable - Autodetected."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_LastIP",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Last IP"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The last known IP address of the device. Uneditable - Autodetected."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_StaticIP",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"override_value": {
|
||||
"override": true
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Static IP"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether the device has a static IP address."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_ScanCycle",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"override_value": {
|
||||
"override": true
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Scan Cycle"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The default value of the <code>Scan device</code> dropdown. Enable if newly discovered devices should be scanned."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_LogEvents",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"override_value": {
|
||||
"override": false
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Log Events"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether events related to the device shouldbe logged."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_AlertEvents",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"override_value": {
|
||||
"override": true
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Alert Events"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether events related to the device should trigger alerts. The default value of the <code>Alert Events</code> checkbox. Down and New Device notifications are always sent unless unselected in <code>NTFPRCS_INCLUDED_SECTIONS</code>."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_AlertDeviceDown",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Alert Device Down"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether an alert should be triggered when the device goes down. The default value of the <code>Alert Down</code> checkbox."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_SkipRepeated",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Skip Repeated"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The default value of the <code>Skip repeated notifications for</code> dropdown. Enter number of <b>hours</b> for which repeated notifications should be ignored for. If you enter <code>0</code> then you get notified on all events."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_LastNotification",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Last Notification"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The date and time of the last notification sent for the device. Uneditable - Autodetected."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_PresentLastScan",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Present Last Scan"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether the device should be marked as present after detected in a scan."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_NewDevice",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": true,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "New Device"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether the device is considered a new device. The default value of the <code>New Device</code> checkbox."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Location",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 250,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Location"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The location of the device."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Archived",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Archived"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether the device is archived. The default value of the <code>Archived</code> checkbox."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Network_Node_MAC_ADDR",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Network Node MAC Address"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The MAC address of the network node."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Network_Node_port",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Network Node Port"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The port number of the network node. Uneditable."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Icon",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Icon"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The icon associated with the device. Check the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md\" target=\"_blank\">documentation on icons</a> for more details."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"required": [
|
||||
"dev_MAC",
|
||||
"dev_Name",
|
||||
"dev_Owner",
|
||||
"dev_FirstConnection",
|
||||
"dev_LastConnection",
|
||||
"dev_LastIP",
|
||||
"dev_StaticIP",
|
||||
"dev_ScanCycle",
|
||||
"dev_LogEvents",
|
||||
"dev_AlertEvents",
|
||||
"dev_AlertDeviceDown",
|
||||
"dev_SkipRepeated",
|
||||
"dev_LastNotification",
|
||||
"dev_PresentLastScan",
|
||||
"dev_NewDevice",
|
||||
"dev_Location",
|
||||
"dev_Archived",
|
||||
"dev_Network_Node_MAC_ADDR",
|
||||
"dev_Network_Node_port",
|
||||
"dev_Icon"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
This plugin will not be loaded
|
||||
@@ -51,7 +51,7 @@
|
||||
{
|
||||
"name": "prev_ip",
|
||||
"type": "sql",
|
||||
"value": "SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet' "
|
||||
"value": "SELECT devLastIP FROM Devices WHERE devMac = 'Internet' "
|
||||
},
|
||||
{
|
||||
"name": "INTRNT_DIG_GET_IP_ARG",
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
## Overview
|
||||
|
||||
A simple template-based plugin for known devices. You can change to overwrite values for known devices.
|
||||
|
||||
### Usage
|
||||
|
||||
- Head to **Settings** > **Known Devices** to adjust the default values.
|
||||
|
||||
### Notes
|
||||
|
||||
- This plugin generates editable settings that are then used in the `device.py` script to initialize new values. TO FIX
|
||||
@@ -1,883 +0,0 @@
|
||||
{
|
||||
"code_name": "known_template",
|
||||
"template_type": "database-entry",
|
||||
"unique_prefix": "KNWN",
|
||||
"plugin_type": "system",
|
||||
"enabled": true,
|
||||
"data_source": "template",
|
||||
"show_ui": false,
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"display_name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Known Devices"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The template used for known devices."
|
||||
}
|
||||
],
|
||||
"icon": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "<i class=\"fa fa-check\"></i>"
|
||||
}
|
||||
],
|
||||
"params": [
|
||||
{
|
||||
"name": "target_macs",
|
||||
"type": "setting",
|
||||
"value": "KNWN_target_macs"
|
||||
},
|
||||
{
|
||||
"name": "dev_AlertDeviceDown",
|
||||
"type": "setting",
|
||||
"value": "KNWN_dev_AlertDeviceDown"
|
||||
},
|
||||
{
|
||||
"name": "dev_AlertEvents",
|
||||
"type": "setting",
|
||||
"value": "KNWN_dev_AlertEvents"
|
||||
},
|
||||
{
|
||||
"name": "trigger_ids",
|
||||
"type": "array",
|
||||
"value": "trigger.Object_PrimaryID"
|
||||
},
|
||||
{
|
||||
"name": "trigger_objects",
|
||||
"type": "array",
|
||||
"value": "trigger"
|
||||
}
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"function": "FLOW",
|
||||
"type": "json",
|
||||
"default_value": [
|
||||
{
|
||||
"name": "apply_template",
|
||||
"trigger": [
|
||||
{
|
||||
"object_event": "new",
|
||||
"object_filter": "",
|
||||
"object": "Devices"
|
||||
}
|
||||
],
|
||||
"steps": [
|
||||
{
|
||||
"step_type": "wait",
|
||||
"params": [
|
||||
{
|
||||
"days": 3,
|
||||
"hours": 0,
|
||||
"minutes": 0,
|
||||
"seconds": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"step_type": "condition",
|
||||
"params": [
|
||||
{
|
||||
"left": {
|
||||
"value": "triggers[0].object['dev_NewDevice']",
|
||||
"use_quotes": true,
|
||||
"js_template": "'{value}'.toString()"
|
||||
},
|
||||
"operator": {
|
||||
"value": "==",
|
||||
"data_type": "boolean"
|
||||
},
|
||||
"right": {
|
||||
"value": true,
|
||||
"use_quotes": false,
|
||||
"js_template": "'{value}'.toString()"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"step_type": "action",
|
||||
"params": [
|
||||
{
|
||||
"type": "plugin",
|
||||
"params": {
|
||||
"unique_prefix": "KNWN",
|
||||
"overrides": [
|
||||
{
|
||||
"object_path": "settings.0",
|
||||
"key": "function",
|
||||
"value": "target_macs",
|
||||
"target_property": "default_value",
|
||||
"desired_value": "triggers.keys"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Plugin flow"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "This flow makes sure the template is applied to devices that are older than 3 days."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "target_macs",
|
||||
"type": "list.readonly",
|
||||
"maxLength": 50,
|
||||
"default_value": [],
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Target devices"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The MAC address of the devices to update. Uneditable. This parameter is dynamically updated via a Flow."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "UPDATE Devices SET dev_AlertDeviceDown = {KNWN_dev_AlertDeviceDown}, dev_AlertEvents = {KNWN_dev_AlertEvents} WHERE dev_MAC in ({target_macs})",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "UPDATE SQL"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "This SQL query is used to update target devices."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Name",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "(unknown)",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Name"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The name of the device. Uneditable as internal functionality is dependent on specific new device names."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Owner",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 30,
|
||||
"default_value": "House",
|
||||
"override_value": {
|
||||
"override": false
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Owner"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The owner of the device."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_DeviceType",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 30,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Type"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The type of the device."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Vendor",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 250,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Vendor"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The vendor of the device. Uneditable - Autodetected."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Favorite",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"override_value": {
|
||||
"override": false
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Favorite Device"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether the device is marked as a favorite."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Group",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 10,
|
||||
"default_value": "",
|
||||
"override_value": {
|
||||
"override": false
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Group"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The group to which the device belongs."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Comments",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Comments"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Additional comments or notes about the device."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_FirstConnection",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "First Connection"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The date and time of the first connection with the device. Uneditable - Autodetected."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_LastConnection",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Last Connection"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The date and time of the last connection with the device. Uneditable - Autodetected."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_LastIP",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Last IP"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The last known IP address of the device. Uneditable - Autodetected."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_StaticIP",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"override_value": {
|
||||
"override": true
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Static IP"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether the device has a static IP address."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_ScanCycle",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"override_value": {
|
||||
"override": true
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Scan Cycle"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The default value of the <code>Scan device</code> dropdown. Enable if newly discovered devices should be scanned."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_LogEvents",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"override_value": {
|
||||
"override": false
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Log Events"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether events related to the device shouldbe logged."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_AlertEvents",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"override_value": {
|
||||
"override": true
|
||||
},
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Alert Events"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether events related to the device should trigger alerts. The default value of the <code>Alert All Events</code> checkbox."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_AlertDeviceDown",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Alert Device Down"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether an alert should be triggered when the device goes down. The default value of the <code>Alert Down</code> checkbox."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_SkipRepeated",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Skip Repeated"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The default value of the <code>Skip repeated notifications for</code> dropdown. Enter number of <b>hours</b> for which repeated notifications should be ignored for. If you enter <code>0</code> then you get notified on all events."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_LastNotification",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"format": "date-time",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Last Notification"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The date and time of the last notification sent for the device. Uneditable - Autodetected."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_PresentLastScan",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 1,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Present Last Scan"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether the device should be marked as present after detected in a scan."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_NewDevice",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": true,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "New Device"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether the device is considered a new device. The default value of the <code>New Device</code> checkbox."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Location",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"maxLength": 250,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Location"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The location of the device."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Archived",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Archived"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Indicates whether the device is archived. The default value of the <code>Archived</code> checkbox."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Network_Node_MAC_ADDR",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Network Node MAC Address"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The MAC address of the network node."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Network_Node_port",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 0,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Network Node Port"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The port number of the network node. Uneditable."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Icon",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Device Icon"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "The icon associated with the device. Check the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md\" target=\"_blank\">documentation on icons</a> for more details."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"required": [
|
||||
"dev_MAC",
|
||||
"dev_Name",
|
||||
"dev_Owner",
|
||||
"dev_FirstConnection",
|
||||
"dev_LastConnection",
|
||||
"dev_LastIP",
|
||||
"dev_StaticIP",
|
||||
"dev_ScanCycle",
|
||||
"dev_LogEvents",
|
||||
"dev_AlertEvents",
|
||||
"dev_AlertDeviceDown",
|
||||
"dev_SkipRepeated",
|
||||
"dev_LastNotification",
|
||||
"dev_PresentLastScan",
|
||||
"dev_NewDevice",
|
||||
"dev_Location",
|
||||
"dev_Archived",
|
||||
"dev_Network_Node_MAC_ADDR",
|
||||
"dev_Network_Node_port",
|
||||
"dev_Icon"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
This plugin will not be loaded
|
||||
@@ -30,7 +30,7 @@
|
||||
{
|
||||
"name": "ips",
|
||||
"type": "sql",
|
||||
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC",
|
||||
"value": "SELECT devLastIP from DEVICES order by devMac",
|
||||
"timeoutMultiplier": true
|
||||
},
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
{
|
||||
"name": "ips",
|
||||
"type": "sql",
|
||||
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC",
|
||||
"value": "SELECT devLastIP from DEVICES order by devMac",
|
||||
"timeoutMultiplier": true
|
||||
}
|
||||
],
|
||||
@@ -79,7 +79,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "When the plugin should be executed. If enabled this will execute the scan until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Setting this to <code>on_new_device</code> or a daily <code>schedule</code> is recommended.<br/><br/> Depends on the <a onclick=\"toggleAllSettings()\" href=\"#SCAN_SUBNETS\"><code>SCAN_SUBNETS</code> setting</a>."
|
||||
"string": "When the plugin should be executed. If enabled this will execute the scan until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Setting this to <code>before_name_updates</code> is recommended.<br/><br/> Depends on the <a onclick=\"toggleAllSettings()\" href=\"#SCAN_SUBNETS\"><code>SCAN_SUBNETS</code> setting</a>."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -60,19 +60,19 @@ def main():
|
||||
# execute_name_lookup('192.168.1.121', timeout)
|
||||
|
||||
for device in unknown_devices:
|
||||
domain_name, dns_server = execute_name_lookup(device['dev_LastIP'], timeout)
|
||||
domain_name, dns_server = execute_name_lookup(device['devLastIP'], timeout)
|
||||
|
||||
if domain_name != '':
|
||||
plugin_objects.add_object(
|
||||
# "MAC", "IP", "Server", "Name"
|
||||
primaryId = device['dev_MAC'],
|
||||
secondaryId = device['dev_LastIP'],
|
||||
primaryId = device['devMac'],
|
||||
secondaryId = device['devLastIP'],
|
||||
watched1 = dns_server,
|
||||
watched2 = domain_name,
|
||||
watched3 = '',
|
||||
watched4 = '',
|
||||
extra = '',
|
||||
foreignKey = device['dev_MAC'])
|
||||
foreignKey = device['devMac'])
|
||||
|
||||
plugin_objects.write_result_file()
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_MAC",
|
||||
"function": "devMac",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -295,7 +295,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Name",
|
||||
"function": "devName",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -324,7 +324,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Owner",
|
||||
"function": "devOwner",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -338,7 +338,7 @@
|
||||
{
|
||||
"name": "value",
|
||||
"type": "sql",
|
||||
"value": "SELECT DISTINCT '' as id, '❌None' as name UNION SELECT dev_Owner as id, dev_Owner as name FROM (SELECT dev_Owner FROM Devices UNION SELECT 'House' ) AS all_devices ORDER BY id;"
|
||||
"value": "SELECT DISTINCT '' as id, '❌None' as name UNION SELECT devOwner as id, devOwner as name FROM (SELECT devOwner FROM Devices UNION SELECT 'House' ) AS all_devices ORDER BY id;"
|
||||
}
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
@@ -356,7 +356,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_DeviceType",
|
||||
"function": "devType",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -370,7 +370,7 @@
|
||||
{
|
||||
"name": "value",
|
||||
"type": "sql",
|
||||
"value": "SELECT DISTINCT 9 as ord, dev_DeviceType as id, dev_DeviceType as name FROM Devices WHERE dev_DeviceType NOT IN ('', 'Smartphone', 'Tablet', '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', 'Firewall', 'Hypervisor', 'Powerline', 'Switch', 'WLAN', 'PLC', 'Router', 'USB LAN Adapter', 'USB WIFI Adapter') UNION SELECT 0 as ord, '', '❌None' UNION SELECT 1 as ord, '-----', '-- 📱Handhelds --' UNION SELECT 1 as ord, 'Smartphone', 'Smartphone' UNION SELECT 1 as ord, 'Tablet', 'Tablet' UNION SELECT 2 as ord, '-----', '-- 💻Computers --' UNION SELECT 2 as ord, 'Laptop', 'Laptop' UNION SELECT 2 as ord, 'Mini PC', 'Mini PC' UNION SELECT 2 as ord, 'PC', 'PC' UNION SELECT 2 as ord, 'Printer', 'Printer' UNION SELECT 2 as ord, 'Server', 'Server' UNION SELECT 2 as ord, 'Singleboard Computer (SBC)', 'Singleboard Computer (SBC)' UNION SELECT 2 as ord, 'NAS', 'NAS' UNION SELECT 3 as ord, '-----', '-- 🏠Smart home --' UNION SELECT 3 as ord, 'Domotic', 'Domotic' UNION SELECT 3 as ord, 'IP Camera', 'IP Camera' UNION SELECT 3 as ord, 'Game Console', 'Game Console' UNION SELECT 3 as ord, 'SmartTV', 'SmartTV' UNION SELECT 3 as ord, 'TV Decoder', 'TV Decoder' UNION SELECT 3 as ord, 'Virtual Assistance', 'Virtual Assistance' UNION SELECT 4 as ord, '-----', '-- Wired --' UNION SELECT 4 as ord, 'Clock', 'Clock' UNION SELECT 4 as ord, 'House Appliance', 'House Appliance' UNION SELECT 4 as ord, 'Phone', 'Phone' UNION SELECT 4 as ord, 'Radio', 'Radio' UNION SELECT 5 as ord, '-----', '-- 📡Network nodes --' UNION SELECT 5 as ord, 'AP', 'AP' UNION SELECT 5 as ord, 'Gateway', 'Gateway' UNION SELECT 5 as ord, 'Firewall', 'Firewall' UNION SELECT 5 as ord, 'Hypervisor', 'Hypervisor' UNION SELECT 5 as ord, 'Powerline', 'Powerline' UNION SELECT 5 as ord, 'Switch', 'Switch' UNION SELECT 5 as ord, 'WLAN', 'WLAN' UNION SELECT 5 as ord, 'PLC', 'PLC' UNION SELECT 5 as ord, 'Router', 'Router' UNION SELECT 5 as ord, 'USB LAN Adapter', 'USB LAN Adapter' UNION SELECT 5 as ord, 'USB WIFI Adapter', 'USB WIFI Adapter' UNION SELECT 9 as ord, '-----', '-- ⚙Custom --' UNION SELECT 10 as ord, '-----', '-----' UNION SELECT 10 as ord, 'Other', 'Other' ORDER BY 1,2;"
|
||||
"value": "SELECT DISTINCT 9 as ord, devType as id, devType as name FROM Devices WHERE devType NOT IN ('', 'Smartphone', 'Tablet', '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', 'Firewall', 'Hypervisor', 'Powerline', 'Switch', 'WLAN', 'PLC', 'Router', 'USB LAN Adapter', 'USB WIFI Adapter') UNION SELECT 0 as ord, '', '❌None' UNION SELECT 1 as ord, '-----', '-- 📱Handhelds --' UNION SELECT 1 as ord, 'Smartphone', 'Smartphone' UNION SELECT 1 as ord, 'Tablet', 'Tablet' UNION SELECT 2 as ord, '-----', '-- 💻Computers --' UNION SELECT 2 as ord, 'Laptop', 'Laptop' UNION SELECT 2 as ord, 'Mini PC', 'Mini PC' UNION SELECT 2 as ord, 'PC', 'PC' UNION SELECT 2 as ord, 'Printer', 'Printer' UNION SELECT 2 as ord, 'Server', 'Server' UNION SELECT 2 as ord, 'Singleboard Computer (SBC)', 'Singleboard Computer (SBC)' UNION SELECT 2 as ord, 'NAS', 'NAS' UNION SELECT 3 as ord, '-----', '-- 🏠Smart home --' UNION SELECT 3 as ord, 'Domotic', 'Domotic' UNION SELECT 3 as ord, 'IP Camera', 'IP Camera' UNION SELECT 3 as ord, 'Game Console', 'Game Console' UNION SELECT 3 as ord, 'SmartTV', 'SmartTV' UNION SELECT 3 as ord, 'TV Decoder', 'TV Decoder' UNION SELECT 3 as ord, 'Virtual Assistance', 'Virtual Assistance' UNION SELECT 4 as ord, '-----', '-- Wired --' UNION SELECT 4 as ord, 'Clock', 'Clock' UNION SELECT 4 as ord, 'House Appliance', 'House Appliance' UNION SELECT 4 as ord, 'Phone', 'Phone' UNION SELECT 4 as ord, 'Radio', 'Radio' UNION SELECT 5 as ord, '-----', '-- 📡Network nodes --' UNION SELECT 5 as ord, 'AP', 'AP' UNION SELECT 5 as ord, 'Gateway', 'Gateway' UNION SELECT 5 as ord, 'Firewall', 'Firewall' UNION SELECT 5 as ord, 'Hypervisor', 'Hypervisor' UNION SELECT 5 as ord, 'Powerline', 'Powerline' UNION SELECT 5 as ord, 'Switch', 'Switch' UNION SELECT 5 as ord, 'WLAN', 'WLAN' UNION SELECT 5 as ord, 'PLC', 'PLC' UNION SELECT 5 as ord, 'Router', 'Router' UNION SELECT 5 as ord, 'USB LAN Adapter', 'USB LAN Adapter' UNION SELECT 5 as ord, 'USB WIFI Adapter', 'USB WIFI Adapter' UNION SELECT 9 as ord, '-----', '-- ⚙Custom --' UNION SELECT 10 as ord, '-----', '-----' UNION SELECT 10 as ord, 'Other', 'Other' ORDER BY 1,2;"
|
||||
},
|
||||
{
|
||||
"name": "uilang",
|
||||
@@ -393,7 +393,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Vendor",
|
||||
"function": "devVendor",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -422,7 +422,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Favorite",
|
||||
"function": "devFavorite",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
@@ -450,7 +450,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Group",
|
||||
"function": "devGroup",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -464,7 +464,7 @@
|
||||
{
|
||||
"name": "value",
|
||||
"type": "sql",
|
||||
"value": "SELECT DISTINCT '' as id, '❌None' as name UNION SELECT dev_Group as id, dev_Group as name FROM (SELECT dev_Group FROM Devices WHERE dev_Group <> '' UNION SELECT 'Personal' UNION SELECT 'Always on' UNION SELECT 'Friends' UNION SELECT 'Others' ) AS all_devices ORDER BY id;"
|
||||
"value": "SELECT DISTINCT '' as id, '❌None' as name UNION SELECT devGroup as id, devGroup as name FROM (SELECT devGroup FROM Devices WHERE devGroup <> '' UNION SELECT 'Personal' UNION SELECT 'Always on' UNION SELECT 'Friends' UNION SELECT 'Others' ) AS all_devices ORDER BY id;"
|
||||
}
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
@@ -482,7 +482,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Comments",
|
||||
"function": "devComments",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -506,7 +506,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_FirstConnection",
|
||||
"function": "devFirstConnection",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -535,7 +535,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_LastConnection",
|
||||
"function": "devLastConnection",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -564,7 +564,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_LastIP",
|
||||
"function": "devLastIP",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -593,7 +593,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_StaticIP",
|
||||
"function": "devStaticIP",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
@@ -621,7 +621,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_ScanCycle",
|
||||
"function": "devScan",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
@@ -649,7 +649,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_LogEvents",
|
||||
"function": "devLogEvents",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
@@ -677,7 +677,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_AlertEvents",
|
||||
"function": "devAlertEvents",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
@@ -705,7 +705,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_AlertDeviceDown",
|
||||
"function": "devAlertDown",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
@@ -733,7 +733,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_SkipRepeated",
|
||||
"function": "devSkipRepeated",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -764,7 +764,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_LastNotification",
|
||||
"function": "devLastNotification",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -793,7 +793,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_PresentLastScan",
|
||||
"function": "devPresentLastScan",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
@@ -821,7 +821,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_NewDevice",
|
||||
"function": "devIsNew",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
@@ -849,7 +849,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Location",
|
||||
"function": "devLocation",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -863,7 +863,7 @@
|
||||
{
|
||||
"name": "value",
|
||||
"type": "sql",
|
||||
"value": "SELECT DISTINCT '' AS id, '❌None' AS name UNION SELECT dev_Location AS id, dev_Location AS name FROM Devices WHERE dev_Location NOT IN ('', 'null') AND dev_Location IS NOT NULL UNION SELECT 'Bathroom' AS id, 'Bathroom' AS name UNION SELECT 'Bedroom', 'Bedroom' UNION SELECT 'Dining room', 'Dining room' UNION SELECT 'Hall', 'Hall' UNION SELECT 'Kitchen', 'Kitchen' UNION SELECT 'Laundry', 'Laundry' UNION SELECT 'Living room', 'Living room' UNION SELECT 'Study', 'Study' UNION SELECT 'Attic', 'Attic' UNION SELECT 'Basement', 'Basement' UNION SELECT 'Garage', 'Garage' UNION SELECT 'Back yard', 'Back yard' UNION SELECT 'Garden', 'Garden' UNION SELECT 'Terrace', 'Terrace' ORDER BY id;"
|
||||
"value": "SELECT DISTINCT '' AS id, '❌None' AS name UNION SELECT devLocation AS id, devLocation AS name FROM Devices WHERE devLocation NOT IN ('', 'null') AND devLocation IS NOT NULL UNION SELECT 'Bathroom' AS id, 'Bathroom' AS name UNION SELECT 'Bedroom', 'Bedroom' UNION SELECT 'Dining room', 'Dining room' UNION SELECT 'Hall', 'Hall' UNION SELECT 'Kitchen', 'Kitchen' UNION SELECT 'Laundry', 'Laundry' UNION SELECT 'Living room', 'Living room' UNION SELECT 'Study', 'Study' UNION SELECT 'Attic', 'Attic' UNION SELECT 'Basement', 'Basement' UNION SELECT 'Garage', 'Garage' UNION SELECT 'Back yard', 'Back yard' UNION SELECT 'Garden', 'Garden' UNION SELECT 'Terrace', 'Terrace' ORDER BY id;"
|
||||
}
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
@@ -881,7 +881,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Archived",
|
||||
"function": "devIsArchived",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
@@ -909,7 +909,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Network_Node_MAC_ADDR",
|
||||
"function": "devParentMAC",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -922,7 +922,7 @@
|
||||
{
|
||||
"name": "value",
|
||||
"type": "sql",
|
||||
"value": "SELECT '❌None' as name, '' as id UNION SELECT Dev_Name as name, dev_MAC as id FROM Devices WHERE EXISTS (SELECT 1 FROM Settings WHERE Code_Name = 'NETWORK_DEVICE_TYPES' AND LOWER(value) LIKE '%' || LOWER(dev_DeviceType) || '%' AND dev_DeviceType <> '')"
|
||||
"value": "SELECT '❌None' as name, '' as id UNION SELECT devName as name, devMac as id FROM Devices WHERE EXISTS (SELECT 1 FROM Settings WHERE Code_Name = 'NETWORK_DEVICE_TYPES' AND LOWER(value) LIKE '%' || LOWER(devType) || '%' AND devType <> '')"
|
||||
},
|
||||
{
|
||||
"name": "target_macs",
|
||||
@@ -945,7 +945,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Network_Node_port",
|
||||
"function": "devParentPort",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -973,7 +973,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "dev_Icon",
|
||||
"function": "devIcon",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
@@ -982,7 +982,7 @@
|
||||
"elementOptions": [
|
||||
{ "cssClasses": "input-group-addon iconPreview" },
|
||||
{ "getStringKey": "Gen_SelectToPreview" },
|
||||
{ "customId": "NEWDEV_dev_Icon_preview" }
|
||||
{ "customId": "NEWDEV_devIcon_preview" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
@@ -994,7 +994,7 @@
|
||||
{
|
||||
"onChange": "updateIconPreview(this)"
|
||||
},
|
||||
{ "customParams": "NEWDEV_dev_Icon,NEWDEV_dev_Icon_preview" }
|
||||
{ "customParams": "NEWDEV_devIcon,NEWDEV_devIcon_preview" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
@@ -1006,7 +1006,7 @@
|
||||
{
|
||||
"name": "value",
|
||||
"type": "sql",
|
||||
"value": "WITH RECURSIVE SettingsIcons AS (SELECT REPLACE(REPLACE(REPLACE(Value, '[', ''), ']', ''), '''', '') AS icon_list FROM Settings WHERE Code_Name = 'UI_ICONS'), SplitIcons AS (SELECT TRIM(SUBSTR(icon_list, 1, INSTR(icon_list || ',', ',') - 1)) AS icon, SUBSTR(icon_list, INSTR(icon_list || ',', ',') + 1) AS remaining_icons FROM SettingsIcons WHERE icon_list <> '' UNION ALL SELECT TRIM(SUBSTR(remaining_icons, 1, INSTR(remaining_icons || ',', ',') - 1)) AS icon, SUBSTR(remaining_icons, INSTR(remaining_icons || ',', ',') + 1) AS remaining_icons FROM SplitIcons WHERE remaining_icons <> '') SELECT DISTINCT * FROM (SELECT icon as name, icon as id FROM SplitIcons UNION SELECT '❌None' AS name, '' AS id UNION SELECT Dev_Icon AS name, Dev_Icon AS id FROM Devices WHERE Dev_Icon <> '') AS combined_results;"
|
||||
"value": "WITH RECURSIVE SettingsIcons AS (SELECT REPLACE(REPLACE(REPLACE(Value, '[', ''), ']', ''), '''', '') AS icon_list FROM Settings WHERE Code_Name = 'UI_ICONS'), SplitIcons AS (SELECT TRIM(SUBSTR(icon_list, 1, INSTR(icon_list || ',', ',') - 1)) AS icon, SUBSTR(icon_list, INSTR(icon_list || ',', ',') + 1) AS remaining_icons FROM SettingsIcons WHERE icon_list <> '' UNION ALL SELECT TRIM(SUBSTR(remaining_icons, 1, INSTR(remaining_icons || ',', ',') - 1)) AS icon, SUBSTR(remaining_icons, INSTR(remaining_icons || ',', ',') + 1) AS remaining_icons FROM SplitIcons WHERE remaining_icons <> '') SELECT DISTINCT * FROM (SELECT icon as name, icon as id FROM SplitIcons UNION SELECT '❌None' AS name, '' AS id UNION SELECT devIcon AS name, devIcon AS id FROM Devices WHERE devIcon <> '') AS combined_results;"
|
||||
}
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
@@ -1025,27 +1025,6 @@
|
||||
}
|
||||
],
|
||||
"required": [
|
||||
"dev_MAC",
|
||||
"dev_Name",
|
||||
"dev_Owner",
|
||||
"dev_FirstConnection",
|
||||
"dev_LastConnection",
|
||||
"dev_LastIP",
|
||||
"dev_StaticIP",
|
||||
"dev_ScanCycle",
|
||||
"dev_LogEvents",
|
||||
"dev_AlertEvents",
|
||||
"dev_AlertDeviceDown",
|
||||
"dev_SkipRepeated",
|
||||
"dev_LastNotification",
|
||||
"dev_PresentLastScan",
|
||||
"dev_NewDevice",
|
||||
"dev_Location",
|
||||
"dev_Archived",
|
||||
"dev_Network_Node_MAC_ADDR",
|
||||
"dev_Network_Node_port",
|
||||
"dev_Icon",
|
||||
"LESS_NAME_CLEANUP"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
|
||||
@@ -50,13 +50,13 @@
|
||||
{
|
||||
"name": "ips",
|
||||
"type": "sql",
|
||||
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC",
|
||||
"value": "SELECT devLastIP from DEVICES order by devMac",
|
||||
"timeoutMultiplier": true
|
||||
},
|
||||
{
|
||||
"name": "macs",
|
||||
"type": "sql",
|
||||
"value": "SELECT dev_MAC from DEVICES order by dev_MAC"
|
||||
"value": "SELECT devMac from DEVICES order by devMac"
|
||||
},
|
||||
{
|
||||
"name": "timeout",
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "You can specify a SQL where condition to filter out New Devices from notifications. For example <code>AND dev_LastIP NOT LIKE '192.168.3.%'</code> will always exclude New Device notifications for all devices with the IP starting with <code>192.168.3.%</code>."
|
||||
"string": "You can specify a SQL where condition to filter out New Devices from notifications. For example <code>AND devLastIP NOT LIKE '192.168.3.%'</code> will always exclude New Device notifications for all devices with the IP starting with <code>192.168.3.%</code>."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -149,7 +149,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "You can specify a SQL where condition to filter out Events from notifications. For example <code>AND dev_LastIP NOT LIKE '192.168.3.%'</code> will always exclude New Device notifications for all devices with the IP starting with <code>192.168.3.%</code>."
|
||||
"string": "You can specify a SQL where condition to filter out Events from notifications. For example <code>AND devLastIP NOT LIKE '192.168.3.%'</code> will always exclude New Device notifications for all devices with the IP starting with <code>192.168.3.%</code>."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
{
|
||||
"name": "ips",
|
||||
"type": "sql",
|
||||
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC",
|
||||
"value": "SELECT devLastIP from DEVICES order by devMac",
|
||||
"timeoutMultiplier": true
|
||||
}
|
||||
],
|
||||
@@ -79,7 +79,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "When the plugin should be executed. If enabled this will execute the scan until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Setting this to <code>on_new_device</code> or a daily <code>schedule</code> is recommended.<br/><br/> Depends on the <a onclick=\"toggleAllSettings()\" href=\"#SCAN_SUBNETS\"><code>SCAN_SUBNETS</code> setting</a>."
|
||||
"string": "When the plugin should be executed. If enabled this will execute the scan until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Setting this to <code>before_name_updates</code> is recommended.<br/><br/> Depends on the <a onclick=\"toggleAllSettings()\" href=\"#SCAN_SUBNETS\"><code>SCAN_SUBNETS</code> setting</a>."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -59,19 +59,19 @@ def main():
|
||||
mylog('verbose', [f'[{pluginName}] Unknown devices count: {len(unknown_devices)}'])
|
||||
|
||||
for device in unknown_devices:
|
||||
domain_name, dns_server = execute_nslookup(device['dev_LastIP'], timeout)
|
||||
domain_name, dns_server = execute_nslookup(device['devLastIP'], timeout)
|
||||
|
||||
if domain_name != '':
|
||||
plugin_objects.add_object(
|
||||
# "MAC", "IP", "Server", "Name"
|
||||
primaryId = device['dev_MAC'],
|
||||
secondaryId = device['dev_LastIP'],
|
||||
primaryId = device['devMac'],
|
||||
secondaryId = device['devLastIP'],
|
||||
watched1 = dns_server,
|
||||
watched2 = domain_name,
|
||||
watched3 = '',
|
||||
watched4 = '',
|
||||
extra = '',
|
||||
foreignKey = device['dev_MAC'])
|
||||
foreignKey = device['devMac'])
|
||||
|
||||
plugin_objects.write_result_file()
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ def main():
|
||||
# log result
|
||||
plugin_objects.write_result_file()
|
||||
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}] TEST name from MAC: {device_handler.getValueWithMac('dev_Name','00:e2:59:00:a0:8e')}'])
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}] TEST name from MAC: {device_handler.getValueWithMac('devName','00:e2:59:00:a0:8e')}'])
|
||||
#mylog(OMDLOGLEVEL, [f'[{pluginName}] TEST MAC from IP: {get_mac_from_IP('192.168.0.1')} also {ietf2ieee_mac_formater(get_mac_from_IP('192.168.0.1'))}'])
|
||||
end_time = time.time()
|
||||
mylog('verbose', [f'[{pluginName}] execution completed in {end_time - start_time:.2f} seconds'])
|
||||
@@ -423,7 +423,7 @@ def get_device_data(omada_clients_output,switches_and_aps,device_handler):
|
||||
odevice_data_reordered = [ MAC, IP, NAME, SWITCH_AP, PORT_SSID, TYPE]
|
||||
odevice_data_reordered[MAC]=odevice_data[cMAC]
|
||||
odevice_data_reordered[IP]=odevice_data[cIP]
|
||||
real_naxname = device_handler.getValueWithMac('dev_Name',ieee2ietf_mac_formater(odevice_data[cMAC]))
|
||||
real_naxname = device_handler.getValueWithMac('devName',ieee2ietf_mac_formater(odevice_data[cMAC]))
|
||||
|
||||
#
|
||||
# if the name stored in Nax for a device is empty or the MAC addres or has some parenthhesis or is the same as in omada
|
||||
|
||||
@@ -31,9 +31,10 @@ The plugin operates in three different modes based on the configuration settings
|
||||
|
||||
#### Node (Source) Settings `[n]`
|
||||
|
||||
- **API Token** `[n,h]`: `API_TOKEN` (has to be same across all nodes)
|
||||
|
||||
- **When to Run** `[n,h]`: `SYNC_RUN`
|
||||
- **Schedule** `[n,h]`: `SYNC_RUN_SCHD`
|
||||
- **API Token** `[n,h]`: `SYNC_api_token`
|
||||
- **Encryption Key** `[n,h]`: `SYNC_encryption_key`
|
||||
- **Node Name** `[n]`: `SYNC_node_name`
|
||||
- **Hub URL** `[n]`: `SYNC_hub_url`
|
||||
@@ -42,9 +43,10 @@ The plugin operates in three different modes based on the configuration settings
|
||||
|
||||
#### Hub (Target) Settings `[h]`
|
||||
|
||||
- **API Token** `[n,h]`: `API_TOKEN` (has to be same across all nodes)
|
||||
|
||||
- **When to Run** `[n,h]`: `SYNC_RUN`
|
||||
- **Schedule** `[n,h]`: `SYNC_RUN_SCHD`
|
||||
- **API Token** `[n,h]`: `SYNC_api_token`
|
||||
- **Encryption Key** `[n,h]`: `SYNC_encryption_key`
|
||||
- **Nodes to Pull From** `[h]`: `SYNC_nodes`
|
||||
|
||||
|
||||
@@ -110,46 +110,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "api_token",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [{ "cssClasses": "col-xs-12" }],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "getStringKey": "Gen_Generate" },
|
||||
{ "customParams": "SYNC_api_token" },
|
||||
{ "onClick": "generateApiToken(this, 20)" },
|
||||
{ "cssClasses": "col-xs-12" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"maxLength": 50,
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "API token [n,h]"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "API token to secure communication, you can generate one or enter any value. It's sent in the request header. The API token needs to be the same on the hub and on the nodes."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "encryption_key",
|
||||
"type": {
|
||||
|
||||
@@ -11,7 +11,7 @@ function checkAuthorization($method) {
|
||||
// Retrieve the authorization header
|
||||
$headers = apache_request_headers();
|
||||
$auth_header = $headers['Authorization'] ?? '';
|
||||
$expected_token = 'Bearer ' . getSettingValue('SYNC_api_token');
|
||||
$expected_token = 'Bearer ' . getSettingValue('API_TOKEN');
|
||||
|
||||
// Verify the authorization token
|
||||
if ($auth_header !== $expected_token) {
|
||||
|
||||
@@ -42,7 +42,7 @@ def main():
|
||||
|
||||
# Retrieve configuration settings
|
||||
plugins_to_sync = get_setting_value('SYNC_plugins')
|
||||
api_token = get_setting_value('SYNC_api_token')
|
||||
api_token = get_setting_value('API_TOKEN')
|
||||
encryption_key = get_setting_value('SYNC_encryption_key')
|
||||
hub_url = get_setting_value('SYNC_hub_url')
|
||||
node_name = get_setting_value('SYNC_node_name')
|
||||
@@ -165,7 +165,7 @@ def main():
|
||||
conn = sqlite3.connect(fullDbPath)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Collect all unique dev_MAC values from the JSON files
|
||||
# Collect all unique devMac values from the JSON files
|
||||
unique_mac_addresses = set()
|
||||
device_data = []
|
||||
|
||||
@@ -188,9 +188,9 @@ def main():
|
||||
with open(file_path, 'r') as f:
|
||||
data = json.load(f)
|
||||
for device in data['data']:
|
||||
if device['dev_MAC'] not in unique_mac_addresses:
|
||||
device['dev_SyncHubNodeName'] = tmp_SyncHubNodeName
|
||||
unique_mac_addresses.add(device['dev_MAC'])
|
||||
if device['devMac'] not in unique_mac_addresses:
|
||||
device['devSyncHubNode'] = tmp_SyncHubNodeName
|
||||
unique_mac_addresses.add(device['devMac'])
|
||||
device_data.append(device)
|
||||
|
||||
# Rename the file to "processed_" + current name
|
||||
@@ -204,27 +204,27 @@ def main():
|
||||
os.rename(file_path, new_file_path)
|
||||
|
||||
if len(device_data) > 0:
|
||||
# Retrieve existing dev_MAC values from the Devices table
|
||||
# Retrieve existing devMac values from the Devices table
|
||||
placeholders = ', '.join('?' for _ in unique_mac_addresses)
|
||||
cursor.execute(f'SELECT dev_MAC FROM Devices WHERE dev_MAC IN ({placeholders})', tuple(unique_mac_addresses))
|
||||
cursor.execute(f'SELECT devMac FROM Devices WHERE devMac IN ({placeholders})', tuple(unique_mac_addresses))
|
||||
existing_mac_addresses = set(row[0] for row in cursor.fetchall())
|
||||
|
||||
|
||||
# insert devices into the lats_result.log to manage state
|
||||
for device in device_data:
|
||||
if device['dev_PresentLastScan'] == 1:
|
||||
if device['devPresentLastScan'] == 1:
|
||||
plugin_objects.add_object(
|
||||
primaryId = device['dev_MAC'],
|
||||
secondaryId = device['dev_LastIP'],
|
||||
watched1 = device['dev_Name'],
|
||||
watched2 = device['dev_Vendor'],
|
||||
watched3 = device['dev_SyncHubNodeName'],
|
||||
watched4 = device['dev_GUID'],
|
||||
primaryId = device['devMac'],
|
||||
secondaryId = device['devLastIP'],
|
||||
watched1 = device['devName'],
|
||||
watched2 = device['devVendor'],
|
||||
watched3 = device['devSyncHubNode'],
|
||||
watched4 = device['devGUID'],
|
||||
extra = '',
|
||||
foreignKey = device['dev_GUID'])
|
||||
foreignKey = device['devGUID'])
|
||||
|
||||
# Filter out existing devices
|
||||
new_devices = [device for device in device_data if device['dev_MAC'] not in existing_mac_addresses]
|
||||
new_devices = [device for device in device_data if device['devMac'] not in existing_mac_addresses]
|
||||
|
||||
# Remove 'rowid' key if it exists
|
||||
for device in new_devices:
|
||||
|
||||
@@ -373,7 +373,9 @@
|
||||
"Device_TableHead_SyncHubNodeName",
|
||||
"Device_TableHead_NetworkSite",
|
||||
"Device_TableHead_SSID",
|
||||
"Device_TableHead_SourcePlugin"
|
||||
"Device_TableHead_SourcePlugin",
|
||||
"Device_TableHead_PresentLastScan",
|
||||
"Device_TableHead_AlertDown"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -385,7 +387,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Columns and their order that are shown on the Devices page. Drag and drop the order of columns, click <code>x</code> to remove columns. You can also click into the field to selectivelly add fields."
|
||||
"string": "Columns and their order that are shown on the Devices page. Drag and drop the order of columns, click <code>x</code> to remove columns. You can also click into the field to selectivelly add fields. The <code>Name</code> and <code>Status</code> fields are required."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -85,14 +85,15 @@ def update_vendors (dbPath, plugin_objects):
|
||||
|
||||
# Get devices without a vendor
|
||||
sql.execute ("""SELECT
|
||||
dev_MAC,
|
||||
dev_LastIP,
|
||||
dev_Name,
|
||||
dev_Vendor
|
||||
devMac,
|
||||
devLastIP,
|
||||
devName,
|
||||
devVendor
|
||||
FROM Devices
|
||||
WHERE dev_Vendor = '(unknown)'
|
||||
OR dev_Vendor = ''
|
||||
OR dev_Vendor IS NULL
|
||||
WHERE devVendor = '(unknown)'
|
||||
OR devVendor = '(Unknown)'
|
||||
OR devVendor = ''
|
||||
OR devVendor IS NULL
|
||||
""")
|
||||
devices = sql.fetchall()
|
||||
conn.commit()
|
||||
|
||||
@@ -40,17 +40,12 @@
|
||||
{
|
||||
"name": "macs",
|
||||
"type": "sql",
|
||||
"value": "SELECT dev_MAC from DEVICES"
|
||||
"value": "SELECT devMac from DEVICES"
|
||||
},
|
||||
{
|
||||
"name": "urls",
|
||||
"type": "setting",
|
||||
"value": "WEBMON_urls_to_check"
|
||||
},
|
||||
{
|
||||
"name": "internet_ip",
|
||||
"type": "setting",
|
||||
"value": "WEBMON_SQL_internet_ip"
|
||||
}
|
||||
],
|
||||
"database_column_definitions": [
|
||||
@@ -677,42 +672,6 @@
|
||||
"string": "Servicios para ver. Ingrese la URL completa, por ejemplo, <code>https://google.com</code>. Los valores de esta configuración se usarán para reemplazar el comodín <code>{urls}</code> en la configuración < code>WEBMON_CMD</code>."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "SQL_internet_ip",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "SELECT dev_LastIP FROM Devices WHERE dev_MAC = 'Internet'",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Helper variable"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Variable de ayuda"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Unused setting - for demonstration only. Getting the IP address of the Router / Internet."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Configuración no utilizada: solo para demostración. Obtener la dirección IP del enrutador / Internet."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -64,9 +64,9 @@
|
||||
},
|
||||
"down_reconnected": [
|
||||
{
|
||||
"dev_Name": "Phone - Pixel",
|
||||
"devName": "Phone - Pixel",
|
||||
"eve_MAC": "74:ac:74:ac:74:ac",
|
||||
"dev_Vendor": "Google",
|
||||
"devVendor": "Google",
|
||||
"eve_IP": "192.168.1.167",
|
||||
"DownTime": "2024-05-26 09:06:56+10:00",
|
||||
"ConnectedTime": "2024-05-26 09:13:24+10:00"
|
||||
@@ -75,9 +75,9 @@
|
||||
"down_reconnected_meta": {
|
||||
"title": "🔁 Reconnected down devices",
|
||||
"columnNames": [
|
||||
"dev_Name",
|
||||
"devName",
|
||||
"eve_MAC",
|
||||
"dev_Vendor",
|
||||
"devVendor",
|
||||
"eve_IP",
|
||||
"DownTime",
|
||||
"ConnectedTime"
|
||||
|
||||
@@ -176,6 +176,8 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
// Get plugin and settings data from API endpoints
|
||||
function getData(){
|
||||
|
||||
console.log("in getData");
|
||||
|
||||
$.get('api/table_settings.json?nocache=' + Date.now(), function(res) {
|
||||
|
||||
settingsData = res["data"];
|
||||
@@ -464,10 +466,10 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
|
||||
// INPUT
|
||||
|
||||
// console.log(codeName);
|
||||
|
||||
// Parse the setType JSON string into an object
|
||||
let inputHtml = '';
|
||||
|
||||
console.log(codeName);
|
||||
console.log(setType);
|
||||
|
||||
const setTypeObject = JSON.parse(setType.replace(/'/g, '"'));
|
||||
@@ -819,8 +821,6 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@@ -829,41 +829,46 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
|
||||
function handleLoadingDialog()
|
||||
{
|
||||
// Check if app config is read only
|
||||
const canReadAndWriteConfig = <?php echo (is_readable($confPath) && is_writable($confPath)) ? 'true' : 'false'; ?>;
|
||||
|
||||
// check if config file has been updated
|
||||
$.get('api/app_state.json?nocache=' + Date.now(), function(appState) {
|
||||
if(!canReadAndWriteConfig)
|
||||
{
|
||||
showMessage (getString("settings_readonly"), 10000, "modal_red");
|
||||
console.log(`app.conf seems to be read only (canRWConfig: ${canReadAndWriteConfig}`);
|
||||
} else
|
||||
{
|
||||
// check if config file has been updated
|
||||
$.get('api/app_state.json?nocache=' + Date.now(), function(appState) {
|
||||
|
||||
fileModificationTime = <?php echo filemtime($confPath)*1000;?>;
|
||||
|
||||
fileModificationTime = <?php echo filemtime($confPath)*1000;?>;
|
||||
// console.log(appState["settingsImported"]*1000)
|
||||
importedMiliseconds = parseInt((appState["settingsImported"]*1000));
|
||||
humanReadable = (new Date(importedMiliseconds)).toLocaleString("en-UK", { timeZone: "<?php echo $timeZone?>" });
|
||||
|
||||
// console.log(appState["settingsImported"]*1000)
|
||||
importedMiliseconds = parseInt((appState["settingsImported"]*1000));
|
||||
// check if displayed settings are outdated
|
||||
if(appState["showSpinner"] || fileModificationTime > importedMiliseconds)
|
||||
{
|
||||
showSpinner("settings_old")
|
||||
|
||||
humanReadable = (new Date(importedMiliseconds)).toLocaleString("en-UK", { timeZone: "<?php echo $timeZone?>" });
|
||||
setTimeout("handleLoadingDialog()", 1000);
|
||||
|
||||
// console.log(humanReadable.replaceAll('"', ''))
|
||||
} else
|
||||
{
|
||||
checkInitialization();
|
||||
}
|
||||
|
||||
// check if displayed settings are outdated
|
||||
|
||||
if(appState["showSpinner"] || fileModificationTime > importedMiliseconds)
|
||||
{
|
||||
|
||||
showSpinner("settings_old")
|
||||
document.getElementById('lastImportedTime').innerHTML = humanReadable;
|
||||
})
|
||||
|
||||
setTimeout("handleLoadingDialog()", 1000);
|
||||
|
||||
} else
|
||||
{
|
||||
checkInitialization();
|
||||
}
|
||||
|
||||
|
||||
document.getElementById('lastImportedTime').innerHTML = humanReadable;
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function checkInitialization() {
|
||||
|
||||
if (isAppInitialized()) {
|
||||
// App is initialized, hide spinner and proceed with initialization
|
||||
console.log("App initialized, proceeding...");
|
||||
@@ -880,7 +885,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
// Check again after a delay
|
||||
setTimeout(checkInitialization, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
showSpinner()
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
# Schedule cron jobs
|
||||
* * * * * /app/back/cron_script.sh
|
||||
* * * * * echo "$(date +'%Y-%m-%d %H:%M:%S') - Cron job ran" >> /app/front/log/cron_timestamp.log
|
||||
#* * * * * echo "$(date +'%Y-%m-%d %H:%M:%S') - Cron job ran" >> /app/front/log/cron_timestamp.log
|
||||
|
||||
@@ -30,5 +30,5 @@ source myenv/bin/activate
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3 10
|
||||
|
||||
# install packages thru pip3
|
||||
pip3 install netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros
|
||||
pip3 install graphene flask netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import sys
|
||||
import time
|
||||
import datetime
|
||||
import multiprocessing
|
||||
import subprocess
|
||||
|
||||
# Register NetAlertX modules
|
||||
import conf
|
||||
@@ -34,7 +35,6 @@ from notification import Notification_obj
|
||||
from plugin import run_plugin_scripts, check_and_run_user_event
|
||||
from device import update_devices_names
|
||||
|
||||
|
||||
#===============================================================================
|
||||
#===============================================================================
|
||||
# MAIN
|
||||
@@ -66,6 +66,9 @@ def main ():
|
||||
# check file permissions and fix if required
|
||||
filePermissions()
|
||||
|
||||
# Header + init app state
|
||||
updateState("Initializing", None, None, None, 0)
|
||||
|
||||
# Open DB once and keep open
|
||||
# Opening / closing DB frequently actually casues more issues
|
||||
db = DB() # instance of class DB
|
||||
@@ -81,8 +84,7 @@ def main ():
|
||||
|
||||
mylog('debug', '[MAIN] Starting loop')
|
||||
|
||||
# Header + init app state
|
||||
updateState("Initializing")
|
||||
|
||||
|
||||
all_plugins = None
|
||||
|
||||
@@ -106,7 +108,7 @@ def main ():
|
||||
|
||||
# Update API endpoints
|
||||
update_api(db, all_plugins)
|
||||
|
||||
|
||||
# proceed if 1 minute passed
|
||||
if conf.last_scan_run + datetime.timedelta(minutes=1) < conf.loop_start_time :
|
||||
|
||||
@@ -183,12 +185,12 @@ def main ():
|
||||
db.commitDB()
|
||||
|
||||
# Footer
|
||||
updateState("Process: Wait")
|
||||
|
||||
mylog('verbose', ['[MAIN] Process: Wait'])
|
||||
else:
|
||||
# do something
|
||||
# mylog('verbose', ['[MAIN] Waiting to start next loop'])
|
||||
dummyVariable = 1
|
||||
updateState("Process: Wait")
|
||||
|
||||
|
||||
#loop
|
||||
|
||||
@@ -3,9 +3,12 @@ import json
|
||||
|
||||
# Register NetAlertX modules
|
||||
import conf
|
||||
from const import (apiPath, sql_appevents, sql_devices_all, sql_events_pending_alert, sql_settings, sql_plugins_events, sql_plugins_history, sql_plugins_objects,sql_language_strings, sql_notifications_all, sql_online_history)
|
||||
from const import (apiPath, sql_appevents, sql_devices_all, sql_events_pending_alert, sql_settings, sql_plugins_events, sql_plugins_history, sql_plugins_objects,sql_language_strings, sql_notifications_all, sql_online_history, sql_devices_tiles)
|
||||
from logger import mylog
|
||||
from helper import write_file
|
||||
from helper import write_file, get_setting_value, updateState
|
||||
|
||||
# Import the start_server function
|
||||
from graphql_server.graphql_server_start import start_server
|
||||
|
||||
apiEndpoints = []
|
||||
|
||||
@@ -14,8 +17,10 @@ apiEndpoints = []
|
||||
#===============================================================================
|
||||
def update_api(db, all_plugins, isNotification = False, updateOnlyDataSources = []):
|
||||
mylog('debug', ['[API] Update API starting'])
|
||||
# return
|
||||
|
||||
# update app_state.json and retrieve app_state to chjeck if GraphQL server is running
|
||||
app_state = updateState("Update: API", None, None, None, None)
|
||||
|
||||
folder = apiPath
|
||||
|
||||
# Save plugins
|
||||
@@ -33,6 +38,7 @@ def update_api(db, all_plugins, isNotification = False, updateOnlyDataSources =
|
||||
["plugins_language_strings", sql_language_strings],
|
||||
["notifications", sql_notifications_all],
|
||||
["online_history", sql_online_history],
|
||||
["devices_tiles", sql_devices_tiles],
|
||||
["custom_endpoint", conf.API_CUSTOM_SQL],
|
||||
]
|
||||
|
||||
@@ -42,6 +48,22 @@ def update_api(db, all_plugins, isNotification = False, updateOnlyDataSources =
|
||||
if updateOnlyDataSources == [] or dsSQL[0] in updateOnlyDataSources:
|
||||
|
||||
api_endpoint_class(db, dsSQL[1], folder + 'table_' + dsSQL[0] + '.json')
|
||||
|
||||
# Start the GraphQL server
|
||||
graphql_port_value = get_setting_value("GRAPHQL_PORT")
|
||||
api_token_value = get_setting_value("API_TOKEN")
|
||||
|
||||
# start GraphQL server if not yet running
|
||||
if app_state.graphQLServerStarted == 0:
|
||||
# Validate if settings are available
|
||||
if graphql_port_value is not None and len(api_token_value) > 1:
|
||||
try:
|
||||
graphql_port_value = int(graphql_port_value) # Ensure port is an integer
|
||||
start_server(graphql_port_value, app_state) # Start the server
|
||||
except ValueError:
|
||||
mylog('none', [f"[API] Invalid GRAPHQL_PORT value, must be an integer: {graphql_port_value}"])
|
||||
else:
|
||||
mylog('none', [f"[API] GRAPHQL_PORT or API_TOKEN is not set, will try later."])
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@@ -82,13 +82,13 @@ class AppEvent_obj:
|
||||
{sql_generateGuid},
|
||||
DATETIME('now'),
|
||||
'Devices',
|
||||
NEW.dev_MAC,
|
||||
NEW.dev_LastIP,
|
||||
CASE WHEN NEW.dev_PresentLastScan = 1 THEN 'online' ELSE 'offline' END,
|
||||
'dev_PresentLastScan',
|
||||
NEW.dev_NewDevice,
|
||||
NEW.dev_Archived,
|
||||
NEW.dev_MAC,
|
||||
NEW.devMac,
|
||||
NEW.devLastIP,
|
||||
CASE WHEN NEW.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END,
|
||||
'devPresentLastScan',
|
||||
NEW.devIsNew,
|
||||
NEW.devIsArchived,
|
||||
NEW.devMac,
|
||||
'create'
|
||||
);
|
||||
END;
|
||||
@@ -112,13 +112,13 @@ class AppEvent_obj:
|
||||
{sql_generateGuid},
|
||||
DATETIME('now'),
|
||||
'Devices',
|
||||
NEW.dev_MAC,
|
||||
NEW.dev_LastIP,
|
||||
CASE WHEN NEW.dev_PresentLastScan = 1 THEN 'online' ELSE 'offline' END,
|
||||
'dev_PresentLastScan',
|
||||
NEW.dev_NewDevice,
|
||||
NEW.dev_Archived,
|
||||
NEW.dev_MAC,
|
||||
NEW.devMac,
|
||||
NEW.devLastIP,
|
||||
CASE WHEN NEW.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END,
|
||||
'devPresentLastScan',
|
||||
NEW.devIsNew,
|
||||
NEW.devIsArchived,
|
||||
NEW.devMac,
|
||||
'update'
|
||||
);
|
||||
END;
|
||||
@@ -136,13 +136,13 @@ class AppEvent_obj:
|
||||
{sql_generateGuid},
|
||||
DATETIME('now'),
|
||||
'Devices',
|
||||
OLD.dev_MAC,
|
||||
OLD.dev_LastIP,
|
||||
CASE WHEN OLD.dev_PresentLastScan = 1 THEN 'online' ELSE 'offline' END,
|
||||
'dev_PresentLastScan',
|
||||
OLD.dev_NewDevice,
|
||||
OLD.dev_Archived,
|
||||
OLD.dev_MAC,
|
||||
OLD.devMac,
|
||||
OLD.devLastIP,
|
||||
CASE WHEN OLD.devPresentLastScan = 1 THEN 'online' ELSE 'offline' END,
|
||||
'devPresentLastScan',
|
||||
OLD.devIsNew,
|
||||
OLD.devIsArchived,
|
||||
OLD.devMac,
|
||||
'delete'
|
||||
);
|
||||
END;
|
||||
|
||||
@@ -43,4 +43,4 @@ REPORT_DASHBOARD_URL = 'http://netalertx/'
|
||||
# -------------------------------------------
|
||||
|
||||
# API
|
||||
API_CUSTOM_SQL = 'SELECT * FROM Devices WHERE dev_PresentLastScan = 0'
|
||||
API_CUSTOM_SQL = 'SELECT * FROM Devices WHERE devPresentLastScan = 0'
|
||||
|
||||
@@ -27,11 +27,86 @@ vendorsPathNewest = '/usr/share/arp-scan/ieee-oui_all_filtered.txt'
|
||||
#===============================================================================
|
||||
# SQL queries
|
||||
#===============================================================================
|
||||
sql_devices_all = """select rowid, * from Devices"""
|
||||
sql_devices_all = """
|
||||
SELECT
|
||||
rowid,
|
||||
IFNULL(devMac, '') AS devMac,
|
||||
IFNULL(devName, '') AS devName,
|
||||
IFNULL(devOwner, '') AS devOwner,
|
||||
IFNULL(devType, '') AS devType,
|
||||
IFNULL(devVendor, '') AS devVendor,
|
||||
IFNULL(devFavorite, '') AS devFavorite,
|
||||
IFNULL(devGroup, '') AS devGroup,
|
||||
IFNULL(devComments, '') AS devComments,
|
||||
IFNULL(devFirstConnection, '') AS devFirstConnection,
|
||||
IFNULL(devLastConnection, '') AS devLastConnection,
|
||||
IFNULL(devLastIP, '') AS devLastIP,
|
||||
IFNULL(devStaticIP, '') AS devStaticIP,
|
||||
IFNULL(devScan, '') AS devScan,
|
||||
IFNULL(devLogEvents, '') AS devLogEvents,
|
||||
IFNULL(devAlertEvents, '') AS devAlertEvents,
|
||||
IFNULL(devAlertDown, '') AS devAlertDown,
|
||||
IFNULL(devSkipRepeated, '') AS devSkipRepeated,
|
||||
IFNULL(devLastNotification, '') AS devLastNotification,
|
||||
IFNULL(devPresentLastScan, '') AS devPresentLastScan,
|
||||
IFNULL(devIsNew, '') AS devIsNew,
|
||||
IFNULL(devLocation, '') AS devLocation,
|
||||
IFNULL(devIsArchived, '') AS devIsArchived,
|
||||
IFNULL(devParentMAC, '') AS devParentMAC,
|
||||
IFNULL(devParentPort, '') AS devParentPort,
|
||||
IFNULL(devIcon, '') AS devIcon,
|
||||
IFNULL(devGUID, '') AS devGUID,
|
||||
IFNULL(devSite, '') AS devSite,
|
||||
IFNULL(devSSID, '') AS devSSID,
|
||||
IFNULL(devSyncHubNode, '') AS devSyncHubNode,
|
||||
IFNULL(devSourcePlugin, '') AS devSourcePlugin,
|
||||
CASE
|
||||
WHEN devIsNew = 1 THEN 'New'
|
||||
WHEN devPresentLastScan = 1 THEN 'On-line'
|
||||
WHEN devPresentLastScan = 0 AND devAlertDown != 0 THEN 'Down'
|
||||
WHEN devIsArchived = 1 THEN 'Archived'
|
||||
WHEN devPresentLastScan = 0 THEN 'Off-line'
|
||||
ELSE 'Unknown status'
|
||||
END AS devStatus
|
||||
FROM Devices
|
||||
"""
|
||||
|
||||
sql_appevents = """select * from AppEvents"""
|
||||
# The below query calculates counts of devices in various categories:
|
||||
# (connected/online, offline, down, new, archived),
|
||||
# as well as a combined count for devices that match any status listed in the UI_MY_DEVICES setting
|
||||
sql_devices_tiles = """
|
||||
WITH Statuses AS (
|
||||
SELECT Value
|
||||
FROM Settings
|
||||
WHERE Code_Name = 'UI_MY_DEVICES'
|
||||
),
|
||||
MyDevicesFilter AS (
|
||||
SELECT
|
||||
-- Build a dynamic filter for devices matching any status in UI_MY_DEVICES
|
||||
devPresentLastScan, devAlertDown, devIsNew, devIsArchived
|
||||
FROM Devices
|
||||
WHERE
|
||||
(instr((SELECT Value FROM Statuses), 'online') > 0 AND devPresentLastScan = 1) OR
|
||||
(instr((SELECT Value FROM Statuses), 'offline') > 0 AND devPresentLastScan = 0) OR
|
||||
(instr((SELECT Value FROM Statuses), 'down') > 0 AND devPresentLastScan = 0 AND devAlertDown = 1) OR
|
||||
(instr((SELECT Value FROM Statuses), 'new') > 0 AND devIsNew = 1) OR
|
||||
(instr((SELECT Value FROM Statuses), 'archived') > 0 AND devIsArchived = 1)
|
||||
)
|
||||
SELECT
|
||||
-- Counts for each individual status
|
||||
(SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 1) AS connected,
|
||||
(SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 0) AS offline,
|
||||
(SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 0 AND devAlertDown = 1) AS down,
|
||||
(SELECT COUNT(*) FROM Devices WHERE devIsNew = 1) AS new,
|
||||
(SELECT COUNT(*) FROM Devices WHERE devIsArchived = 1) AS archived,
|
||||
-- My Devices count
|
||||
(SELECT COUNT(*) FROM MyDevicesFilter) AS my_devices
|
||||
FROM Statuses;
|
||||
"""
|
||||
sql_devices_stats = """SELECT Online_Devices as online, Down_Devices as down, All_Devices as 'all', Archived_Devices as archived,
|
||||
(select count(*) from Devices a where dev_NewDevice = 1 ) as new,
|
||||
(select count(*) from Devices a where dev_Name = '(unknown)' or dev_Name = '(name not found)' ) as unknown
|
||||
(select count(*) from Devices a where devIsNew = 1 ) as new,
|
||||
(select count(*) from Devices a where devName = '(unknown)' or devName = '(name not found)' ) as unknown
|
||||
from Online_History order by Scan_Date desc limit 1"""
|
||||
sql_events_pending_alert = "SELECT * FROM Events where eve_PendingAlertEmail is not 0"
|
||||
sql_settings = "SELECT * FROM Settings"
|
||||
@@ -42,14 +117,14 @@ sql_online_history = "SELECT * FROM Online_History"
|
||||
sql_plugins_events = "SELECT * FROM Plugins_Events"
|
||||
sql_plugins_history = "SELECT * FROM Plugins_History ORDER BY DateTimeChanged DESC"
|
||||
sql_new_devices = """SELECT * FROM (
|
||||
SELECT eve_IP as dev_LastIP, eve_MAC as dev_MAC
|
||||
SELECT eve_IP as devLastIP, eve_MAC as devMac
|
||||
FROM Events_Devices
|
||||
WHERE eve_PendingAlertEmail = 1
|
||||
AND eve_EventType = 'New Device'
|
||||
ORDER BY eve_DateTime ) t1
|
||||
LEFT JOIN
|
||||
( SELECT dev_Name, dev_MAC as dev_MAC_t2 FROM Devices) t2
|
||||
ON t1.dev_MAC = t2.dev_MAC_t2"""
|
||||
( SELECT devName, devMac as devMac_t2 FROM Devices) t2
|
||||
ON t1.devMac = t2.devMac_t2"""
|
||||
|
||||
|
||||
sql_generateGuid = '''
|
||||
|
||||
@@ -28,7 +28,7 @@ class DB():
|
||||
mylog('debug','openDB: database already open')
|
||||
return
|
||||
|
||||
mylog('none', '[Database] Opening DB' )
|
||||
mylog('verbose', '[Database] Opening DB' )
|
||||
# Open DB and Cursor
|
||||
try:
|
||||
self.sql_connection = sqlite3.connect (fullDbPath, isolation_level=None)
|
||||
@@ -37,7 +37,7 @@ class DB():
|
||||
self.sql_connection.row_factory = sqlite3.Row
|
||||
self.sql = self.sql_connection.cursor()
|
||||
except sqlite3.Error as e:
|
||||
mylog('none',[ '[Database] - Open DB Error: ', e])
|
||||
mylog('verbose',[ '[Database] - Open DB Error: ', e])
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -81,149 +81,404 @@ class DB():
|
||||
"""
|
||||
Check the current tables in the DB and upgrade them if neccessary
|
||||
"""
|
||||
|
||||
# indicates, if Online_History table is available
|
||||
onlineHistoryAvailable = self.sql.execute("""
|
||||
SELECT name FROM sqlite_master WHERE type='table'
|
||||
AND name='Online_History';
|
||||
""").fetchall() != []
|
||||
|
||||
# Check if it is incompatible (Check if table has all required columns)
|
||||
isIncompatible = False
|
||||
|
||||
if onlineHistoryAvailable :
|
||||
isIncompatible = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Online_History') WHERE name='Archived_Devices'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
# Drop table if available, but incompatible
|
||||
if onlineHistoryAvailable and isIncompatible:
|
||||
mylog('none','[upgradeDB] Table is incompatible, Dropping the Online_History table')
|
||||
self.sql.execute("DROP TABLE Online_History;")
|
||||
onlineHistoryAvailable = False
|
||||
|
||||
if onlineHistoryAvailable == False :
|
||||
self.sql.execute("""
|
||||
CREATE TABLE "Online_History" (
|
||||
|
||||
self.sql.execute("""
|
||||
CREATE TABLE IF NOT EXISTS "Online_History" (
|
||||
"Index" INTEGER,
|
||||
"Scan_Date" TEXT,
|
||||
"Online_Devices" INTEGER,
|
||||
"Down_Devices" INTEGER,
|
||||
"All_Devices" INTEGER,
|
||||
"Archived_Devices" INTEGER,
|
||||
"Offline_Devices" INTEGER,
|
||||
PRIMARY KEY("Index" AUTOINCREMENT)
|
||||
);
|
||||
""")
|
||||
|
||||
# Offline_Devices column
|
||||
Offline_Devices_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Online_History') WHERE name='Offline_Devices'
|
||||
# -------------------------------------------------------------------
|
||||
# DevicesNew - cleanup after 6/6/2025 - need to update also DB in the source code!
|
||||
|
||||
# check if migration already done based on devMac
|
||||
devMac_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='devMac'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if devMac_missing:
|
||||
|
||||
if Offline_Devices_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding Offline_Devices to the Online_History table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Online_History" ADD "Offline_Devices" INTEGER
|
||||
""")
|
||||
# -------------------------------------------------------------------------
|
||||
# Alter Devices table
|
||||
# -------------------------------------------------------------------------
|
||||
# dev_Network_Node_MAC_ADDR column
|
||||
dev_Network_Node_MAC_ADDR_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Network_Node_MAC_ADDR'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_Network_Node_MAC_ADDR_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_Network_Node_MAC_ADDR to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_Network_Node_MAC_ADDR" TEXT
|
||||
""")
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Alter Devices table
|
||||
# -------------------------------------------------------------------------
|
||||
# dev_Network_Node_MAC_ADDR column
|
||||
dev_Network_Node_MAC_ADDR_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Network_Node_MAC_ADDR'
|
||||
""").fetchone()[0] == 0
|
||||
# dev_Network_Node_port column
|
||||
dev_Network_Node_port_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Network_Node_port'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_Network_Node_MAC_ADDR_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_Network_Node_MAC_ADDR to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_Network_Node_MAC_ADDR" TEXT
|
||||
""")
|
||||
if dev_Network_Node_port_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_Network_Node_port to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_Network_Node_port" INTEGER
|
||||
""")
|
||||
|
||||
# dev_Network_Node_port column
|
||||
dev_Network_Node_port_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Network_Node_port'
|
||||
""").fetchone()[0] == 0
|
||||
# dev_Icon column
|
||||
dev_Icon_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Icon'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_Network_Node_port_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_Network_Node_port to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_Network_Node_port" INTEGER
|
||||
""")
|
||||
if dev_Icon_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_Icon to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_Icon" TEXT
|
||||
""")
|
||||
|
||||
# dev_Icon column
|
||||
dev_Icon_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_Icon'
|
||||
""").fetchone()[0] == 0
|
||||
# dev_GUID column
|
||||
dev_GUID_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_GUID'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_Icon_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_Icon to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_Icon" TEXT
|
||||
""")
|
||||
if dev_GUID_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_GUID to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_GUID" TEXT
|
||||
""")
|
||||
|
||||
# dev_GUID column
|
||||
dev_GUID_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_GUID'
|
||||
""").fetchone()[0] == 0
|
||||
# dev_NetworkSite column
|
||||
dev_NetworkSite_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_NetworkSite'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_GUID_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_GUID to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_GUID" TEXT
|
||||
""")
|
||||
if dev_NetworkSite_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_NetworkSite to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_NetworkSite" TEXT
|
||||
""")
|
||||
|
||||
# dev_NetworkSite column
|
||||
dev_NetworkSite_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_NetworkSite'
|
||||
""").fetchone()[0] == 0
|
||||
# dev_SSID column
|
||||
dev_SSID_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SSID'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if dev_NetworkSite_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_NetworkSite to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_NetworkSite" TEXT
|
||||
""")
|
||||
if dev_SSID_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_SSID to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_SSID" TEXT
|
||||
""")
|
||||
|
||||
# dev_SSID column
|
||||
dev_SSID_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SSID'
|
||||
""").fetchone()[0] == 0
|
||||
# SQL query to update missing dev_GUID
|
||||
self.sql.execute(f'''
|
||||
UPDATE Devices
|
||||
SET dev_GUID = {sql_generateGuid}
|
||||
WHERE dev_GUID IS NULL
|
||||
''')
|
||||
|
||||
if dev_SSID_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_SSID to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_SSID" TEXT
|
||||
""")
|
||||
# dev_SyncHubNodeName column
|
||||
dev_SyncHubNodeName_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SyncHubNodeName'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
# SQL query to update missing dev_GUID
|
||||
self.sql.execute(f'''
|
||||
UPDATE Devices
|
||||
SET dev_GUID = {sql_generateGuid}
|
||||
WHERE dev_GUID IS NULL
|
||||
''')
|
||||
if dev_SyncHubNodeName_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_SyncHubNodeName to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_SyncHubNodeName" TEXT
|
||||
""")
|
||||
|
||||
# dev_SourcePlugin column
|
||||
dev_SourcePlugin_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SourcePlugin'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
# dev_SyncHubNodeName column
|
||||
dev_SyncHubNodeName_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SyncHubNodeName'
|
||||
""").fetchone()[0] == 0
|
||||
if dev_SourcePlugin_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_SourcePlugin to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_SourcePlugin" TEXT
|
||||
""")
|
||||
|
||||
# SQL to create Devices table with indexes
|
||||
sql_create_devices_new_tmp = """
|
||||
CREATE TABLE IF NOT EXISTS Devices_tmp (
|
||||
devMac STRING (50) PRIMARY KEY NOT NULL COLLATE NOCASE,
|
||||
devName STRING (50) NOT NULL DEFAULT "(unknown)",
|
||||
devOwner STRING (30) DEFAULT "(unknown)" NOT NULL,
|
||||
devType STRING (30),
|
||||
devVendor STRING (250),
|
||||
devFavorite BOOLEAN CHECK (devFavorite IN (0, 1)) DEFAULT (0) NOT NULL,
|
||||
devGroup STRING (10),
|
||||
devComments TEXT,
|
||||
devFirstConnection DATETIME NOT NULL,
|
||||
devLastConnection DATETIME NOT NULL,
|
||||
devLastIP STRING (50) NOT NULL COLLATE NOCASE,
|
||||
devStaticIP BOOLEAN DEFAULT (0) NOT NULL CHECK (devStaticIP IN (0, 1)),
|
||||
devScan INTEGER DEFAULT (1) NOT NULL,
|
||||
devLogEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devLogEvents IN (0, 1)),
|
||||
devAlertEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devAlertEvents IN (0, 1)),
|
||||
devAlertDown BOOLEAN NOT NULL DEFAULT (0) CHECK (devAlertDown IN (0, 1)),
|
||||
devSkipRepeated INTEGER DEFAULT 0 NOT NULL,
|
||||
devLastNotification DATETIME,
|
||||
devPresentLastScan BOOLEAN NOT NULL DEFAULT (0) CHECK (devPresentLastScan IN (0, 1)),
|
||||
devIsNew BOOLEAN NOT NULL DEFAULT (1) CHECK (devIsNew IN (0, 1)),
|
||||
devLocation STRING (250) COLLATE NOCASE,
|
||||
devIsArchived BOOLEAN NOT NULL DEFAULT (0) CHECK (devIsArchived IN (0, 1)),
|
||||
devParentMAC TEXT,
|
||||
devParentPort INTEGER,
|
||||
devIcon TEXT,
|
||||
devGUID TEXT,
|
||||
devSite TEXT,
|
||||
devSSID TEXT,
|
||||
devSyncHubNode TEXT,
|
||||
devSourcePlugin TEXT
|
||||
);
|
||||
|
||||
if dev_SyncHubNodeName_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_SyncHubNodeName to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_SyncHubNodeName" TEXT
|
||||
""")
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_PresentLastScan ON Devices_tmp (devPresentLastScan);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_FirstConnection ON Devices_tmp (devFirstConnection);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_AlertDeviceDown ON Devices_tmp (devAlertDown);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_StaticIP ON Devices_tmp (devStaticIP);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_ScanCycle ON Devices_tmp (devScan);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_Favorite ON Devices_tmp (devFavorite);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_LastIP ON Devices_tmp (devLastIP);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_NewDevice ON Devices_tmp (devIsNew);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_Archived ON Devices_tmp (devIsArchived);
|
||||
"""
|
||||
|
||||
# Execute the creation of the Devices table and indexes
|
||||
self.sql.executescript(sql_create_devices_new_tmp)
|
||||
|
||||
# dev_SourcePlugin column
|
||||
dev_SourcePlugin_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Devices') WHERE name='dev_SourcePlugin'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
# copy over data
|
||||
sql_copy_from_devices = """
|
||||
INSERT OR IGNORE INTO Devices_tmp (
|
||||
devMac,
|
||||
devName,
|
||||
devOwner,
|
||||
devType,
|
||||
devVendor,
|
||||
devFavorite,
|
||||
devGroup,
|
||||
devComments,
|
||||
devFirstConnection,
|
||||
devLastConnection,
|
||||
devLastIP,
|
||||
devStaticIP,
|
||||
devScan,
|
||||
devLogEvents,
|
||||
devAlertEvents,
|
||||
devAlertDown,
|
||||
devSkipRepeated,
|
||||
devLastNotification,
|
||||
devPresentLastScan,
|
||||
devIsNew,
|
||||
devLocation,
|
||||
devIsArchived,
|
||||
devParentMAC,
|
||||
devParentPort,
|
||||
devIcon,
|
||||
devGUID,
|
||||
devSite,
|
||||
devSSID,
|
||||
devSyncHubNode,
|
||||
devSourcePlugin
|
||||
)
|
||||
SELECT
|
||||
dev_MAC AS devMac,
|
||||
dev_Name AS devName,
|
||||
dev_Owner AS devOwner,
|
||||
dev_DeviceType AS devType,
|
||||
dev_Vendor AS devVendor,
|
||||
dev_Favorite AS devFavorite,
|
||||
dev_Group AS devGroup,
|
||||
dev_Comments AS devComments,
|
||||
dev_FirstConnection AS devFirstConnection,
|
||||
dev_LastConnection AS devLastConnection,
|
||||
dev_LastIP AS devLastIP,
|
||||
dev_StaticIP AS devStaticIP,
|
||||
dev_ScanCycle AS devScan,
|
||||
dev_LogEvents AS devLogEvents,
|
||||
dev_AlertEvents AS devAlertEvents,
|
||||
dev_AlertDeviceDown AS devAlertDown,
|
||||
dev_SkipRepeated AS devSkipRepeated,
|
||||
dev_LastNotification AS devLastNotification,
|
||||
dev_PresentLastScan AS devPresentLastScan,
|
||||
dev_NewDevice AS devIsNew,
|
||||
dev_Location AS devLocation,
|
||||
dev_Archived AS devIsArchived,
|
||||
dev_Network_Node_MAC_ADDR AS devParentMAC,
|
||||
dev_Network_Node_port AS devParentPort,
|
||||
dev_Icon AS devIcon,
|
||||
dev_GUID AS devGUID,
|
||||
dev_NetworkSite AS devSite,
|
||||
dev_SSID AS devSSID,
|
||||
dev_SyncHubNodeName AS devSyncHubNode,
|
||||
dev_SourcePlugin AS devSourcePlugin
|
||||
FROM Devices;
|
||||
"""
|
||||
|
||||
self.sql.execute(sql_copy_from_devices)
|
||||
|
||||
|
||||
self.sql.execute(""" DROP TABLE Devices;""")
|
||||
# SQL to create Devices table with indexes
|
||||
sql_create_devices_new = """
|
||||
CREATE TABLE IF NOT EXISTS Devices (
|
||||
devMac STRING (50) PRIMARY KEY NOT NULL COLLATE NOCASE,
|
||||
devName STRING (50) NOT NULL DEFAULT "(unknown)",
|
||||
devOwner STRING (30) DEFAULT "(unknown)" NOT NULL,
|
||||
devType STRING (30),
|
||||
devVendor STRING (250),
|
||||
devFavorite BOOLEAN CHECK (devFavorite IN (0, 1)) DEFAULT (0) NOT NULL,
|
||||
devGroup STRING (10),
|
||||
devComments TEXT,
|
||||
devFirstConnection DATETIME NOT NULL,
|
||||
devLastConnection DATETIME NOT NULL,
|
||||
devLastIP STRING (50) NOT NULL COLLATE NOCASE,
|
||||
devStaticIP BOOLEAN DEFAULT (0) NOT NULL CHECK (devStaticIP IN (0, 1)),
|
||||
devScan INTEGER DEFAULT (1) NOT NULL,
|
||||
devLogEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devLogEvents IN (0, 1)),
|
||||
devAlertEvents BOOLEAN NOT NULL DEFAULT (1) CHECK (devAlertEvents IN (0, 1)),
|
||||
devAlertDown BOOLEAN NOT NULL DEFAULT (0) CHECK (devAlertDown IN (0, 1)),
|
||||
devSkipRepeated INTEGER DEFAULT 0 NOT NULL,
|
||||
devLastNotification DATETIME,
|
||||
devPresentLastScan BOOLEAN NOT NULL DEFAULT (0) CHECK (devPresentLastScan IN (0, 1)),
|
||||
devIsNew BOOLEAN NOT NULL DEFAULT (1) CHECK (devIsNew IN (0, 1)),
|
||||
devLocation STRING (250) COLLATE NOCASE,
|
||||
devIsArchived BOOLEAN NOT NULL DEFAULT (0) CHECK (devIsArchived IN (0, 1)),
|
||||
devParentMAC TEXT,
|
||||
devParentPort INTEGER,
|
||||
devIcon TEXT,
|
||||
devGUID TEXT,
|
||||
devSite TEXT,
|
||||
devSSID TEXT,
|
||||
devSyncHubNode TEXT,
|
||||
devSourcePlugin TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_PresentLastScan ON Devices (devPresentLastScan);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_FirstConnection ON Devices (devFirstConnection);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_AlertDeviceDown ON Devices (devAlertDown);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_StaticIP ON Devices (devStaticIP);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_ScanCycle ON Devices (devScan);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_Favorite ON Devices (devFavorite);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_LastIP ON Devices (devLastIP);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_NewDevice ON Devices (devIsNew);
|
||||
CREATE INDEX IF NOT EXISTS IDX_dev_Archived ON Devices (devIsArchived);
|
||||
"""
|
||||
|
||||
# Execute the creation of the Devices table and indexes
|
||||
self.sql.executescript(sql_create_devices_new)
|
||||
|
||||
# copy over data
|
||||
sql_copy_from_devices_tmp = """
|
||||
INSERT OR IGNORE INTO Devices (
|
||||
devMac,
|
||||
devName,
|
||||
devOwner,
|
||||
devType,
|
||||
devVendor,
|
||||
devFavorite,
|
||||
devGroup,
|
||||
devComments,
|
||||
devFirstConnection,
|
||||
devLastConnection,
|
||||
devLastIP,
|
||||
devStaticIP,
|
||||
devScan,
|
||||
devLogEvents,
|
||||
devAlertEvents,
|
||||
devAlertDown,
|
||||
devSkipRepeated,
|
||||
devLastNotification,
|
||||
devPresentLastScan,
|
||||
devIsNew,
|
||||
devLocation,
|
||||
devIsArchived,
|
||||
devParentMAC,
|
||||
devParentPort,
|
||||
devIcon,
|
||||
devGUID,
|
||||
devSite,
|
||||
devSSID,
|
||||
devSyncHubNode,
|
||||
devSourcePlugin
|
||||
)
|
||||
SELECT
|
||||
devMac,
|
||||
devName,
|
||||
devOwner,
|
||||
devType,
|
||||
devVendor,
|
||||
devFavorite,
|
||||
devGroup,
|
||||
devComments,
|
||||
devFirstConnection,
|
||||
devLastConnection,
|
||||
devLastIP,
|
||||
devStaticIP,
|
||||
devScan,
|
||||
devLogEvents,
|
||||
devAlertEvents,
|
||||
devAlertDown,
|
||||
devSkipRepeated,
|
||||
devLastNotification,
|
||||
devPresentLastScan,
|
||||
devIsNew,
|
||||
devLocation,
|
||||
devIsArchived,
|
||||
devParentMAC,
|
||||
devParentPort,
|
||||
devIcon,
|
||||
devGUID,
|
||||
devSite,
|
||||
devSSID,
|
||||
devSyncHubNode,
|
||||
devSourcePlugin
|
||||
FROM Devices_tmp;
|
||||
"""
|
||||
|
||||
self.sql.execute(sql_copy_from_devices_tmp)
|
||||
self.sql.execute(""" DROP TABLE Devices_tmp;""")
|
||||
|
||||
|
||||
# VIEWS
|
||||
|
||||
self.sql.execute(""" DROP VIEW IF EXISTS Events_Devices;""")
|
||||
self.sql.execute(""" CREATE VIEW Events_Devices AS
|
||||
SELECT *
|
||||
FROM Events
|
||||
LEFT JOIN Devices ON eve_MAC = devMac;
|
||||
""")
|
||||
|
||||
|
||||
self.sql.execute(""" DROP VIEW IF EXISTS LatestEventsPerMAC;""")
|
||||
self.sql.execute("""CREATE VIEW LatestEventsPerMAC AS
|
||||
WITH RankedEvents AS (
|
||||
SELECT
|
||||
e.*,
|
||||
ROW_NUMBER() OVER (PARTITION BY e.eve_MAC ORDER BY e.eve_DateTime DESC) AS row_num
|
||||
FROM Events AS e
|
||||
)
|
||||
SELECT
|
||||
e.*,
|
||||
d.*,
|
||||
c.*
|
||||
FROM RankedEvents AS e
|
||||
LEFT JOIN Devices AS d ON e.eve_MAC = d.devMac
|
||||
INNER JOIN CurrentScan AS c ON e.eve_MAC = c.cur_MAC
|
||||
WHERE e.row_num = 1;""")
|
||||
|
||||
self.sql.execute(""" DROP VIEW IF EXISTS Sessions_Devices;""")
|
||||
self.sql.execute("""CREATE VIEW Sessions_Devices AS SELECT * FROM Sessions LEFT JOIN "Devices" ON ses_MAC = devMac;""")
|
||||
|
||||
|
||||
|
||||
|
||||
if dev_SourcePlugin_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding dev_SourcePlugin to the Devices table"])
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Devices" ADD "dev_SourcePlugin" TEXT
|
||||
""")
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Settings table setup
|
||||
@@ -284,96 +539,7 @@ class DB():
|
||||
"par_Value" TEXT
|
||||
);
|
||||
""")
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Nmap_Scan table setup DEPRECATED after 9/9/2024
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# indicates, if Nmap_Scan table is available
|
||||
nmapScanMissing = self.sql.execute("""
|
||||
SELECT name FROM sqlite_master WHERE type='table'
|
||||
AND name='Nmap_Scan';
|
||||
""").fetchone() == None
|
||||
|
||||
if nmapScanMissing == False:
|
||||
# move data into the PLugins_Objects table
|
||||
self.sql.execute("""INSERT INTO Plugins_Objects (
|
||||
Plugin,
|
||||
Object_PrimaryID,
|
||||
Object_SecondaryID,
|
||||
DateTimeCreated,
|
||||
DateTimeChanged,
|
||||
Watched_Value1,
|
||||
Watched_Value2,
|
||||
Watched_Value3,
|
||||
Watched_Value4,
|
||||
Status,
|
||||
Extra,
|
||||
UserData,
|
||||
ForeignKey
|
||||
)
|
||||
SELECT
|
||||
'NMAP' AS Plugin,
|
||||
MAC AS Object_PrimaryID,
|
||||
Port AS Object_SecondaryID,
|
||||
Time AS DateTimeCreated,
|
||||
DATETIME('now') AS DateTimeChanged,
|
||||
State AS Watched_Value1,
|
||||
Service AS Watched_Value2,
|
||||
'' AS Watched_Value3,
|
||||
'' AS Watched_Value4,
|
||||
'watched-not-changed' AS Status,
|
||||
Extra AS Extra,
|
||||
Extra AS UserData,
|
||||
MAC AS ForeignKey
|
||||
FROM Nmap_Scan;""")
|
||||
|
||||
# Delete the Nmap_Scan table
|
||||
self.sql.execute("DROP TABLE Nmap_Scan;")
|
||||
nmapScanMissing = True
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Nmap_Scan table setup DEPRECATED after 9/9/2024 cleanup above
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Icon format migration table setup DEPRECATED after 9/9/2024 cleanup below
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
sql_Icons = """ UPDATE Devices SET dev_Icon = '<i class="fa fa-' || dev_Icon || '"></i>'
|
||||
WHERE dev_Icon NOT LIKE '<i class="fa fa-%'
|
||||
AND dev_Icon NOT LIKE '<svg%'
|
||||
AND dev_Icon NOT LIKE 'PGkg%'
|
||||
AND dev_Icon NOT LIKE 'PHN%'
|
||||
AND dev_Icon NOT IN ('', 'null')
|
||||
"""
|
||||
self.sql.execute(sql_Icons)
|
||||
self.commitDB()
|
||||
|
||||
# Base64 conversion
|
||||
|
||||
self.sql.execute("SELECT dev_MAC, dev_Icon FROM Devices WHERE dev_Icon like '<%' ")
|
||||
icons = self.sql.fetchall()
|
||||
|
||||
|
||||
# Loop through the icons, encode them, and update the database
|
||||
for icon_tuple in icons:
|
||||
icon = icon_tuple[1]
|
||||
|
||||
# Encode the icon as base64
|
||||
encoded_icon = base64.b64encode(icon.encode('utf-8')).decode('ascii')
|
||||
# Update the database with the encoded icon
|
||||
sql_update = f"""
|
||||
UPDATE Devices
|
||||
SET dev_Icon = '{encoded_icon}'
|
||||
WHERE dev_MAC = '{icon_tuple[0]}'
|
||||
"""
|
||||
|
||||
self.sql.execute(sql_update)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Icon format migration table setup DEPRECATED after 9/9/2024 cleanup above
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Plugins tables setup
|
||||
@@ -395,10 +561,18 @@ class DB():
|
||||
Extra TEXT NOT NULL,
|
||||
UserData TEXT NOT NULL,
|
||||
ForeignKey TEXT NOT NULL,
|
||||
SyncHubNodeName TEXT,
|
||||
"HelpVal1" TEXT,
|
||||
"HelpVal2" TEXT,
|
||||
"HelpVal3" TEXT,
|
||||
"HelpVal4" TEXT,
|
||||
PRIMARY KEY("Index" AUTOINCREMENT)
|
||||
); """
|
||||
self.sql.execute(sql_Plugins_Objects)
|
||||
|
||||
# -----------------------------------------
|
||||
# REMOVE after 6/6/2025 - START
|
||||
# -----------------------------------------
|
||||
# syncHubNodeName column
|
||||
plug_SyncHubNodeName_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Objects') WHERE name='SyncHubNodeName'
|
||||
@@ -421,6 +595,10 @@ class DB():
|
||||
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal2" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal3" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal4" TEXT')
|
||||
|
||||
# -----------------------------------------
|
||||
# REMOVE after 6/6/2025 - END
|
||||
# -----------------------------------------
|
||||
|
||||
# Plugin execution results
|
||||
sql_Plugins_Events = """ CREATE TABLE IF NOT EXISTS Plugins_Events(
|
||||
@@ -438,10 +616,19 @@ class DB():
|
||||
Extra TEXT NOT NULL,
|
||||
UserData TEXT NOT NULL,
|
||||
ForeignKey TEXT NOT NULL,
|
||||
SyncHubNodeName TEXT,
|
||||
"HelpVal1" TEXT,
|
||||
"HelpVal2" TEXT,
|
||||
"HelpVal3" TEXT,
|
||||
"HelpVal4" TEXT,
|
||||
PRIMARY KEY("Index" AUTOINCREMENT)
|
||||
); """
|
||||
self.sql.execute(sql_Plugins_Events)
|
||||
|
||||
# -----------------------------------------
|
||||
# REMOVE after 6/6/2025 - START
|
||||
# -----------------------------------------
|
||||
|
||||
# syncHubNodeName column
|
||||
plug_SyncHubNodeName_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Events') WHERE name='SyncHubNodeName'
|
||||
@@ -464,6 +651,10 @@ class DB():
|
||||
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal2" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal3" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal4" TEXT')
|
||||
|
||||
# -----------------------------------------
|
||||
# REMOVE after 6/6/2025 - END
|
||||
# -----------------------------------------
|
||||
|
||||
|
||||
# Plugin execution history
|
||||
@@ -482,9 +673,18 @@ class DB():
|
||||
Extra TEXT NOT NULL,
|
||||
UserData TEXT NOT NULL,
|
||||
ForeignKey TEXT NOT NULL,
|
||||
SyncHubNodeName TEXT,
|
||||
"HelpVal1" TEXT,
|
||||
"HelpVal2" TEXT,
|
||||
"HelpVal3" TEXT,
|
||||
"HelpVal4" TEXT,
|
||||
PRIMARY KEY("Index" AUTOINCREMENT)
|
||||
); """
|
||||
self.sql.execute(sql_Plugins_History)
|
||||
|
||||
# -----------------------------------------
|
||||
# REMOVE after 6/6/2025 - START
|
||||
# -----------------------------------------
|
||||
|
||||
# syncHubNodeName column
|
||||
plug_SyncHubNodeName_missing = self.sql.execute ("""
|
||||
@@ -509,6 +709,9 @@ class DB():
|
||||
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal3" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal4" TEXT')
|
||||
|
||||
# -----------------------------------------
|
||||
# REMOVE after 6/6/2025 - END
|
||||
# -----------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Plugins_Language_Strings table setup
|
||||
@@ -573,7 +776,7 @@ class DB():
|
||||
d.*,
|
||||
c.*
|
||||
FROM RankedEvents AS e
|
||||
LEFT JOIN Devices AS d ON e.eve_MAC = d.dev_MAC
|
||||
LEFT JOIN Devices AS d ON e.eve_MAC = d.devMac
|
||||
INNER JOIN CurrentScan AS c ON e.eve_MAC = c.cur_MAC
|
||||
WHERE e.row_num = 1;
|
||||
""")
|
||||
@@ -638,7 +841,7 @@ class DB():
|
||||
columnNames = list(map(lambda x: x[0], self.sql.description))
|
||||
rows = self.sql.fetchall()
|
||||
except sqlite3.Error as e:
|
||||
mylog('none',[ '[Database] - SQL ERROR: ', e])
|
||||
mylog('verbose',[ '[Database] - SQL ERROR: ', e])
|
||||
return json_obj({}, []) # return empty object
|
||||
|
||||
result = {"data":[]}
|
||||
@@ -663,9 +866,9 @@ class DB():
|
||||
rows = self.sql.fetchall()
|
||||
return rows
|
||||
except AssertionError:
|
||||
mylog('none',[ '[Database] - ERROR: inconsistent query and/or arguments.', query, " params: ", args])
|
||||
mylog('verbose',[ '[Database] - ERROR: inconsistent query and/or arguments.', query, " params: ", args])
|
||||
except sqlite3.Error as e:
|
||||
mylog('none',[ '[Database] - SQL ERROR: ', e])
|
||||
mylog('verbose',[ '[Database] - SQL ERROR: ', e])
|
||||
return None
|
||||
|
||||
def read_one(self, query, *args):
|
||||
@@ -680,7 +883,7 @@ class DB():
|
||||
return rows[0]
|
||||
|
||||
if len(rows) > 1:
|
||||
mylog('none',[ '[Database] - Warning!: query returns multiple rows, only first row is passed on!', query, " params: ", args])
|
||||
mylog('verbose',[ '[Database] - Warning!: query returns multiple rows, only first row is passed on!', query, " params: ", args])
|
||||
return rows[0]
|
||||
# empty result set
|
||||
return None
|
||||
|
||||
274
server/device.py
@@ -25,16 +25,16 @@ class Device_obj:
|
||||
# Get all with unknown names
|
||||
def getUnknown(self):
|
||||
self.db.sql.execute("""
|
||||
SELECT * FROM Devices WHERE dev_Name in ("(unknown)", "(name not found)", "" )
|
||||
SELECT * FROM Devices WHERE devName in ("(unknown)", "(name not found)", "" )
|
||||
""")
|
||||
return self.db.sql.fetchall()
|
||||
|
||||
# Get specific column value based on dev_MAC
|
||||
def getValueWithMac(self, column_name, dev_MAC):
|
||||
# Get specific column value based on devMac
|
||||
def getValueWithMac(self, column_name, devMac):
|
||||
|
||||
query = f"SELECT {column_name} FROM Devices WHERE dev_MAC = ?"
|
||||
query = f"SELECT {column_name} FROM Devices WHERE devMac = ?"
|
||||
|
||||
self.db.sql.execute(query, (dev_MAC,))
|
||||
self.db.sql.execute(query, (devMac,))
|
||||
|
||||
result = self.db.sql.fetchone()
|
||||
|
||||
@@ -102,12 +102,12 @@ def print_scan_stats(db):
|
||||
query = """
|
||||
SELECT
|
||||
(SELECT COUNT(*) FROM CurrentScan) AS devices_detected,
|
||||
(SELECT COUNT(*) FROM CurrentScan WHERE NOT EXISTS (SELECT 1 FROM Devices WHERE dev_MAC = cur_MAC)) AS new_devices,
|
||||
(SELECT COUNT(*) FROM Devices WHERE dev_AlertDeviceDown != 0 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE dev_MAC = cur_MAC)) AS down_alerts,
|
||||
(SELECT COUNT(*) FROM Devices WHERE dev_AlertDeviceDown != 0 AND dev_PresentLastScan = 1 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE dev_MAC = cur_MAC)) AS new_down_alerts,
|
||||
(SELECT COUNT(*) FROM Devices WHERE dev_PresentLastScan = 0) AS new_connections,
|
||||
(SELECT COUNT(*) FROM Devices WHERE dev_PresentLastScan = 1 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE dev_MAC = cur_MAC)) AS disconnections,
|
||||
(SELECT COUNT(*) FROM Devices, CurrentScan WHERE dev_MAC = cur_MAC AND dev_LastIP <> cur_IP) AS ip_changes,
|
||||
(SELECT COUNT(*) FROM CurrentScan WHERE NOT EXISTS (SELECT 1 FROM Devices WHERE devMac = cur_MAC)) AS new_devices,
|
||||
(SELECT COUNT(*) FROM Devices WHERE devAlertDown != 0 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE devMac = cur_MAC)) AS down_alerts,
|
||||
(SELECT COUNT(*) FROM Devices WHERE devAlertDown != 0 AND devPresentLastScan = 1 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE devMac = cur_MAC)) AS new_down_alerts,
|
||||
(SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 0) AS new_connections,
|
||||
(SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 1 AND NOT EXISTS (SELECT 1 FROM CurrentScan WHERE devMac = cur_MAC)) AS disconnections,
|
||||
(SELECT COUNT(*) FROM Devices, CurrentScan WHERE devMac = cur_MAC AND devLastIP <> cur_IP) AS ip_changes,
|
||||
cur_ScanMethod,
|
||||
COUNT(*) AS scan_method_count
|
||||
FROM CurrentScan
|
||||
@@ -175,7 +175,7 @@ def create_new_devices (db):
|
||||
SELECT cur_MAC, cur_IP, '{startTime}', 'New Device', cur_Vendor, 1
|
||||
FROM CurrentScan
|
||||
WHERE NOT EXISTS (SELECT 1 FROM Devices
|
||||
WHERE dev_MAC = cur_MAC)
|
||||
WHERE devMac = cur_MAC)
|
||||
"""
|
||||
|
||||
|
||||
@@ -197,33 +197,33 @@ def create_new_devices (db):
|
||||
mylog('debug','[New Devices] 2 Create devices')
|
||||
|
||||
# default New Device values preparation
|
||||
newDevColumns = """dev_AlertEvents,
|
||||
dev_AlertDeviceDown,
|
||||
dev_PresentLastScan,
|
||||
dev_Archived,
|
||||
dev_NewDevice,
|
||||
dev_SkipRepeated,
|
||||
dev_ScanCycle,
|
||||
dev_Owner,
|
||||
dev_Favorite,
|
||||
dev_Group,
|
||||
dev_Comments,
|
||||
dev_LogEvents,
|
||||
dev_Location"""
|
||||
newDevColumns = """devAlertEvents,
|
||||
devAlertDown,
|
||||
devPresentLastScan,
|
||||
devIsArchived,
|
||||
devIsNew,
|
||||
devSkipRepeated,
|
||||
devScan,
|
||||
devOwner,
|
||||
devFavorite,
|
||||
devGroup,
|
||||
devComments,
|
||||
devLogEvents,
|
||||
devLocation"""
|
||||
|
||||
newDevDefaults = f"""{get_setting_value('NEWDEV_dev_AlertEvents')},
|
||||
{get_setting_value('NEWDEV_dev_AlertDeviceDown')},
|
||||
{get_setting_value('NEWDEV_dev_PresentLastScan')},
|
||||
{get_setting_value('NEWDEV_dev_Archived')},
|
||||
{get_setting_value('NEWDEV_dev_NewDevice')},
|
||||
{get_setting_value('NEWDEV_dev_SkipRepeated')},
|
||||
{get_setting_value('NEWDEV_dev_ScanCycle')},
|
||||
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Owner'))}',
|
||||
{get_setting_value('NEWDEV_dev_Favorite')},
|
||||
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Group'))}',
|
||||
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Comments'))}',
|
||||
{get_setting_value('NEWDEV_dev_LogEvents')},
|
||||
'{sanitize_SQL_input(get_setting_value('NEWDEV_dev_Location'))}'"""
|
||||
newDevDefaults = f"""{get_setting_value('NEWDEV_devAlertEvents')},
|
||||
{get_setting_value('NEWDEV_devAlertDown')},
|
||||
{get_setting_value('NEWDEV_devPresentLastScan')},
|
||||
{get_setting_value('NEWDEV_devIsArchived')},
|
||||
{get_setting_value('NEWDEV_devIsNew')},
|
||||
{get_setting_value('NEWDEV_devSkipRepeated')},
|
||||
{get_setting_value('NEWDEV_devScan')},
|
||||
'{sanitize_SQL_input(get_setting_value('NEWDEV_devOwner'))}',
|
||||
{get_setting_value('NEWDEV_devFavorite')},
|
||||
'{sanitize_SQL_input(get_setting_value('NEWDEV_devGroup'))}',
|
||||
'{sanitize_SQL_input(get_setting_value('NEWDEV_devComments'))}',
|
||||
{get_setting_value('NEWDEV_devLogEvents')},
|
||||
'{sanitize_SQL_input(get_setting_value('NEWDEV_devLocation'))}'"""
|
||||
|
||||
# Fetch data from CurrentScan skipping ignored devices by IP and MAC
|
||||
query = f"""SELECT cur_MAC, cur_Name, cur_Vendor, cur_ScanMethod, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type
|
||||
@@ -238,28 +238,28 @@ def create_new_devices (db):
|
||||
|
||||
# Handle NoneType
|
||||
cur_Name = cur_Name.strip() if cur_Name else '(unknown)'
|
||||
cur_Type = cur_Type.strip() if cur_Type else get_setting_value("NEWDEV_dev_DeviceType")
|
||||
cur_Type = cur_Type.strip() if cur_Type else get_setting_value("NEWDEV_devType")
|
||||
cur_NetworkNodeMAC = cur_NetworkNodeMAC.strip() if cur_NetworkNodeMAC else ''
|
||||
cur_NetworkNodeMAC = cur_NetworkNodeMAC if cur_NetworkNodeMAC and cur_MAC != "Internet" else (get_setting_value("NEWDEV_dev_Network_Node_MAC_ADDR") if cur_MAC != "Internet" else "null")
|
||||
cur_NetworkNodeMAC = cur_NetworkNodeMAC if cur_NetworkNodeMAC and cur_MAC != "Internet" else (get_setting_value("NEWDEV_devParentMAC") if cur_MAC != "Internet" else "null")
|
||||
cur_SyncHubNodeName = cur_SyncHubNodeName if cur_SyncHubNodeName and cur_SyncHubNodeName != "null" else (get_setting_value("SYNC_node_name"))
|
||||
|
||||
# Preparing the individual insert statement
|
||||
sqlQuery = f"""INSERT OR IGNORE INTO Devices
|
||||
(
|
||||
dev_MAC,
|
||||
dev_name,
|
||||
dev_Vendor,
|
||||
dev_LastIP,
|
||||
dev_FirstConnection,
|
||||
dev_LastConnection,
|
||||
dev_SyncHubNodeName,
|
||||
dev_GUID,
|
||||
dev_Network_Node_MAC_ADDR,
|
||||
dev_Network_Node_port,
|
||||
dev_NetworkSite,
|
||||
dev_SSID,
|
||||
dev_DeviceType,
|
||||
dev_SourcePlugin,
|
||||
devMac,
|
||||
devName,
|
||||
devVendor,
|
||||
devLastIP,
|
||||
devFirstConnection,
|
||||
devLastConnection,
|
||||
devSyncHubNode,
|
||||
devGUID,
|
||||
devParentMAC,
|
||||
devParentPort,
|
||||
devSite,
|
||||
devSSID,
|
||||
devType,
|
||||
devSourcePlugin,
|
||||
{newDevColumns}
|
||||
)
|
||||
VALUES
|
||||
@@ -297,140 +297,140 @@ def update_devices_data_from_scan (db):
|
||||
|
||||
# Update Last Connection
|
||||
mylog('debug', '[Update Devices] 1 Last Connection')
|
||||
sql.execute(f"""UPDATE Devices SET dev_LastConnection = '{startTime}',
|
||||
dev_PresentLastScan = 1
|
||||
WHERE dev_PresentLastScan = 0
|
||||
sql.execute(f"""UPDATE Devices SET devLastConnection = '{startTime}',
|
||||
devPresentLastScan = 1
|
||||
WHERE devPresentLastScan = 0
|
||||
AND EXISTS (SELECT 1 FROM CurrentScan
|
||||
WHERE dev_MAC = cur_MAC) """)
|
||||
WHERE devMac = cur_MAC) """)
|
||||
|
||||
# Clean no active devices
|
||||
mylog('debug', '[Update Devices] 2 Clean no active devices')
|
||||
sql.execute("""UPDATE Devices SET dev_PresentLastScan = 0
|
||||
sql.execute("""UPDATE Devices SET devPresentLastScan = 0
|
||||
WHERE NOT EXISTS (SELECT 1 FROM CurrentScan
|
||||
WHERE dev_MAC = cur_MAC) """)
|
||||
WHERE devMac = cur_MAC) """)
|
||||
|
||||
# Update IP
|
||||
mylog('debug', '[Update Devices] - cur_IP -> dev_LastIP (always updated)')
|
||||
mylog('debug', '[Update Devices] - cur_IP -> devLastIP (always updated)')
|
||||
sql.execute("""UPDATE Devices
|
||||
SET dev_LastIP = (SELECT cur_IP FROM CurrentScan
|
||||
WHERE dev_MAC = cur_MAC)
|
||||
SET devLastIP = (SELECT cur_IP FROM CurrentScan
|
||||
WHERE devMac = cur_MAC)
|
||||
WHERE EXISTS (SELECT 1 FROM CurrentScan
|
||||
WHERE dev_MAC = cur_MAC) """)
|
||||
WHERE devMac = cur_MAC) """)
|
||||
|
||||
# Update only devices with empty or NULL vendors
|
||||
mylog('debug', '[Update Devices] - cur_Vendor -> (if empty) dev_Vendor')
|
||||
mylog('debug', '[Update Devices] - cur_Vendor -> (if empty) devVendor')
|
||||
sql.execute("""UPDATE Devices
|
||||
SET dev_Vendor = (
|
||||
SET devVendor = (
|
||||
SELECT cur_Vendor
|
||||
FROM CurrentScan
|
||||
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
|
||||
WHERE Devices.devMac = CurrentScan.cur_MAC
|
||||
)
|
||||
WHERE
|
||||
(dev_Vendor IS NULL OR dev_Vendor IN ("", "null"))
|
||||
(devVendor IS NULL OR devVendor IN ("", "null"))
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM CurrentScan
|
||||
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
|
||||
WHERE Devices.devMac = CurrentScan.cur_MAC
|
||||
)""")
|
||||
|
||||
# Update only devices with empty or NULL dev_Network_Node_port
|
||||
mylog('debug', '[Update Devices] - (if not empty) cur_Port -> dev_Network_Node_port')
|
||||
# Update only devices with empty or NULL devParentPort
|
||||
mylog('debug', '[Update Devices] - (if not empty) cur_Port -> devParentPort')
|
||||
sql.execute("""UPDATE Devices
|
||||
SET dev_Network_Node_port = (
|
||||
SET devParentPort = (
|
||||
SELECT cur_Port
|
||||
FROM CurrentScan
|
||||
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
|
||||
WHERE Devices.devMac = CurrentScan.cur_MAC
|
||||
)
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM CurrentScan
|
||||
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
|
||||
WHERE Devices.devMac = CurrentScan.cur_MAC
|
||||
AND CurrentScan.cur_Port IS NOT NULL AND CurrentScan.cur_Port NOT IN ("", "null")
|
||||
)""")
|
||||
|
||||
# Update only devices with empty or NULL dev_Network_Node_MAC_ADDR
|
||||
mylog('debug', '[Update Devices] - (if not empty) cur_NetworkNodeMAC -> dev_Network_Node_MAC_ADDR')
|
||||
# Update only devices with empty or NULL devParentMAC
|
||||
mylog('debug', '[Update Devices] - (if not empty) cur_NetworkNodeMAC -> devParentMAC')
|
||||
sql.execute("""UPDATE Devices
|
||||
SET dev_Network_Node_MAC_ADDR = (
|
||||
SET devParentMAC = (
|
||||
SELECT cur_NetworkNodeMAC
|
||||
FROM CurrentScan
|
||||
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
|
||||
WHERE Devices.devMac = CurrentScan.cur_MAC
|
||||
)
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM CurrentScan
|
||||
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
|
||||
WHERE Devices.devMac = CurrentScan.cur_MAC
|
||||
AND CurrentScan.cur_NetworkNodeMAC IS NOT NULL AND CurrentScan.cur_NetworkNodeMAC NOT IN ("", "null")
|
||||
)""")
|
||||
|
||||
# Update only devices with empty or NULL dev_NetworkSite
|
||||
mylog('debug', '[Update Devices] - (if not empty) cur_NetworkSite -> (if empty) dev_NetworkSite')
|
||||
# Update only devices with empty or NULL devSite
|
||||
mylog('debug', '[Update Devices] - (if not empty) cur_NetworkSite -> (if empty) devSite')
|
||||
sql.execute("""UPDATE Devices
|
||||
SET dev_NetworkSite = (
|
||||
SET devSite = (
|
||||
SELECT cur_NetworkSite
|
||||
FROM CurrentScan
|
||||
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
|
||||
WHERE Devices.devMac = CurrentScan.cur_MAC
|
||||
)
|
||||
WHERE
|
||||
(dev_NetworkSite IS NULL OR dev_NetworkSite IN ("", "null"))
|
||||
(devSite IS NULL OR devSite IN ("", "null"))
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM CurrentScan
|
||||
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
|
||||
WHERE Devices.devMac = CurrentScan.cur_MAC
|
||||
AND CurrentScan.cur_NetworkSite IS NOT NULL AND CurrentScan.cur_NetworkSite NOT IN ("", "null")
|
||||
)""")
|
||||
|
||||
# Update only devices with empty or NULL dev_SSID
|
||||
mylog('debug', '[Update Devices] - (if not empty) cur_SSID -> (if empty) dev_SSID')
|
||||
# Update only devices with empty or NULL devSSID
|
||||
mylog('debug', '[Update Devices] - (if not empty) cur_SSID -> (if empty) devSSID')
|
||||
sql.execute("""UPDATE Devices
|
||||
SET dev_SSID = (
|
||||
SET devSSID = (
|
||||
SELECT cur_SSID
|
||||
FROM CurrentScan
|
||||
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
|
||||
WHERE Devices.devMac = CurrentScan.cur_MAC
|
||||
)
|
||||
WHERE
|
||||
(dev_SSID IS NULL OR dev_SSID IN ("", "null"))
|
||||
(devSSID IS NULL OR devSSID IN ("", "null"))
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM CurrentScan
|
||||
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
|
||||
WHERE Devices.devMac = CurrentScan.cur_MAC
|
||||
AND CurrentScan.cur_SSID IS NOT NULL AND CurrentScan.cur_SSID NOT IN ("", "null")
|
||||
)""")
|
||||
|
||||
# Update only devices with empty or NULL dev_DeviceType
|
||||
mylog('debug', '[Update Devices] - (if not empty) cur_Type -> (if empty) dev_DeviceType')
|
||||
# Update only devices with empty or NULL devType
|
||||
mylog('debug', '[Update Devices] - (if not empty) cur_Type -> (if empty) devType')
|
||||
sql.execute("""UPDATE Devices
|
||||
SET dev_DeviceType = (
|
||||
SET devType = (
|
||||
SELECT cur_Type
|
||||
FROM CurrentScan
|
||||
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
|
||||
WHERE Devices.devMac = CurrentScan.cur_MAC
|
||||
)
|
||||
WHERE
|
||||
(dev_DeviceType IS NULL OR dev_DeviceType IN ("", "null"))
|
||||
(devType IS NULL OR devType IN ("", "null"))
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM CurrentScan
|
||||
WHERE Devices.dev_MAC = CurrentScan.cur_MAC
|
||||
WHERE Devices.devMac = CurrentScan.cur_MAC
|
||||
AND CurrentScan.cur_Type IS NOT NULL AND CurrentScan.cur_Type NOT IN ("", "null")
|
||||
)""")
|
||||
|
||||
# Update (unknown) or (name not found) Names if available
|
||||
mylog('debug','[Update Devices] - (if not empty) cur_Name -> (if empty) dev_NAME')
|
||||
mylog('debug','[Update Devices] - (if not empty) cur_Name -> (if empty) devName')
|
||||
sql.execute (""" UPDATE Devices
|
||||
SET dev_NAME = COALESCE((
|
||||
SET devName = COALESCE((
|
||||
SELECT cur_Name
|
||||
FROM CurrentScan
|
||||
WHERE cur_MAC = dev_MAC
|
||||
WHERE cur_MAC = devMac
|
||||
AND cur_Name IS NOT NULL
|
||||
AND cur_Name <> 'null'
|
||||
AND cur_Name <> ''
|
||||
), dev_NAME)
|
||||
WHERE (dev_NAME IN ('(unknown)', '(name not found)', '')
|
||||
OR dev_NAME IS NULL)
|
||||
), devName)
|
||||
WHERE (devName IN ('(unknown)', '(name not found)', '')
|
||||
OR devName IS NULL)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM CurrentScan
|
||||
WHERE cur_MAC = dev_MAC
|
||||
WHERE cur_MAC = devMac
|
||||
AND cur_Name IS NOT NULL
|
||||
AND cur_Name <> 'null'
|
||||
AND cur_Name <> ''
|
||||
@@ -439,48 +439,48 @@ def update_devices_data_from_scan (db):
|
||||
# Update VENDORS
|
||||
recordsToUpdate = []
|
||||
query = """SELECT * FROM Devices
|
||||
WHERE dev_Vendor = '(unknown)' OR dev_Vendor =''
|
||||
OR dev_Vendor IS NULL"""
|
||||
WHERE devVendor = '(unknown)' OR devVendor =''
|
||||
OR devVendor IS NULL"""
|
||||
|
||||
for device in sql.execute (query) :
|
||||
vendor = query_MAC_vendor (device['dev_MAC'])
|
||||
vendor = query_MAC_vendor (device['devMac'])
|
||||
if vendor != -1 and vendor != -2 :
|
||||
recordsToUpdate.append ([vendor, device['dev_MAC']])
|
||||
recordsToUpdate.append ([vendor, device['devMac']])
|
||||
|
||||
if len(recordsToUpdate) > 0:
|
||||
sql.executemany ("UPDATE Devices SET dev_Vendor = ? WHERE dev_MAC = ? ", recordsToUpdate )
|
||||
sql.executemany ("UPDATE Devices SET devVendor = ? WHERE devMac = ? ", recordsToUpdate )
|
||||
|
||||
# Guess ICONS
|
||||
recordsToUpdate = []
|
||||
query = """SELECT * FROM Devices
|
||||
WHERE dev_Icon in ('', 'null')
|
||||
OR dev_Icon IS NULL"""
|
||||
default_icon = get_setting_value('NEWDEV_dev_Icon')
|
||||
WHERE devIcon in ('', 'null')
|
||||
OR devIcon IS NULL"""
|
||||
default_icon = get_setting_value('NEWDEV_devIcon')
|
||||
|
||||
for device in sql.execute (query) :
|
||||
# Conditional logic for dev_Icon guessing
|
||||
dev_Icon = guess_icon(device['dev_Vendor'], device['dev_MAC'], device['dev_LastIP'], device['dev_Name'], default_icon)
|
||||
# Conditional logic for devIcon guessing
|
||||
devIcon = guess_icon(device['devVendor'], device['devMac'], device['devLastIP'], device['devName'], default_icon)
|
||||
|
||||
recordsToUpdate.append ([dev_Icon, device['dev_MAC']])
|
||||
recordsToUpdate.append ([devIcon, device['devMac']])
|
||||
|
||||
if len(recordsToUpdate) > 0:
|
||||
sql.executemany ("UPDATE Devices SET dev_Icon = ? WHERE dev_MAC = ? ", recordsToUpdate )
|
||||
sql.executemany ("UPDATE Devices SET devIcon = ? WHERE devMac = ? ", recordsToUpdate )
|
||||
|
||||
# Guess Type
|
||||
recordsToUpdate = []
|
||||
query = """SELECT * FROM Devices
|
||||
WHERE dev_DeviceType in ('', 'null')
|
||||
OR dev_DeviceType IS NULL"""
|
||||
default_type = get_setting_value('NEWDEV_dev_DeviceType')
|
||||
WHERE devType in ('', 'null')
|
||||
OR devType IS NULL"""
|
||||
default_type = get_setting_value('NEWDEV_devType')
|
||||
|
||||
for device in sql.execute (query) :
|
||||
# Conditional logic for dev_Icon guessing
|
||||
dev_DeviceType = guess_type(device['dev_Vendor'], device['dev_MAC'], device['dev_LastIP'], device['dev_Name'], default_type)
|
||||
# Conditional logic for devIcon guessing
|
||||
devType = guess_type(device['devVendor'], device['devMac'], device['devLastIP'], device['devName'], default_type)
|
||||
|
||||
recordsToUpdate.append ([dev_DeviceType, device['dev_MAC']])
|
||||
recordsToUpdate.append ([devType, device['devMac']])
|
||||
|
||||
if len(recordsToUpdate) > 0:
|
||||
sql.executemany ("UPDATE Devices SET dev_DeviceType = ? WHERE dev_MAC = ? ", recordsToUpdate )
|
||||
sql.executemany ("UPDATE Devices SET devType = ? WHERE devMac = ? ", recordsToUpdate )
|
||||
|
||||
|
||||
mylog('debug','[Update Devices] Update devices end')
|
||||
@@ -504,7 +504,7 @@ def update_devices_names (db):
|
||||
foundPholus = 0
|
||||
|
||||
# Gen unknown devices
|
||||
sql.execute ("SELECT * FROM Devices WHERE dev_Name IN ('(unknown)','', '(name not found)') AND dev_LastIP <> '-'")
|
||||
sql.execute ("SELECT * FROM Devices WHERE devName IN ('(unknown)','', '(name not found)') AND devLastIP <> '-'")
|
||||
unknownDevices = sql.fetchall()
|
||||
db.commitDB()
|
||||
|
||||
@@ -528,7 +528,7 @@ def update_devices_names (db):
|
||||
newName = nameNotFound
|
||||
|
||||
# Resolve device name with DiG
|
||||
newName = resolve_device_name_dig (device['dev_MAC'], device['dev_LastIP'])
|
||||
newName = resolve_device_name_dig (device['devMac'], device['devLastIP'])
|
||||
|
||||
# count
|
||||
if newName != nameNotFound:
|
||||
@@ -536,21 +536,21 @@ def update_devices_names (db):
|
||||
|
||||
# Resolve device name with AVAHISCAN plugin data
|
||||
if newName == nameNotFound:
|
||||
newName = get_device_name_mdns(db, device['dev_MAC'], device['dev_LastIP'])
|
||||
newName = get_device_name_mdns(db, device['devMac'], device['devLastIP'])
|
||||
|
||||
if newName != nameNotFound:
|
||||
foundmDNSLookup += 1
|
||||
|
||||
# Resolve device name with NSLOOKUP plugin data
|
||||
if newName == nameNotFound:
|
||||
newName = get_device_name_nslookup(db, device['dev_MAC'], device['dev_LastIP'])
|
||||
newName = get_device_name_nslookup(db, device['devMac'], device['devLastIP'])
|
||||
|
||||
if newName != nameNotFound:
|
||||
foundNsLookup += 1
|
||||
|
||||
# Resolve device name with NSLOOKUP plugin data
|
||||
if newName == nameNotFound:
|
||||
newName = get_device_name_nbtlookup(db, device['dev_MAC'], device['dev_LastIP'])
|
||||
newName = get_device_name_nbtlookup(db, device['devMac'], device['devLastIP'])
|
||||
|
||||
if newName != nameNotFound:
|
||||
foundNbtLookup += 1
|
||||
@@ -560,10 +560,10 @@ def update_devices_names (db):
|
||||
if newName == nameNotFound:
|
||||
|
||||
# Try MAC matching
|
||||
newName = resolve_device_name_pholus (device['dev_MAC'], device['dev_LastIP'], pholusResults, nameNotFound, False)
|
||||
newName = resolve_device_name_pholus (device['devMac'], device['devLastIP'], pholusResults, nameNotFound, False)
|
||||
# Try IP matching
|
||||
if newName == nameNotFound:
|
||||
newName = resolve_device_name_pholus (device['dev_MAC'], device['dev_LastIP'], pholusResults, nameNotFound, True)
|
||||
newName = resolve_device_name_pholus (device['devMac'], device['devLastIP'], pholusResults, nameNotFound, True)
|
||||
|
||||
# count
|
||||
if newName != nameNotFound:
|
||||
@@ -574,22 +574,22 @@ def update_devices_names (db):
|
||||
|
||||
notFound += 1
|
||||
|
||||
# if dev_Name is the same as what we will change it to, take no action
|
||||
# if devName is the same as what we will change it to, take no action
|
||||
# this mitigates a race condition which would overwrite a users edits that occured since the select earlier
|
||||
if device['dev_Name'] != nameNotFound:
|
||||
recordsNotFound.append (["(name not found)", device['dev_MAC']])
|
||||
if device['devName'] != nameNotFound:
|
||||
recordsNotFound.append (["(name not found)", device['devMac']])
|
||||
else:
|
||||
# name was found with DiG or Pholus
|
||||
recordsToUpdate.append ([newName, device['dev_MAC']])
|
||||
recordsToUpdate.append ([newName, device['devMac']])
|
||||
|
||||
# Print log
|
||||
mylog('verbose', [f'[Update Device Name] Names Found (DiG/mDNS/NSLOOKUP/NBTSCAN/Pholus): {len(recordsToUpdate)} ({foundDig}/{foundmDNSLookup}/{foundNsLookup}/{foundNbtLookup}/{foundPholus})'] )
|
||||
mylog('verbose', [f'[Update Device Name] Names Not Found : {notFound}'] )
|
||||
|
||||
# update not found devices with (name not found)
|
||||
sql.executemany ("UPDATE Devices SET dev_Name = ? WHERE dev_MAC = ? ", recordsNotFound )
|
||||
sql.executemany ("UPDATE Devices SET devName = ? WHERE devMac = ? ", recordsNotFound )
|
||||
# update names of devices which we were bale to resolve
|
||||
sql.executemany ("UPDATE Devices SET dev_Name = ? WHERE dev_MAC = ? ", recordsToUpdate )
|
||||
sql.executemany ("UPDATE Devices SET devName = ? WHERE devMac = ? ", recordsToUpdate )
|
||||
db.commitDB()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -739,7 +739,7 @@ def guess_type(vendor, mac, ip, name, default):
|
||||
result = default
|
||||
mac = mac.upper()
|
||||
vendor = vendor.lower() if vendor else "unknown"
|
||||
name = name.lower() if name else "(unknown)"
|
||||
name = str(name).lower() if name else "(unknown)"
|
||||
|
||||
# Guess icon based on vendor
|
||||
if any(brand in vendor for brand in {"samsung", "motorola"}):
|
||||
|
||||
188
server/graphql_server/graphql_schema.py
Executable file
@@ -0,0 +1,188 @@
|
||||
import graphene
|
||||
from graphene import ObjectType, String, Int, Boolean, List, Field, InputObjectType
|
||||
import json
|
||||
import sys
|
||||
|
||||
# Register NetAlertX directories
|
||||
INSTALL_PATH="/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/server"])
|
||||
|
||||
from logger import mylog
|
||||
from const import apiPath
|
||||
from helper import is_random_mac, get_number_of_children, format_ip_long, get_setting_value
|
||||
|
||||
# Define a base URL with the user's home directory
|
||||
folder = apiPath
|
||||
|
||||
# Pagination and Sorting Input Types
|
||||
class SortOptionsInput(InputObjectType):
|
||||
field = String()
|
||||
order = String()
|
||||
|
||||
class PageQueryOptionsInput(InputObjectType):
|
||||
page = Int()
|
||||
limit = Int()
|
||||
sort = List(SortOptionsInput)
|
||||
search = String()
|
||||
status = String()
|
||||
|
||||
# Device ObjectType
|
||||
class Device(ObjectType):
|
||||
rowid = Int()
|
||||
devMac = String()
|
||||
devName = String()
|
||||
devOwner = String()
|
||||
devType = String()
|
||||
devVendor = String()
|
||||
devFavorite = Int()
|
||||
devGroup = String()
|
||||
devComments = String()
|
||||
devFirstConnection = String()
|
||||
devLastConnection = String()
|
||||
devLastIP = String()
|
||||
devStaticIP = Int()
|
||||
devScan = Int()
|
||||
devLogEvents = Int()
|
||||
devAlertEvents = Int()
|
||||
devAlertDown = Int()
|
||||
devSkipRepeated = Int()
|
||||
devLastNotification = String()
|
||||
devPresentLastScan = Int()
|
||||
devIsNew = Int()
|
||||
devLocation = String()
|
||||
devIsArchived = Int()
|
||||
devParentMAC = String()
|
||||
devParentPort = String()
|
||||
devIcon = String()
|
||||
devGUID = String()
|
||||
devSite = String()
|
||||
devSSID = String()
|
||||
devSyncHubNode = String()
|
||||
devSourcePlugin = String()
|
||||
devStatus = String()
|
||||
devIsRandomMac = Int()
|
||||
devParentChildrenCount = Int()
|
||||
devIpLong = Int()
|
||||
devFilterStatus = String()
|
||||
|
||||
|
||||
class DeviceResult(ObjectType):
|
||||
devices = List(Device)
|
||||
count = Int()
|
||||
|
||||
# Define Query Type with Pagination Support
|
||||
class Query(ObjectType):
|
||||
devices = Field(DeviceResult, options=PageQueryOptionsInput())
|
||||
|
||||
def resolve_devices(self, info, options=None):
|
||||
# mylog('none', f'[graphql_schema] resolve_devices: {self}')
|
||||
try:
|
||||
with open(folder + 'table_devices.json', 'r') as f:
|
||||
devices_data = json.load(f)["data"]
|
||||
except (FileNotFoundError, json.JSONDecodeError) as e:
|
||||
mylog('none', f'[graphql_schema] Error loading devices data: {e}')
|
||||
return DeviceResult(devices=[], count=0)
|
||||
|
||||
|
||||
# Add dynamic fields to each device
|
||||
for device in devices_data:
|
||||
device["devIsRandomMac"] = 1 if is_random_mac(device["devMac"]) else 0
|
||||
device["devParentChildrenCount"] = get_number_of_children(device["devMac"], devices_data)
|
||||
device["devIpLong"] = format_ip_long(device.get("devLastIP", ""))
|
||||
|
||||
total_count = len(devices_data)
|
||||
|
||||
mylog('none', f'[graphql_schema] devices_data: {devices_data}')
|
||||
|
||||
|
||||
|
||||
# Apply sorting if options are provided
|
||||
if options:
|
||||
|
||||
# Define status-specific filtering
|
||||
if options.status:
|
||||
status = options.status
|
||||
mylog('none', f'[graphql_schema] Applying status filter: {status}')
|
||||
|
||||
# Example filtering based on the "status"
|
||||
if status == "my_devices":
|
||||
# Include devices matching criteria in UI_MY_DEVICES
|
||||
allowed_statuses = get_setting_value("UI_MY_DEVICES")
|
||||
|
||||
mylog('none', f'[graphql_schema] allowed_statuses: {allowed_statuses}')
|
||||
|
||||
devices_data = [
|
||||
device for device in devices_data
|
||||
if (
|
||||
(device["devPresentLastScan"] == 1 and 'online' in allowed_statuses) or
|
||||
(device["devIsNew"] == 1 and 'new' in allowed_statuses) or
|
||||
(device["devPresentLastScan"] == 0 and device["devAlertDown"] and 'down' in allowed_statuses) or
|
||||
(device["devPresentLastScan"] == 0 and 'offline' in allowed_statuses)
|
||||
)
|
||||
]
|
||||
elif status == "connected":
|
||||
devices_data = [device for device in devices_data if device["devPresentLastScan"] == 1]
|
||||
elif status == "favorites":
|
||||
devices_data = [device for device in devices_data if device["devFavorite"] == 1]
|
||||
elif status == "new":
|
||||
devices_data = [device for device in devices_data if device["devIsNew"] == 1]
|
||||
elif status == "down":
|
||||
devices_data = [
|
||||
device for device in devices_data
|
||||
if device["devPresentLastScan"] == 0 and device["devAlertDown"]
|
||||
]
|
||||
elif status == "archived":
|
||||
devices_data = [device for device in devices_data if device["devIsArchived"] == 1]
|
||||
elif status == "offline":
|
||||
devices_data = [device for device in devices_data if device["devPresentLastScan"] == 0]
|
||||
|
||||
# sorting
|
||||
if options.sort:
|
||||
for sort_option in options.sort:
|
||||
devices_data = sorted(
|
||||
devices_data,
|
||||
key=lambda x: mixed_type_sort_key(x.get(sort_option.field)),
|
||||
reverse=(sort_option.order.lower() == "desc")
|
||||
)
|
||||
|
||||
# Filter data if a search term is provided
|
||||
if options.search:
|
||||
# Define static list of searchable fields
|
||||
searchable_fields = [
|
||||
"devName", "devMac", "devOwner", "devType", "devVendor", "devLastIP"
|
||||
"devGroup", "devComments", "devLocation", "devStatus",
|
||||
"devSSID", "devSite", "devSourcePlugin", "devSyncHubNode"
|
||||
]
|
||||
|
||||
search_term = options.search.lower()
|
||||
|
||||
devices_data = [
|
||||
device for device in devices_data
|
||||
if any(
|
||||
search_term in str(device.get(field, "")).lower()
|
||||
for field in searchable_fields # Search only predefined fields
|
||||
)
|
||||
]
|
||||
|
||||
# Then apply pagination
|
||||
if options.page and options.limit:
|
||||
start = (options.page - 1) * options.limit
|
||||
end = start + options.limit
|
||||
devices_data = devices_data[start:end]
|
||||
|
||||
# Convert dict objects to Device instances to enable field resolution
|
||||
devices = [Device(**device) for device in devices_data]
|
||||
|
||||
return DeviceResult(devices=devices, count=total_count)
|
||||
|
||||
# helps sorting inconsistent dataset mixed integers and strings
|
||||
def mixed_type_sort_key(value):
|
||||
if value is None or value == "":
|
||||
return (2, '') # Place None or empty strings last
|
||||
try:
|
||||
return (0, int(value)) # Integers get priority
|
||||
except (ValueError, TypeError):
|
||||
return (1, str(value)) # Strings come next
|
||||
|
||||
# Schema Definition
|
||||
devicesSchema = graphene.Schema(query=Query)
|
||||
62
server/graphql_server/graphql_server_start.py
Executable file
@@ -0,0 +1,62 @@
|
||||
import threading
|
||||
from flask import Flask, request, jsonify
|
||||
from .graphql_schema import devicesSchema
|
||||
from graphene import Schema
|
||||
import sys
|
||||
|
||||
# Register NetAlertX directories
|
||||
INSTALL_PATH = "/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/server"])
|
||||
|
||||
from logger import mylog
|
||||
from helper import get_setting_value, timeNowTZ, updateState
|
||||
from notification import write_notification
|
||||
|
||||
# Flask application
|
||||
app = Flask(__name__)
|
||||
|
||||
# Retrieve API token and port
|
||||
graphql_port_value = get_setting_value("GRAPHQL_PORT")
|
||||
|
||||
|
||||
# Endpoint for GraphQL queries
|
||||
@app.route("/graphql", methods=["POST"])
|
||||
def graphql_endpoint():
|
||||
# Check for API token in headers
|
||||
incoming_header_token = request.headers.get("Authorization")
|
||||
api_token_value = get_setting_value("API_TOKEN")
|
||||
|
||||
if incoming_header_token != f"Bearer {api_token_value}":
|
||||
mylog('verbose', [f'[graphql_server] Unauthorized access attempt'])
|
||||
return jsonify({"error": "Unauthorized"}), 401
|
||||
|
||||
# Retrieve and log request data
|
||||
data = request.get_json()
|
||||
mylog('verbose', [f'[graphql_server] data: {data}'])
|
||||
|
||||
# Execute the GraphQL query
|
||||
result = devicesSchema.execute(data.get("query"), variables=data.get("variables"))
|
||||
|
||||
# Return the result as JSON
|
||||
return jsonify(result.data)
|
||||
|
||||
def start_server(graphql_port, app_state):
|
||||
"""Start the GraphQL server in a background thread."""
|
||||
|
||||
if app_state.graphQLServerStarted == 0:
|
||||
|
||||
mylog('verbose', [f'[graphql_server] Starting on port: {graphql_port}'])
|
||||
|
||||
# Start Flask app in a separate thread
|
||||
thread = threading.Thread(
|
||||
target=lambda: app.run(
|
||||
host="0.0.0.0",
|
||||
port=graphql_port,
|
||||
debug=True,
|
||||
use_reloader=False
|
||||
)
|
||||
)
|
||||
thread.start()
|
||||
|
||||
# Update the state to indicate the server has started
|
||||
app_state = updateState("Process: Wait", None, None, None, 1)
|
||||
@@ -15,6 +15,9 @@ from pathlib import Path
|
||||
import requests
|
||||
import base64
|
||||
import hashlib
|
||||
import random
|
||||
import string
|
||||
import ipaddress
|
||||
|
||||
|
||||
import conf
|
||||
@@ -54,8 +57,9 @@ def get_timezone_offset():
|
||||
# App state
|
||||
#-------------------------------------------------------------------------------
|
||||
# A class to manage the application state and to provide a frontend accessible API point
|
||||
# To keep an existing value pass None
|
||||
class app_state_class:
|
||||
def __init__(self, currentState, settingsSaved=None, settingsImported=None, showSpinner=False):
|
||||
def __init__(self, currentState, settingsSaved=None, settingsImported=None, showSpinner=False, graphQLServerStarted=0):
|
||||
# json file containing the state to communicate with the frontend
|
||||
stateFile = apiPath + '/app_state.json'
|
||||
previousState = ""
|
||||
@@ -75,19 +79,21 @@ class app_state_class:
|
||||
mylog('none', [f'[app_state_class] Failed to handle app_state.json: {e}'])
|
||||
|
||||
|
||||
# Check if the file exists and init values
|
||||
# Check if the file exists and recover previous values
|
||||
if previousState != "":
|
||||
self.settingsSaved = previousState.get("settingsSaved", 0)
|
||||
self.settingsImported = previousState.get("settingsImported", 0)
|
||||
self.showSpinner = previousState.get("showSpinner", False)
|
||||
self.isNewVersion = previousState.get("isNewVersion", False)
|
||||
self.isNewVersionChecked = previousState.get("isNewVersionChecked", 0)
|
||||
else:
|
||||
self.graphQLServerStarted = previousState.get("graphQLServerStarted", 0)
|
||||
else: # init first time values
|
||||
self.settingsSaved = 0
|
||||
self.settingsImported = 0
|
||||
self.showSpinner = False
|
||||
self.isNewVersion = checkNewVersion()
|
||||
self.isNewVersionChecked = int(timeNow().timestamp())
|
||||
self.graphQLServerStarted = 0
|
||||
|
||||
# Overwrite with provided parameters if supplied
|
||||
if settingsSaved is not None:
|
||||
@@ -96,6 +102,8 @@ class app_state_class:
|
||||
self.settingsImported = settingsImported
|
||||
if showSpinner is not None:
|
||||
self.showSpinner = showSpinner
|
||||
if graphQLServerStarted is not None:
|
||||
self.graphQLServerStarted = graphQLServerStarted
|
||||
|
||||
# check for new version every hour and if currently not running new version
|
||||
if self.isNewVersion is False and self.isNewVersionChecked + 3600 < int(timeNow().timestamp()):
|
||||
@@ -112,7 +120,7 @@ class app_state_class:
|
||||
with open(stateFile, 'w') as json_file:
|
||||
json_file.write(json_data)
|
||||
except (TypeError, ValueError) as e:
|
||||
mylog('none', [f'[app_state_class] Failed to serialize object to JSON: {e}'])
|
||||
mylog('none', [f'[app_state_class] Failed to serialize object to JSON: {e}'])
|
||||
|
||||
|
||||
|
||||
@@ -128,9 +136,9 @@ class app_state_class:
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# method to update the state
|
||||
def updateState(newState, settingsSaved = None, settingsImported = None, showSpinner = False):
|
||||
def updateState(newState, settingsSaved = None, settingsImported = None, showSpinner = False, graphQLServerStarted = None):
|
||||
|
||||
state = app_state_class(newState, settingsSaved, settingsImported, showSpinner)
|
||||
return app_state_class(newState, settingsSaved, settingsImported, showSpinner, graphQLServerStarted)
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -904,6 +912,47 @@ def extract_ip_addresses(text):
|
||||
ip_addresses = re.findall(ip_pattern, text)
|
||||
return ip_addresses
|
||||
|
||||
|
||||
def generate_random_string(length):
|
||||
characters = string.ascii_letters + string.digits
|
||||
return ''.join(random.choice(characters) for _ in range(length))
|
||||
|
||||
|
||||
# Helper function to determine if a MAC address is random
|
||||
def is_random_mac(mac):
|
||||
# Check if second character matches "2", "6", "A", "E" (case insensitive)
|
||||
is_random = mac[1].upper() in ["2", "6", "A", "E"]
|
||||
|
||||
# Check against user-defined non-random MAC prefixes
|
||||
if is_random:
|
||||
not_random_prefixes = get_setting_value("UI_NOT_RANDOM_MAC")
|
||||
for prefix in not_random_prefixes:
|
||||
if mac.startswith(prefix):
|
||||
is_random = False
|
||||
break
|
||||
return is_random
|
||||
|
||||
# Helper function to calculate number of children
|
||||
def get_number_of_children(mac, devices):
|
||||
# Count children by checking devParentMAC for each device
|
||||
return sum(1 for dev in devices if dev.get("devParentMAC", "").strip() == mac.strip())
|
||||
|
||||
|
||||
|
||||
# Function to convert IP to a long integer
|
||||
def format_ip_long(ip_address):
|
||||
try:
|
||||
# Check if it's an IPv6 address
|
||||
if ':' in ip_address:
|
||||
ip = ipaddress.IPv6Address(ip_address)
|
||||
else:
|
||||
# Assume it's an IPv4 address
|
||||
ip = ipaddress.IPv4Address(ip_address)
|
||||
return int(ip)
|
||||
except ValueError:
|
||||
# Return a default error value if IP is invalid
|
||||
return -1
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# JSON methods
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@@ -12,7 +12,7 @@ import re
|
||||
|
||||
import conf
|
||||
from const import fullConfPath, applicationPath, fullConfFolder
|
||||
from helper import collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, updateState, setting_value_to_python_type, timeNowTZ, get_setting_value
|
||||
from helper import collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, updateState, setting_value_to_python_type, timeNowTZ, get_setting_value, generate_random_string
|
||||
from logger import mylog
|
||||
from api import update_api
|
||||
from scheduler import schedule_class
|
||||
@@ -75,7 +75,7 @@ def update_or_append(settings_list, item_tuple, key):
|
||||
for index, item in enumerate(settings_list):
|
||||
if item[0] == key:
|
||||
mylog('trace', ['[Import Config] OLD TUPLE : ', item])
|
||||
# Keep values marked as "_KEEP_"
|
||||
# Keep values marked as "_KEEP_" in existing entries
|
||||
updated_tuple = tuple(
|
||||
new_val if new_val != "_KEEP_" else old_val
|
||||
for old_val, new_val in zip(item, item_tuple)
|
||||
@@ -84,12 +84,15 @@ def update_or_append(settings_list, item_tuple, key):
|
||||
settings_list[index] = updated_tuple
|
||||
mylog('trace', ['[Import Config] FOUND key : ', key])
|
||||
return settings_list
|
||||
|
||||
|
||||
settings_list.append(item_tuple)
|
||||
# Append the item only if no values are "_KEEP_"
|
||||
if "_KEEP_" not in item_tuple:
|
||||
settings_list.append(item_tuple)
|
||||
mylog('trace', ['[Import Config] ADDED key : ', key])
|
||||
else:
|
||||
mylog('none', ['[Import Config] Skipped saving _KEEP_ for key : ', key])
|
||||
|
||||
return settings_list
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@@ -148,12 +151,14 @@ def importConfigs (db, all_plugins):
|
||||
conf.HRS_TO_KEEP_NEWDEV = ccd('HRS_TO_KEEP_NEWDEV', 0 , c_d, 'Keep new devices for', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
|
||||
conf.HRS_TO_KEEP_OFFDEV = ccd('HRS_TO_KEEP_OFFDEV', 0 , c_d, 'Keep offline devices for', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
|
||||
conf.CLEAR_NEW_FLAG = ccd('CLEAR_NEW_FLAG', 0 , c_d, 'Clear new flag', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'General')
|
||||
conf.API_CUSTOM_SQL = ccd('API_CUSTOM_SQL', 'SELECT * FROM Devices WHERE dev_PresentLastScan = 0' , c_d, 'Custom endpoint', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General')
|
||||
conf.API_CUSTOM_SQL = ccd('API_CUSTOM_SQL', 'SELECT * FROM Devices WHERE devPresentLastScan = 0' , c_d, 'Custom endpoint', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General')
|
||||
conf.VERSION = ccd('VERSION', '' , c_d, 'Version', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [{ "readonly": "true" }] ,"transformers": []}]}', '', 'General')
|
||||
conf.NETWORK_DEVICE_TYPES = ccd('NETWORK_DEVICE_TYPES', ['AP', 'Gateway', 'Firewall', 'Hypervisor', 'Powerline', 'Switch', 'WLAN', 'PLC', 'Router','USB LAN Adapter', 'USB WIFI Adapter', 'Internet'] , c_d, 'Network device types', '{"dataType":"array","elements":[{"elementType":"input","elementOptions":[{"placeholder":"Enter value"},{"suffix":"_in"},{"cssClasses":"col-sm-10"},{"prefillValue":"null"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":["_in"]},{"separator":""},{"cssClasses":"col-xs-12"},{"onClick":"addList(this,false)"},{"getStringKey":"Gen_Add"}],"transformers":[]},{"elementType":"select", "elementHasInputValue":1,"elementOptions":[{"multiple":"true"},{"readonly":"true"},{"editable":"true"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":[]},{"separator":""},{"cssClasses":"col-xs-6"},{"onClick":"removeAllOptions(this)"},{"getStringKey":"Gen_Remove_All"}],"transformers":[]},{"elementType":"button","elementOptions":[{"sourceSuffixes":[]},{"separator":""},{"cssClasses":"col-xs-6"},{"onClick":"removeFromList(this)"},{"getStringKey":"Gen_Remove_Last"}],"transformers":[]}]}', '[]', 'General')
|
||||
conf.GRAPHQL_PORT = ccd('GRAPHQL_PORT', 20212 , c_d, 'GraphQL port', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', '[]', 'General')
|
||||
conf.API_TOKEN = ccd('API_TOKEN', 't_' + generate_random_string(20) , c_d, 'API token', '{"dataType": "string","elements": [{"elementType": "input","elementHasInputValue": 1,"elementOptions": [{ "cssClasses": "col-xs-12" }],"transformers": []},{"elementType": "button","elementOptions": [{ "getStringKey": "Gen_Generate" },{ "customParams": "API_TOKEN" },{ "onClick": "generateApiToken(this, 20)" },{ "cssClasses": "col-xs-12" }],"transformers": []}]}', '[]', 'General')
|
||||
|
||||
# UI
|
||||
conf.UI_LANG = ccd('UI_LANG', 'English' , c_d, 'Language Interface', '{"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}', "['English', 'French', 'German', 'Norwegian', 'Russian', 'Spanish', 'Italian (it_it)', 'Portuguese (pt_br)', 'Polish (pl_pl)', 'Turkish (tr_tr)', 'Chinese (zh_cn)', 'Czech (cs_cz)' ]", 'UI')
|
||||
conf.UI_LANG = ccd('UI_LANG', 'English' , c_d, 'Language Interface', '{"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}', "['English', 'German', 'Spanish', 'French', 'Norwegian', 'Russian', 'Italian (it_it)', 'Portuguese (pt_br)', 'Polish (pl_pl)', 'Chinese (zh_cn)', 'Turkish (tr_tr)', 'Czech (cs_cz)', 'Arabic (ar_ar)', 'Catalan (ca_ca)' ]", 'UI')
|
||||
|
||||
# Init timezone in case it changed
|
||||
conf.tz = timezone(conf.TIMEZONE)
|
||||
@@ -319,7 +324,7 @@ def importConfigs (db, all_plugins):
|
||||
|
||||
# Log the value being passed
|
||||
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
|
||||
mylog('debug', [f"[Config] Setting override {setting_name} with value: {value}"])
|
||||
mylog('verbose', [f"[Config] Setting override {setting_name} with value: {value}"])
|
||||
ccd(setting_name, value, c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True, 1)
|
||||
|
||||
except json.JSONDecodeError:
|
||||
@@ -369,7 +374,12 @@ def importConfigs (db, all_plugins):
|
||||
# Used to determine the next import
|
||||
conf.lastImportedConfFile = os.path.getmtime(config_file)
|
||||
|
||||
updateState("Config imported", conf.lastImportedConfFile, conf.lastImportedConfFile, False)
|
||||
# updateState(newState (text),
|
||||
# settingsSaved = None (timestamp),
|
||||
# settingsImported = None (timestamp),
|
||||
# showSpinner = False (1/0),
|
||||
# graphQLServerStarted = 1 (1/0))
|
||||
updateState("Config imported", conf.lastImportedConfFile, conf.lastImportedConfFile, False, 1)
|
||||
|
||||
msg = '[Config] Imported new settings config'
|
||||
mylog('minimal', msg)
|
||||
@@ -399,21 +409,51 @@ def read_config_file(filename):
|
||||
# 🤔Idea/TODO: Check and compare versions/timestamps amd only perform a replacement if config/version older than...
|
||||
replacements = {
|
||||
r'\bREPORT_TO\b': 'SMTP_REPORT_TO',
|
||||
r'\bSYNC_api_token\b': 'API_TOKEN',
|
||||
r'\bAPI_TOKEN=\'\'': f'API_TOKEN=\'t_{generate_random_string(20)}\'',
|
||||
r'\bREPORT_FROM\b': 'SMTP_REPORT_FROM',
|
||||
r'\bPIALERT_WEB_PROTECTION\b': 'SETPWD_enable_password',
|
||||
r'\bPIALERT_WEB_PASSWORD\b': 'SETPWD_password',
|
||||
r'REPORT_MAIL=True': 'SMTP_RUN=\'on_notification\'',
|
||||
r'REPORT_APPRISE=True': 'APPRISE_RUN=\'on_notification\'',
|
||||
r'REPORT_NTFY=True': 'NTFY_RUN=\'on_notification\'',
|
||||
r'REPORT_WEBHOOK=True': 'WEBHOOK_RUN=\'on_notification\'',
|
||||
r'REPORT_PUSHSAFER=True': 'PUSHSAFER_RUN=\'on_notification\'',
|
||||
r'REPORT_MQTT=True': 'MQTT_RUN=\'on_notification\'',
|
||||
r'REPORT_MAIL=True': "SMTP_RUN='on_notification'",
|
||||
r'REPORT_APPRISE=True': "APPRISE_RUN='on_notification'",
|
||||
r'REPORT_NTFY=True': "NTFY_RUN='on_notification'",
|
||||
r'REPORT_WEBHOOK=True': "WEBHOOK_RUN='on_notification'",
|
||||
r'REPORT_PUSHSAFER=True': "PUSHSAFER_RUN='on_notification'",
|
||||
r'REPORT_MQTT=True': "MQTT_RUN='on_notification'",
|
||||
r'PIHOLE_CMD=': 'PIHOLE_CMD_OLD=',
|
||||
r'\bINCLUDED_SECTIONS\b': 'NTFPRCS_INCLUDED_SECTIONS',
|
||||
r'\bDIG_GET_IP_ARG\b': 'INTRNT_DIG_GET_IP_ARG',
|
||||
r'\/home/pi/pialert\b': '/app'
|
||||
r'dev_MAC': 'devMac',
|
||||
r'dev_Name': 'devName',
|
||||
r'dev_Favorite': 'devFavorite',
|
||||
r'dev_Group': 'devGroup',
|
||||
r'dev_Comments': 'devComments',
|
||||
r'dev_FirstConnection': 'devFirstConnection',
|
||||
r'dev_LastConnection': 'devLastConnection',
|
||||
r'dev_LastIP': 'devLastIP',
|
||||
r'dev_StaticIP': 'devStaticIP',
|
||||
r'dev_ScanCycle': 'devScan',
|
||||
r'dev_LogEvents': 'devLogEvents',
|
||||
r'dev_AlertEvents': 'devAlertEvents',
|
||||
r'dev_AlertDeviceDown': 'devAlertDown',
|
||||
r'dev_SkipRepeated': 'devSkipRepeated',
|
||||
r'dev_LastNotification': 'devLastNotification',
|
||||
r'dev_PresentLastScan': 'devPresentLastScan',
|
||||
r'dev_NewDevice': 'devIsNew',
|
||||
r'dev_Location': 'devLocation',
|
||||
r'dev_Archived': 'devIsArchived',
|
||||
r'dev_Network_Node_MAC_ADDR': 'devParentMAC',
|
||||
r'dev_Network_Node_port': 'devParentPort',
|
||||
r'dev_Icon': 'devIcon',
|
||||
r'dev_GUID': 'devGUID',
|
||||
r'dev_NetworkSite': 'devSite',
|
||||
r'dev_SSID': 'devSSID',
|
||||
r'dev_SyncHubNodeName': 'devSyncHubNode',
|
||||
r'dev_SourcePlugin': 'devSourcePlugin',
|
||||
r'/home/pi/pialert\b': '/app'
|
||||
}
|
||||
|
||||
|
||||
def renameSettings(config_file):
|
||||
# Check if the file contains any of the old setting code names
|
||||
contains_old_settings = False
|
||||
|
||||
132
server/logger.py
@@ -1,13 +1,11 @@
|
||||
""" Colection of functions to support all logging for NetAlertX """
|
||||
import sys
|
||||
import io
|
||||
import datetime
|
||||
import threading
|
||||
import queue
|
||||
import time
|
||||
|
||||
import conf
|
||||
from const import *
|
||||
# from helper import get_setting_value
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# duplication from helper to avoid circle
|
||||
@@ -18,17 +16,15 @@ def timeNowTZ():
|
||||
else:
|
||||
return datetime.datetime.now().replace(microsecond=0)
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# More verbose as the numbers go up
|
||||
debugLevels = [
|
||||
('none', 0), ('minimal', 1), ('verbose', 2), ('debug', 3), ('trace', 4)
|
||||
]
|
||||
debugLevels = [
|
||||
('none', 0), ('minimal', 1), ('verbose', 2), ('debug', 3), ('trace', 4)
|
||||
]
|
||||
|
||||
currentLevel = 0
|
||||
|
||||
def mylog(requestedDebugLevel, n):
|
||||
|
||||
setLvl = 0
|
||||
reqLvl = 0
|
||||
|
||||
@@ -43,100 +39,86 @@ def mylog(requestedDebugLevel, n):
|
||||
file_print (*n)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def file_print (*args):
|
||||
# Queue for log messages
|
||||
log_queue = queue.Queue()
|
||||
|
||||
result = timeNowTZ().strftime ('%H:%M:%S') + ' '
|
||||
|
||||
# Dedicated thread for writing logs
|
||||
log_thread = None # Will hold the thread reference
|
||||
|
||||
def log_writer():
|
||||
while True:
|
||||
log_entry = log_queue.get()
|
||||
if log_entry is None: # Graceful exit signal
|
||||
break
|
||||
with open(logPath + "/app.log", 'a') as log_file:
|
||||
log_file.write(log_entry + '\n')
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Function to start the log writer thread if it doesn't exist
|
||||
def start_log_writer_thread():
|
||||
global log_thread
|
||||
if log_thread is None or not log_thread.is_alive():
|
||||
print("Starting log writer thread...")
|
||||
log_thread = threading.Thread(target=log_writer, args=(), daemon=True)
|
||||
log_thread.start()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def file_print(*args):
|
||||
result = timeNowTZ().strftime('%H:%M:%S') + ' '
|
||||
|
||||
for arg in args:
|
||||
result += str(arg)
|
||||
print(result)
|
||||
|
||||
append_to_file_with_timeout(logPath + "/app.log", result + '\n', 5)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Function to append to the file
|
||||
def append_to_file(file_path, data):
|
||||
try:
|
||||
# Open the file for appending
|
||||
file = open(file_path, "a")
|
||||
|
||||
# Write the data to the file
|
||||
file.write(data)
|
||||
|
||||
# Close the file
|
||||
file.close()
|
||||
except Exception as e:
|
||||
print(f"Error appending to file: {e}")
|
||||
# Ensure the log writer thread is running
|
||||
start_log_writer_thread()
|
||||
|
||||
# Queue the log entry for writing
|
||||
append_to_file_with_timeout( result, 5)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Function to append to the file with a timeout
|
||||
def append_to_file_with_timeout(file_path, data, timeout):
|
||||
# Create a thread for appending to the file
|
||||
append_thread = threading.Thread(target=append_to_file, args=(file_path, data))
|
||||
|
||||
# Start the thread
|
||||
append_thread.start()
|
||||
|
||||
# Wait for the thread to complete or timeout
|
||||
append_thread.join(timeout)
|
||||
|
||||
# If the thread is still running, it has exceeded the timeout
|
||||
if append_thread.is_alive():
|
||||
append_thread.join() # Optionally, you can force it to terminate
|
||||
|
||||
# Handle the timeout here, e.g., log an error
|
||||
def append_to_file_with_timeout(data, timeout):
|
||||
try:
|
||||
log_queue.put(data, timeout=timeout)
|
||||
except queue.Full:
|
||||
print("Appending to file timed out")
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def print_log (pText):
|
||||
|
||||
# Check LOG actived
|
||||
if not conf.LOG_LEVEL == 'debug' :
|
||||
def print_log(pText):
|
||||
# Check if logging is active
|
||||
if not conf.LOG_LEVEL == 'debug':
|
||||
return
|
||||
|
||||
# Current Time
|
||||
log_timestamp2 = datetime.datetime.now(conf.tz).replace(microsecond=0)
|
||||
|
||||
# Print line + time + elapsed time + text
|
||||
file_print ('[LOG_LEVEL=debug] ',
|
||||
# log_timestamp2, ' ',
|
||||
log_timestamp2.strftime ('%H:%M:%S'), ' ',
|
||||
pText)
|
||||
|
||||
|
||||
# Print line + time + text
|
||||
file_print('[LOG_LEVEL=debug]', log_timestamp2.strftime('%H:%M:%S'), pText)
|
||||
return pText
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# textchars = bytearray({7,8,9,10,12,13,27} | set(range(0x20, 0x100)) - {0x7f})
|
||||
# is_binary_string = lambda bytes: bool(bytes.translate(None, textchars))
|
||||
|
||||
def append_file_binary(file_path, input_data):
|
||||
with open(file_path, 'ab') as file:
|
||||
if isinstance(input_data, str):
|
||||
input_data = input_data.encode('utf-8') # Encode string as bytes
|
||||
file.write(input_data)
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def logResult(stdout, stderr):
|
||||
if stderr is not None:
|
||||
append_file_binary(logPath + '/stderr.log', stderr)
|
||||
if stdout is not None:
|
||||
append_file_binary(logPath + '/stdout.log', stdout)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def logResult (stdout, stderr):
|
||||
if stderr != None:
|
||||
append_file_binary (logPath + '/stderr.log', stderr)
|
||||
if stdout != None:
|
||||
append_file_binary (logPath + '/stdout.log', stdout)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def append_line_to_file (pPath, pText):
|
||||
# append the line depending using the correct python version
|
||||
def append_line_to_file(pPath, pText):
|
||||
# append the line using the correct python version
|
||||
if sys.version_info < (3, 0):
|
||||
file = io.open (pPath , mode='a', encoding='utf-8')
|
||||
file.write ( pText.decode('unicode_escape') )
|
||||
file = io.open(pPath, mode='a', encoding='utf-8')
|
||||
file.write(pText.decode('unicode_escape'))
|
||||
file.close()
|
||||
else:
|
||||
file = open (pPath, 'a', encoding='utf-8')
|
||||
file.write (pText)
|
||||
file.close()
|
||||
file = open(pPath, 'a', encoding='utf-8')
|
||||
file.write(pText)
|
||||
file.close()
|
||||
|
||||
@@ -85,7 +85,7 @@ def void_ghost_disconnections (db):
|
||||
AND eve_MAC IN (
|
||||
SELECT Events.eve_MAC
|
||||
FROM CurrentScan, Devices, Events
|
||||
WHERE dev_MAC = cur_MAC
|
||||
WHERE devMac = cur_MAC
|
||||
AND eve_MAC = cur_MAC
|
||||
AND eve_EventType = 'Disconnected'
|
||||
AND eve_DateTime >= DATETIME(?, '-3 minutes')
|
||||
@@ -99,7 +99,7 @@ def void_ghost_disconnections (db):
|
||||
AND eve_PairEventRowid IN (
|
||||
SELECT Events.RowID
|
||||
FROM CurrentScan, Devices, Events
|
||||
WHERE dev_MAC = cur_MAC
|
||||
WHERE devMac = cur_MAC
|
||||
AND eve_MAC = cur_MAC
|
||||
AND eve_EventType = 'Disconnected'
|
||||
AND eve_DateTime >= DATETIME(?, '-3 minutes')
|
||||
@@ -114,7 +114,7 @@ def void_ghost_disconnections (db):
|
||||
AND ROWID IN (
|
||||
SELECT Events.RowID
|
||||
FROM CurrentScan, Devices, Events
|
||||
WHERE dev_MAC = cur_MAC
|
||||
WHERE devMac = cur_MAC
|
||||
AND eve_MAC = cur_MAC
|
||||
AND eve_EventType = 'Disconnected'
|
||||
AND eve_DateTime >= DATETIME(?, '-3 minutes')
|
||||
@@ -186,12 +186,12 @@ def insert_events (db):
|
||||
sql.execute (f"""INSERT INTO Events (eve_MAC, eve_IP, eve_DateTime,
|
||||
eve_EventType, eve_AdditionalInfo,
|
||||
eve_PendingAlertEmail)
|
||||
SELECT dev_MAC, dev_LastIP, '{startTime}', 'Device Down', '', 1
|
||||
SELECT devMac, devLastIP, '{startTime}', 'Device Down', '', 1
|
||||
FROM Devices
|
||||
WHERE dev_AlertDeviceDown != 0
|
||||
AND dev_PresentLastScan = 1
|
||||
WHERE devAlertDown != 0
|
||||
AND devPresentLastScan = 1
|
||||
AND NOT EXISTS (SELECT 1 FROM CurrentScan
|
||||
WHERE dev_MAC = cur_MAC
|
||||
WHERE devMac = cur_MAC
|
||||
) """)
|
||||
|
||||
# Check new Connections or Down Reconnections
|
||||
@@ -208,7 +208,7 @@ def insert_events (db):
|
||||
1
|
||||
FROM CurrentScan AS c
|
||||
LEFT JOIN LatestEventsPerMAC AS last_event ON c.cur_MAC = last_event.eve_MAC
|
||||
WHERE last_event.dev_PresentLastScan = 0 OR last_event.eve_MAC IS NULL
|
||||
WHERE last_event.devPresentLastScan = 0 OR last_event.eve_MAC IS NULL
|
||||
""")
|
||||
|
||||
# Check disconnections
|
||||
@@ -216,13 +216,13 @@ def insert_events (db):
|
||||
sql.execute (f"""INSERT INTO Events (eve_MAC, eve_IP, eve_DateTime,
|
||||
eve_EventType, eve_AdditionalInfo,
|
||||
eve_PendingAlertEmail)
|
||||
SELECT dev_MAC, dev_LastIP, '{startTime}', 'Disconnected', '',
|
||||
dev_AlertEvents
|
||||
SELECT devMac, devLastIP, '{startTime}', 'Disconnected', '',
|
||||
devAlertEvents
|
||||
FROM Devices
|
||||
WHERE dev_AlertDeviceDown = 0
|
||||
AND dev_PresentLastScan = 1
|
||||
WHERE devAlertDown = 0
|
||||
AND devPresentLastScan = 1
|
||||
AND NOT EXISTS (SELECT 1 FROM CurrentScan
|
||||
WHERE dev_MAC = cur_MAC
|
||||
WHERE devMac = cur_MAC
|
||||
) """)
|
||||
|
||||
# Check IP Changed
|
||||
@@ -231,10 +231,10 @@ def insert_events (db):
|
||||
eve_EventType, eve_AdditionalInfo,
|
||||
eve_PendingAlertEmail)
|
||||
SELECT cur_MAC, cur_IP, '{startTime}', 'IP Changed',
|
||||
'Previous IP: '|| dev_LastIP, dev_AlertEvents
|
||||
'Previous IP: '|| devLastIP, devAlertEvents
|
||||
FROM Devices, CurrentScan
|
||||
WHERE dev_MAC = cur_MAC
|
||||
AND dev_LastIP <> cur_IP """ )
|
||||
WHERE devMac = cur_MAC
|
||||
AND devLastIP <> cur_IP """ )
|
||||
mylog('debug','[Events] - Events end')
|
||||
|
||||
|
||||
@@ -248,9 +248,9 @@ def insertOnlineHistory(db):
|
||||
query = """
|
||||
SELECT
|
||||
COUNT(*) AS allDevics,
|
||||
SUM(CASE WHEN dev_Archived = 1 THEN 1 ELSE 0 END) AS archivedDevices,
|
||||
SUM(CASE WHEN dev_PresentLastScan = 1 THEN 1 ELSE 0 END) AS onlineDevices,
|
||||
SUM(CASE WHEN dev_PresentLastScan = 0 AND dev_AlertDeviceDown = 1 THEN 1 ELSE 0 END) AS downDevices
|
||||
SUM(CASE WHEN devIsArchived = 1 THEN 1 ELSE 0 END) AS archivedDevices,
|
||||
SUM(CASE WHEN devPresentLastScan = 1 THEN 1 ELSE 0 END) AS onlineDevices,
|
||||
SUM(CASE WHEN devPresentLastScan = 0 AND devAlertDown = 1 THEN 1 ELSE 0 END) AS downDevices
|
||||
FROM Devices
|
||||
"""
|
||||
|
||||
|
||||
@@ -246,8 +246,8 @@ class Notification_obj:
|
||||
def clearPendingEmailFlag(self):
|
||||
|
||||
# Clean Pending Alert Events
|
||||
self.db.sql.execute ("""UPDATE Devices SET dev_LastNotification = ?
|
||||
WHERE dev_MAC IN (
|
||||
self.db.sql.execute ("""UPDATE Devices SET devLastNotification = ?
|
||||
WHERE devMac IN (
|
||||
SELECT eve_MAC FROM Events
|
||||
WHERE eve_PendingAlertEmail = 1
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import json
|
||||
import subprocess
|
||||
import datetime
|
||||
import base64
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -145,6 +146,18 @@ def run_plugin_scripts(db, all_plugins, runType, pluginsState = plugins_state())
|
||||
|
||||
|
||||
|
||||
# Function to run a plugin command
|
||||
def run_plugin(command, set_RUN_TIMEOUT):
|
||||
try:
|
||||
return subprocess.check_output(command, universal_newlines=True, stderr=subprocess.STDOUT, timeout=set_RUN_TIMEOUT)
|
||||
except subprocess.CalledProcessError as e:
|
||||
mylog('none', [e.output])
|
||||
mylog('none', ['[Plugins] ⚠ ERROR - enable LOG_LEVEL=debug and check logs'])
|
||||
return None
|
||||
except subprocess.TimeoutExpired as timeErr:
|
||||
mylog('none', [f'[Plugins] ⚠ ERROR - TIMEOUT - the plugin {plugin["unique_prefix"]} forcefully terminated as timeout reached. Increase TIMEOUT setting and scan interval.'])
|
||||
return None
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Executes the plugin command specified in the setting with the function specified as CMD
|
||||
@@ -209,15 +222,14 @@ def execute_plugin(db, all_plugins, plugin, pluginsState = plugins_state() ):
|
||||
mylog('verbose', ['[Plugins] Executing: ', set_CMD])
|
||||
mylog('debug', ['[Plugins] Resolved : ', command])
|
||||
|
||||
try:
|
||||
# try running a subprocess with a forced timeout in case the subprocess hangs
|
||||
output = subprocess.check_output(command, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(set_RUN_TIMEOUT))
|
||||
except subprocess.CalledProcessError as e:
|
||||
# An error occurred, handle it
|
||||
mylog('none', [e.output])
|
||||
mylog('none', ['[Plugins] ⚠ ERROR - enable LOG_LEVEL=debug and check logs'])
|
||||
except subprocess.TimeoutExpired as timeErr:
|
||||
mylog('none', [f'[Plugins] ⚠ ERROR - TIMEOUT - the plugin {plugin["unique_prefix"]} forcefully terminated as timeout reached. Increase TIMEOUT setting and scan interval.'])
|
||||
# Using ThreadPoolExecutor to handle concurrent subprocesses
|
||||
with ThreadPoolExecutor(max_workers=5) as executor:
|
||||
futures = [executor.submit(run_plugin, command, set_RUN_TIMEOUT)] # Submit the command as a future
|
||||
|
||||
for future in as_completed(futures):
|
||||
output = future.result() # Get the output or error
|
||||
if output is not None:
|
||||
mylog('verbose', [f'[Plugins] Output: {output}'])
|
||||
|
||||
# Initialize newLines
|
||||
newLines = []
|
||||
|
||||
@@ -48,12 +48,12 @@ def get_notifications (db):
|
||||
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
|
||||
WHERE eve_PendingAlertEmail = 1 AND eve_EventType not in ('Device Down', 'Down Reconnected', 'New Device' ) AND eve_MAC IN
|
||||
(
|
||||
SELECT dev_MAC FROM Devices WHERE dev_AlertEvents = 0
|
||||
SELECT devMac FROM Devices WHERE devAlertEvents = 0
|
||||
)""")
|
||||
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
|
||||
WHERE eve_PendingAlertEmail = 1 AND eve_EventType in ('Device Down', 'Down Reconnected') AND eve_MAC IN
|
||||
(
|
||||
SELECT dev_MAC FROM Devices WHERE dev_AlertDeviceDown = 0
|
||||
SELECT devMac FROM Devices WHERE devAlertDown = 0
|
||||
)""")
|
||||
|
||||
sections = get_setting_value('NTFPRCS_INCLUDED_SECTIONS')
|
||||
@@ -62,7 +62,7 @@ def get_notifications (db):
|
||||
|
||||
if 'new_devices' in sections:
|
||||
# Compose New Devices Section (no empty lines in SQL queries!)
|
||||
sqlQuery = f"""SELECT eve_MAC as MAC, eve_DateTime as Datetime, dev_LastIP as IP, eve_EventType as "Event Type", dev_Name as "Device name", dev_Comments as Comments FROM Events_Devices
|
||||
sqlQuery = f"""SELECT eve_MAC as MAC, eve_DateTime as Datetime, devLastIP as IP, eve_EventType as "Event Type", devName as "Device name", devComments as Comments FROM Events_Devices
|
||||
WHERE eve_PendingAlertEmail = 1
|
||||
AND eve_EventType = 'New Device' {get_setting_value('NTFPRCS_new_dev_condition').replace('{s-quote}',"'")}
|
||||
ORDER BY eve_DateTime"""
|
||||
@@ -83,7 +83,7 @@ def get_notifications (db):
|
||||
# Compose Devices Down Section
|
||||
# - select only Down Alerts with pending email of devices that didn't reconnect within the specified time window
|
||||
sqlQuery = f"""
|
||||
SELECT dev_Name, eve_MAC, dev_Vendor, eve_IP, eve_DateTime, eve_EventType
|
||||
SELECT devName, eve_MAC, devVendor, eve_IP, eve_DateTime, eve_EventType
|
||||
FROM Events_Devices AS down_events
|
||||
WHERE eve_PendingAlertEmail = 1
|
||||
AND down_events.eve_EventType = 'Device Down'
|
||||
@@ -113,7 +113,7 @@ def get_notifications (db):
|
||||
# Compose Reconnected Down Section
|
||||
# - select only Devices, that were previously down and now are Connected
|
||||
sqlQuery = f"""
|
||||
SELECT dev_Name, eve_MAC, dev_Vendor, eve_IP, eve_DateTime, eve_EventType
|
||||
SELECT devName, eve_MAC, devVendor, eve_IP, eve_DateTime, eve_EventType
|
||||
FROM Events_Devices AS reconnected_devices
|
||||
WHERE reconnected_devices.eve_EventType = 'Down Reconnected'
|
||||
AND reconnected_devices.eve_PendingAlertEmail = 1
|
||||
@@ -133,7 +133,7 @@ def get_notifications (db):
|
||||
|
||||
if 'events' in sections:
|
||||
# Compose Events Section (no empty lines in SQL queries!)
|
||||
sqlQuery = f"""SELECT eve_MAC as MAC, eve_DateTime as Datetime, dev_LastIP as IP, eve_EventType as "Event Type", dev_Name as "Device name", dev_Comments as Comments FROM Events_Devices
|
||||
sqlQuery = f"""SELECT eve_MAC as MAC, eve_DateTime as Datetime, devLastIP as IP, eve_EventType as "Event Type", devName as "Device name", devComments as Comments FROM Events_Devices
|
||||
WHERE eve_PendingAlertEmail = 1
|
||||
AND eve_EventType IN ('Connected', 'Down Reconnected', 'Disconnected','IP Changed') {get_setting_value('NTFPRCS_event_condition').replace('{s-quote}',"'")}
|
||||
ORDER BY eve_DateTime"""
|
||||
@@ -190,11 +190,11 @@ def skip_repeated_notifications (db):
|
||||
db.sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
|
||||
WHERE eve_PendingAlertEmail = 1 AND eve_MAC IN
|
||||
(
|
||||
SELECT dev_MAC FROM Devices
|
||||
WHERE dev_LastNotification IS NOT NULL
|
||||
AND dev_LastNotification <>""
|
||||
AND (strftime("%s", dev_LastNotification)/60 +
|
||||
dev_SkipRepeated * 60) >
|
||||
SELECT devMac FROM Devices
|
||||
WHERE devLastNotification IS NOT NULL
|
||||
AND devLastNotification <>""
|
||||
AND (strftime("%s", devLastNotification)/60 +
|
||||
devSkipRepeated * 60) >
|
||||
(strftime('%s','now','localtime')/60 )
|
||||
)
|
||||
""" )
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import sys
|
||||
import pathlib
|
||||
import sqlite3
|
||||
import random
|
||||
import string
|
||||
import uuid
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
sys.path.append(str(pathlib.Path(__file__).parent.parent.resolve()) + "/server/")
|
||||
|
||||
|
||||
import datetime
|
||||
|
||||
from helper import timeNowTZ, updateSubnets
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
def test_helper():
|
||||
assert timeNow() == datetime.datetime.now().replace(microsecond=0)
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
def test_updateSubnets():
|
||||
# test single subnet
|
||||
@@ -22,8 +22,162 @@ def test_updateSubnets():
|
||||
assert type(result) is list
|
||||
assert len(result) == 1
|
||||
|
||||
# test multip subnets
|
||||
# test multiple subnets
|
||||
subnet = ["192.168.1.0/24 --interface=eth0", "192.168.2.0/24 --interface=eth1"]
|
||||
result = updateSubnets(subnet)
|
||||
assert type(result) is list
|
||||
assert len(result) == 2
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
# Function to insert 10,000 random device entries
|
||||
def insert_devices(db_path, num_entries=1):
|
||||
conn = sqlite3.connect(db_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
print(f"{num_entries} entries to generate.")
|
||||
|
||||
# Function to generate a random MAC address
|
||||
def generate_mac():
|
||||
return '00:1A:2B:{:02X}:{:02X}:{:02X}'.format(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
|
||||
|
||||
# Function to generate a random string of given length
|
||||
def generate_random_string(length):
|
||||
return ''.join(random.choices(string.ascii_letters + string.digits, k=length))
|
||||
|
||||
# Function to generate a random date within the last `n` days
|
||||
def generate_random_date(n_days=365):
|
||||
start_date = datetime.now() - timedelta(days=random.randint(0, n_days))
|
||||
return start_date.strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# Function to generate a GUID (Globally Unique Identifier)
|
||||
def generate_guid():
|
||||
return str(uuid.uuid4()) # Generates a unique GUID
|
||||
|
||||
# SQL query to insert a new row into Devices table
|
||||
insert_query = """
|
||||
INSERT INTO Devices (
|
||||
devMac,
|
||||
devName,
|
||||
devOwner,
|
||||
devType,
|
||||
devVendor,
|
||||
devFavorite,
|
||||
devGroup,
|
||||
devComments,
|
||||
devFirstConnection,
|
||||
devLastConnection,
|
||||
devLastIP,
|
||||
devStaticIP,
|
||||
devScan,
|
||||
devLogEvents,
|
||||
devAlertEvents,
|
||||
devAlertDown,
|
||||
devSkipRepeated,
|
||||
devLastNotification,
|
||||
devPresentLastScan,
|
||||
devIsNew,
|
||||
devLocation,
|
||||
devIsArchived,
|
||||
devParentMAC,
|
||||
devParentPort,
|
||||
devIcon,
|
||||
devGUID,
|
||||
devSite,
|
||||
devSSID,
|
||||
devSyncHubNode,
|
||||
devSourcePlugin
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
"""
|
||||
|
||||
# List of device types, vendors, groups, locations
|
||||
device_types = ['Phone', 'Laptop', 'Tablet', 'Other']
|
||||
vendors = ['Vendor A', 'Vendor B', 'Vendor C']
|
||||
groups = ['Group1', 'Group2']
|
||||
locations = ['Location A', 'Location B']
|
||||
|
||||
# Insert the specified number of rows (default is 10,000)
|
||||
for i in range(num_entries):
|
||||
dev_mac = generate_mac()
|
||||
dev_name = f'Device_{i:04d}'
|
||||
dev_owner = f'Owner_{i % 100:03d}'
|
||||
dev_type = random.choice(device_types)
|
||||
dev_vendor = random.choice(vendors)
|
||||
dev_favorite = random.choice([0, 1])
|
||||
dev_group = random.choice(groups)
|
||||
dev_comments = "" # Left as NULL
|
||||
dev_first_connection = generate_random_date(365) # Within last 365 days
|
||||
dev_last_connection = generate_random_date(30) # Within last 30 days
|
||||
dev_last_ip = f'192.168.0.{random.randint(0, 255)}'
|
||||
dev_static_ip = random.choice([0, 1])
|
||||
dev_scan = random.randint(1, 10)
|
||||
dev_log_events = random.choice([0, 1])
|
||||
dev_alert_events = random.choice([0, 1])
|
||||
dev_alert_down = random.choice([0, 1])
|
||||
dev_skip_repeated = random.randint(0, 5)
|
||||
dev_last_notification = "" # Left as NULL
|
||||
dev_present_last_scan = random.choice([0, 1])
|
||||
dev_is_new = random.choice([0, 1])
|
||||
dev_location = random.choice(locations)
|
||||
dev_is_archived = random.choice([0, 1])
|
||||
dev_parent_mac = "" # Left as NULL
|
||||
dev_parent_port = "" # Left as NULL
|
||||
dev_icon = "" # Left as NULL
|
||||
dev_guid = generate_guid() # Left as NULL
|
||||
dev_site = "" # Left as NULL
|
||||
dev_ssid = "" # Left as NULL
|
||||
dev_sync_hub_node = "" # Left as NULL
|
||||
dev_source_plugin = "" # Left as NULL
|
||||
|
||||
# Execute the insert query
|
||||
cursor.execute(insert_query, (
|
||||
dev_mac,
|
||||
dev_name,
|
||||
dev_owner,
|
||||
dev_type,
|
||||
dev_vendor,
|
||||
dev_favorite,
|
||||
dev_group,
|
||||
dev_comments,
|
||||
dev_first_connection,
|
||||
dev_last_connection,
|
||||
dev_last_ip,
|
||||
dev_static_ip,
|
||||
dev_scan,
|
||||
dev_log_events,
|
||||
dev_alert_events,
|
||||
dev_alert_down,
|
||||
dev_skip_repeated,
|
||||
dev_last_notification,
|
||||
dev_present_last_scan,
|
||||
dev_is_new,
|
||||
dev_location,
|
||||
dev_is_archived,
|
||||
dev_parent_mac,
|
||||
dev_parent_port,
|
||||
dev_icon,
|
||||
dev_guid,
|
||||
dev_site,
|
||||
dev_ssid,
|
||||
dev_sync_hub_node,
|
||||
dev_source_plugin
|
||||
))
|
||||
|
||||
# Commit after every 1000 rows to improve performance
|
||||
if i % 1000 == 0:
|
||||
conn.commit()
|
||||
|
||||
# Final commit to save all remaining data
|
||||
conn.commit()
|
||||
|
||||
# Close the database connection
|
||||
conn.close()
|
||||
|
||||
print(f"{num_entries} entries have been successfully inserted into the Devices table.")
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
if __name__ == "__main__":
|
||||
# Call insert_devices with database path and number of entries as arguments
|
||||
db_path = "/app/db/app.db"
|
||||
num_entries = int(sys.argv[1]) if len(sys.argv) > 1 else 10000
|
||||
insert_devices(db_path, num_entries)
|
||||
|
||||