Compare commits

...

113 Commits

Author SHA1 Message Date
github-actions[bot]
dcc43d1f3c [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-11 11:53:35 +00:00
github-actions[bot]
8f35bf36ff [🤖Automation] Update README with sponsors information
Some checks failed
docker / docker_dev (push) Has been cancelled
2024-09-10 11:53:40 +00:00
jokob-sk
1548168eba Lang
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-10 08:26:06 +10:00
github-actions[bot]
2e35bac6ec [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-09 11:53:47 +00:00
jokob-sk
ba348fc4c2 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-09 07:30:38 +10:00
jokob-sk
d3337e75a9 ⚙ Settings/Lang cache improvements #687 + #766 2024-09-09 07:30:33 +10:00
github-actions[bot]
9e0bc043b0 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-08 11:53:36 +00:00
jokob-sk
29fdd0b115 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-08 13:57:24 +10:00
jokob-sk
48e92a186e 🧪 Override Settings via ENV variable [experimental] #687 2024-09-08 13:57:08 +10:00
github-actions[bot]
1dcb66e972 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-07 11:53:42 +00:00
jokob-sk
fa0d6d312d Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-07 09:28:36 +10:00
jokob-sk
a19fe342e7 🚀 Better upgarde message 2024-09-07 09:28:19 +10:00
jokob-sk
c4fc68cac8 Merge pull request #759 from elraro/fix-mtscan
chore: fixed mtscan and Dockerfile
2024-09-07 09:08:49 +10:00
jokob-sk
3a050c31a7 Update feature_request.yml 2024-09-07 09:06:29 +10:00
jokob-sk
2cd406a390 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-09-07 08:38:10 +10:00
jokob-sk
b086417686 💾 Cache update for proper status color + All display #779 2024-09-07 08:38:03 +10:00
Hosted Weblate
dbecbfc85f Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-06 18:09:25 +02:00
Massimo Pissarello
3f9e4c4425 Translated using Weblate (Italian)
Currently translated at 100.0% (694 of 694 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2024-09-06 18:09:21 +02:00
Safeguard
4fd1869bde Translated using Weblate (Russian)
Currently translated at 100.0% (694 of 694 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2024-09-06 18:09:19 +02:00
github-actions[bot]
78025a376c [🤖Automation] Update README with sponsors information 2024-09-06 11:53:57 +00:00
elraro
615fd08f5b chore: changed mtscan type to device_scanner 2024-09-06 00:29:10 +02:00
elraro
4839211fe1 chore: fixed mtscan 2024-09-06 00:23:17 +02:00
jokob-sk
19aaa92fa3 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-06 07:59:38 +10:00
jokob-sk
43aa40efbb ⚙ Settings #779 2024-09-06 07:59:35 +10:00
github-actions[bot]
95f48cb70d [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-05 11:53:47 +00:00
jokob-sk
8c0da1d0df Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-05 08:09:39 +10:00
jokob-sk
b0d07a6adc ⚙ Settings #779 2024-09-05 08:09:23 +10:00
github-actions[bot]
ee23ae19f7 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-04 11:53:54 +00:00
jokob-sk
0c73e49245 Merge pull request #783 from doctorixx/main
Some checks are pending
docker / docker_dev (push) Waiting to run
Update plugins docs after add telegram publisher(and fix typo) - thanks @doctorixx !
2024-09-04 07:23:14 +10:00
github-actions[bot]
899a0c3608 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-03 11:53:53 +00:00
Doctorixx
d188b640e4 Fix ordering in tip (in plugins readme) 2024-09-03 13:47:09 +03:00
Doctorixx
a95eb45924 Update plugins list (add telegram publisher) 2024-09-03 13:45:26 +03:00
jokob-sk
f737a71939 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-03 07:51:27 +10:00
jokob-sk
9df97e0e33 📡 Upgrade -> Show message 2024-09-03 07:51:17 +10:00
github-actions[bot]
4ce7077599 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-02 11:53:50 +00:00
jokob-sk
605a33330b 📡 Upgrade -> Show message
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-02 15:53:15 +10:00
jokob-sk
9bd5ff10b4 📡 Upgrade -> Show message
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-02 09:15:49 +10:00
jokob-sk
45d3be2439 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-09-02 08:16:20 +10:00
jokob-sk
46209e3e47 Authelia #780 2024-09-02 08:16:15 +10:00
github-actions[bot]
9b9836cae2 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-01 11:53:40 +00:00
jokob-sk
89be97bfb2 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-09-01 08:27:35 +10:00
jokob-sk
3e4f64a7c6 Refactor maintenance.php 2024-09-01 08:27:17 +10:00
github-actions[bot]
50fbd6e616 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-31 11:53:55 +00:00
jokob-sk
5a96ad2304 Refactor devices.php
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-31 17:32:10 +10:00
jokob-sk
25667014fc Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-08-31 12:57:04 +10:00
jokob-sk
955472ef5c fix HRS_TO_KEEP_NEWDEV #777 2024-08-31 12:56:46 +10:00
github-actions[bot]
e32b60cafc [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-30 11:53:37 +00:00
jokob-sk
3033c617fa Merge pull request #775 from doctorixx/main
Some checks are pending
docker / docker_dev (push) Waiting to run
Add Telegram publisher by @doctorixx 🙏
2024-08-30 07:32:07 +10:00
Doctorixx
1688836b4f Add Telegram publisher 2024-08-29 16:41:59 +03:00
github-actions[bot]
f30b6b7fc1 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-29 11:53:43 +00:00
github-actions[bot]
0c5c754f38 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-28 11:53:54 +00:00
github-actions[bot]
da21ee6477 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-27 11:53:48 +00:00
github-actions[bot]
3a268add06 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-26 11:53:54 +00:00
github-actions[bot]
03b610a6ec [🤖Automation] Update README with sponsors information
Some checks failed
docker / docker_dev (push) Has been cancelled
2024-08-25 11:53:45 +00:00
github-actions[bot]
38f70fd045 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-24 11:53:46 +00:00
jokob-sk
3473fabdbf 📚 Docs + Readme
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-24 08:23:19 +10:00
jokob-sk
46186e5d3b Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-08-24 08:10:08 +10:00
jokob-sk
e0dd3ab53e 📚 Docs + Readme 2024-08-24 08:10:00 +10:00
github-actions[bot]
c385ac68f4 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-23 11:53:58 +00:00
github-actions[bot]
e1c446b0df [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-22 11:53:54 +00:00
jokob-sk
0413ac5fb4 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-22 20:02:31 +10:00
jokob-sk
01f8dc5f6b Small fixes 2024-08-22 20:02:18 +10:00
Hosted Weblate
00451a6846 Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-21 22:09:24 +02:00
Mehdi
b181e2ada6 Translated using Weblate (French)
Currently translated at 100.0% (691 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-08-21 22:09:22 +02:00
Sylvain Pichon
73a0a49934 Translated using Weblate (French)
Currently translated at 100.0% (691 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-08-21 22:09:21 +02:00
github-actions[bot]
b3ad58f5f3 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-21 11:54:00 +00:00
Hosted Weblate
03e0061b03 Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-20 21:09:31 +02:00
Sylvain Pichon
e5a63e9caa Translated using Weblate (French)
Currently translated at 99.4% (687 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-08-20 21:09:27 +02:00
github-actions[bot]
eb3a54ff1c [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-20 11:53:54 +00:00
Hosted Weblate
b3b8196b64 Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-19 18:35:04 +02:00
Sergey Karmanov
408d8cb7c5 Translated using Weblate (Russian)
Currently translated at 100.0% (691 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2024-08-19 18:35:02 +02:00
Sylvain Pichon
57d94634f1 Translated using Weblate (French)
Currently translated at 75.8% (524 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-08-19 18:35:01 +02:00
github-actions[bot]
3778dcb3ad [🤖Automation] Update README with sponsors information 2024-08-19 11:53:49 +00:00
github-actions[bot]
393a0d8168 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-18 11:53:32 +00:00
Hosted Weblate
c98c22c27d Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-18 07:09:15 +00:00
Sylvain Pichon
54ae8a7b35 Translated using Weblate (French)
Currently translated at 74.6% (516 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-08-18 07:09:12 +00:00
github-actions[bot]
a2cc2b441e [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-17 11:53:59 +00:00
jokob-sk
a3c0974e77 Merge pull request #764 from ingoratsdorf/main
Some checks are pending
docker / docker_dev (push) Waiting to run
Resolved issue with Paho V2 API
2024-08-17 12:07:29 +10:00
Ingo Ratsdorf
b7fa32f70a Resolved issue with Paho V2 API
Chnaged client creation logic to V2 API as we are already using Paho2.0. Chnaged version selection from Paho version (which should not have been a user choice) to MQTT Protocol selection, which can be v3 or v5. Most modern MQQTT brokers like Mosquitta or EMQX support v5.
2024-08-17 14:00:39 +12:00
Hosted Weblate
7fd8b039ed Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-16 23:09:21 +00:00
Sylvain Pichon
303cadc68c Translated using Weblate (French)
Currently translated at 69.3% (479 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-08-17 01:09:13 +02:00
gallegonovato
61ab586bd6 Translated using Weblate (Spanish)
Currently translated at 100.0% (691 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/es/
2024-08-17 01:09:11 +02:00
github-actions[bot]
0c64bd392b [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-16 11:53:36 +00:00
jokob-sk
fa0e07a511 Handle offlien GitHub #763
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-16 08:53:58 +10:00
jokob-sk
d699f6744e Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-08-16 08:50:02 +10:00
jokob-sk
84f0221615 Handle offlien GitHub #763 2024-08-16 08:49:44 +10:00
Hosted Weblate
2e34b1ff41 Merge branch 'origin/main' into Weblate. 2024-08-15 22:14:16 +00:00
Sylvain Pichon
8238eccb75 Translated using Weblate (French)
Currently translated at 63.5% (439 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2024-08-16 00:14:10 +02:00
jokob-sk
a6f86ee44a 🧹Logo Cleanup + cs_cz 2024-08-16 08:03:39 +10:00
jokob-sk
c9e92469a4 🧹Logo Cleanup + cs_cz 2024-08-16 08:01:39 +10:00
github-actions[bot]
87fb4a105a [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-15 11:53:54 +00:00
github-actions[bot]
6f2cf76bda [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-14 11:53:57 +00:00
github-actions[bot]
09531dc207 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-13 11:53:34 +00:00
Hosted Weblate
39d7642484 Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-13 07:09:30 +02:00
Ptsa Daniel
287facb798 Translated using Weblate (Chinese (Simplified))
Currently translated at 97.9% (677 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/zh_Hans/
2024-08-13 07:09:27 +02:00
jokob-sk
c3f91cae9e Merge pull request #761 from ingoratsdorf/main
Some checks are pending
docker / docker_dev (push) Waiting to run
Fix for MQTT device tracker adding quotes to payload - thanks so much @ingoratsdorf  🙏
2024-08-13 08:35:31 +10:00
Ingo Ratsdorf
ef9aeea2d2 Fix for MQTT device tracker adding quotes to payload 2024-08-13 07:41:12 +12:00
jokob-sk
597cd48318 Merge pull request #760 from ingoratsdorf/main
Some checks are pending
docker / docker_dev (push) Waiting to run
Fixed invalid escape sequence in MQTT publisher
2024-08-13 00:01:09 +10:00
github-actions[bot]
c78db01269 [🤖Automation] Update README with sponsors information 2024-08-12 11:53:52 +00:00
Ingo Ratsdorf
bee84cf8b2 Fixed invalid escape sequence
\s is invalid in Python3 and must be \\s now
2024-08-12 22:19:04 +12:00
elraro
ae1673c1c3 chore: fixed mtscan and Dockerfile 2024-08-11 23:55:02 +02:00
github-actions[bot]
7c080302e8 [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-11 11:54:00 +00:00
jokob-sk
cec177a912 Merge branch 'main' of https://github.com/jokob-sk/NetAlertX 2024-08-11 21:13:42 +10:00
jokob-sk
fff1f36b61 Cleanup work 2024-08-11 21:13:12 +10:00
Hosted Weblate
17d16b1bda Merge branch 'origin/main' into Weblate.
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-10 23:41:17 +00:00
Ptsa Daniel
8199e5e714 Translated using Weblate (Chinese (Simplified))
Currently translated at 8.2% (57 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/zh_Hans/
2024-08-11 01:41:13 +02:00
Ramon Martinez
5c0e9a8af8 Translated using Weblate (Portuguese (Brazil))
Currently translated at 35.4% (245 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pt_BR/
2024-08-11 01:41:12 +02:00
Ettore Atalan
6438165b14 Translated using Weblate (German)
Currently translated at 94.6% (654 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/de/
2024-08-11 01:41:12 +02:00
jokob-sk
b3d1a43261 Merge pull request #758 from elraro/fix-mtscan
Some checks are pending
docker / docker_dev (push) Waiting to run
fix: mtscan plugin - thank you @elraro 🙏
2024-08-11 08:07:40 +10:00
github-actions[bot]
4ef7f507ed [🤖Automation] Update README with sponsors information
Some checks are pending
docker / docker_dev (push) Waiting to run
2024-08-10 11:53:49 +00:00
Hosted Weblate
0e830e92ed Merge branch 'origin/main' into Weblate. 2024-08-10 13:40:07 +02:00
Ramon Martinez
552e861887 Translated using Weblate (Portuguese (Brazil))
Currently translated at 34.4% (238 of 691 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/pt_BR/
2024-08-10 13:40:05 +02:00
elraro
c88afde5f8 fix: mtscan plugin
Change the MTSCAN plugin with the correct name
2024-08-10 12:48:25 +02:00
61 changed files with 3878 additions and 2134 deletions

View File

@@ -9,20 +9,6 @@ body:
options: options:
- label: I have searched the existing open and closed issues - label: I have searched the existing open and closed issues
required: true required: true
- type: checkboxes
attributes:
label: Am I willing to test this? 🧪
description: I rely on the community to test unreleased features. If you are requesting a feature, please be willing to test it within 48h of test request. Otherwise, the feature might be pulled from the code base.
options:
- label: I will do my best to test this feature on the `netlertx-dev` image when requested within 48h and report bugs to help deliver a great user experience for everyone and not to break existing installations.
required: true
- type: checkboxes
attributes:
label: Can I help implement this? 👩‍💻👨‍💻
description: The maintainer will provide guidance and help. The implementer will read the PR guidelines https://github.com/jokob-sk/NetAlertX/tree/main/docs#-pull-requests-prs
options:
- label: "Yes"
- label: "No"
- type: textarea - type: textarea
attributes: attributes:
label: Is your feature request related to a problem? Please describe label: Is your feature request related to a problem? Please describe
@@ -50,3 +36,17 @@ body:
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations: validations:
required: true required: true
- type: checkboxes
attributes:
label: Am I willing to test this? 🧪
description: I rely on the community to test unreleased features. If you are requesting a feature, please be willing to test it within 48h of test request. Otherwise, the feature might be pulled from the code base.
options:
- label: I will do my best to test this feature on the `netlertx-dev` image when requested within 48h and report bugs to help deliver a great user experience for everyone and not to break existing installations.
required: true
- type: checkboxes
attributes:
label: Can I help implement this? 👩‍💻👨‍💻
description: The maintainer will provide guidance and help. The implementer will read the PR guidelines https://github.com/jokob-sk/NetAlertX/tree/main/docs#-pull-requests-prs
options:
- label: "Yes"
- label: "No"

View File

@@ -1,8 +1,8 @@
FROM alpine:3.20 as builder FROM alpine:3.20 AS builder
ARG INSTALL_DIR=/app ARG INSTALL_DIR=/app
ENV PYTHONUNBUFFERED 1 ENV PYTHONUNBUFFERED=1
# Install build dependencies # Install build dependencies
RUN apk add --no-cache bash python3 python3-dev gcc musl-dev libffi-dev openssl-dev \ RUN apk add --no-cache bash python3 python3-dev gcc musl-dev libffi-dev openssl-dev \
@@ -21,7 +21,7 @@ RUN pip install netifaces tplink-omada-client pycryptodome requests paho-mqtt sc
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;" && bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
# second stage # second stage
FROM alpine:3.20 as runner FROM alpine:3.20 AS runner
ARG INSTALL_DIR=/app ARG INSTALL_DIR=/app

View File

@@ -1,7 +1,7 @@
FROM debian:bookworm-slim FROM debian:bookworm-slim
# default UID and GID # default UID and GID
ENV USER=pi USER_ID=1000 USER_GID=1000 PORT=20211 ENV USER=pi USER_ID=1000 USER_GID=1000 PORT=20211
#TZ=Europe/London #TZ=Europe/London
# Todo, figure out why using a workdir instead of full paths don't work # Todo, figure out why using a workdir instead of full paths don't work
@@ -43,7 +43,7 @@ RUN phpenmod -v 8.2 sqlite3
RUN apt-get install -y python3-venv RUN apt-get install -y python3-venv
RUN python3 -m venv myenv RUN python3 -m venv myenv
RUN /bin/bash -c "source myenv/bin/activate && update-alternatives --install /usr/bin/python python /usr/bin/python3 10 && pip3 install tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython cryptography " RUN /bin/bash -c "source myenv/bin/activate && update-alternatives --install /usr/bin/python python /usr/bin/python3 10 && pip3 install tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython cryptography librouteros "
# Create a buildtimestamp.txt to later check if a new version was released # Create a buildtimestamp.txt to later check if a new version was released
RUN date +%s > ${INSTALL_DIR}/front/buildtimestamp.txt RUN date +%s > ${INSTALL_DIR}/front/buildtimestamp.txt

View File

@@ -1,12 +1,13 @@
# 💻🔍 Network scanner & notification framework [![GitHub Committed](https://img.shields.io/github/last-commit/jokob-sk/NetAlertX?color=40ba12&label=Committed&logo=GitHub&logoColor=fff&style=for-the-badge)](https://github.com/jokob-sk/NetAlertX)
[![Docker Size](https://img.shields.io/docker/image-size/jokobsk/netalertx?label=Size&logo=Docker&color=0aa8d2&logoColor=fff&style=for-the-badge)](https://hub.docker.com/r/jokobsk/netalertx)
[![Docker Pulls](https://img.shields.io/docker/pulls/jokobsk/netalertx?label=Pulls&logo=docker&color=0aa8d2&logoColor=fff&style=for-the-badge)](https://hub.docker.com/r/jokobsk/netalertx)
[![GitHub Release](https://img.shields.io/github/v/release/jokob-sk/NetAlertX?color=0aa8d2&logoColor=fff&logo=GitHub&style=for-the-badge)](https://github.com/jokob-sk/NetAlertX/releases)
[![Discord](https://img.shields.io/discord/1274490466481602755?color=0aa8d2&logoColor=fff&logo=Discord&style=for-the-badge)](https://discord.gg/UQnnHNYV)
# 🖧🔍 Network scanner & notification framework
Get visibility of what's going on on your WIFI/LAN network. Schedule scans for devices, port changes and get alerts if unknown devices or changes are found. Write your own [Plugins](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) with auto-generated UI and in-build notification system. Build out and easily maintain your network source of truth (NSoT). Get visibility of what's going on on your WIFI/LAN network. Schedule scans for devices, port changes and get alerts if unknown devices or changes are found. Write your own [Plugins](https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins#readme) with auto-generated UI and in-build notification system. Build out and easily maintain your network source of truth (NSoT).
[![GitHub Committed](https://img.shields.io/github/last-commit/jokob-sk/NetAlertX?color=40ba12&label=Committed&logo=GitHub&logoColor=fff)](https://github.com/jokob-sk/NetAlertX)
[![Docker Size](https://img.shields.io/docker/image-size/jokobsk/netalertx?label=Size&logo=Docker&color=0aa8d2&logoColor=fff)](https://hub.docker.com/r/jokobsk/netalertx)
[![Docker Pulls](https://img.shields.io/docker/pulls/jokobsk/netalertx?label=Pulls&logo=docker&color=0aa8d2&logoColor=fff)](https://hub.docker.com/r/jokobsk/netalertx)
[![GitHub Release](https://img.shields.io/github/v/release/jokob-sk/NetAlertX?color=0aa8d2&logoColor=fff&logo=GitHub)](https://github.com/jokob-sk/NetAlertX/releases)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/jokob-sk?style=social)](https://github.com/sponsors/jokob-sk)
| 🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/netalertx) | 📑 [Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) |🆕 [Release notes](https://github.com/jokob-sk/NetAlertX/releases) | 📚 [All Docs](https://github.com/jokob-sk/NetAlertX/tree/main/docs) | | 🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/netalertx) | 📑 [Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) |🆕 [Release notes](https://github.com/jokob-sk/NetAlertX/releases) | 📚 [All Docs](https://github.com/jokob-sk/NetAlertX/tree/main/docs) |
|----------------------|----------------------| ----------------------| ----------------------| |----------------------|----------------------| ----------------------| ----------------------|
@@ -64,7 +65,7 @@ Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and scree
| Docs | Link | | Docs | Link |
|-------------|-------------| |-------------|-------------|
| 📥🐳 | [Docker instructions](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) | 📥🐳 | [Docker instructions](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md)
| 📥💻 | [HW install (experimental 🧪)](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HW_INSTALL.md) | | 📥🗄️ | [HW install (experimental 🧪)](https://github.com/jokob-sk/NetAlertX/blob/main/docs/HW_INSTALL.md) |
| 📥🟧 | [Unraid App](https://unraid.net/community/apps) | | 📥🟧 | [Unraid App](https://unraid.net/community/apps) |
| 📚 | [All Documentation](https://github.com/jokob-sk/NetAlertX/blob/main/docs/README.md) (App Usage and Configuration) | | 📚 | [All Documentation](https://github.com/jokob-sk/NetAlertX/blob/main/docs/README.md) (App Usage and Configuration) |

View File

@@ -64,7 +64,9 @@ services:
# DELETE END anyone trying to use this file: comment out / delete ABOVE lines, they are only for development purposes # DELETE END anyone trying to use this file: comment out / delete ABOVE lines, they are only for development purposes
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
environment: environment:
# - APP_CONF_OVERRIDE={"SCAN_SUBNETS":"['192.168.1.0/24 --interface=eth1']","UI_dark_mode":"True"}
- TZ=${TZ} - TZ=${TZ}
- PORT=${PORT} - PORT=${PORT}
# ❗ DANGER ZONE BELOW - Setting ALWAYS_FRESH_INSTALL=true will delete the content of the /db & /config folders # ❗ DANGER ZONE BELOW - Setting ALWAYS_FRESH_INSTALL=true will delete the content of the /db & /config folders
- ALWAYS_FRESH_INSTALL=${ALWAYS_FRESH_INSTALL} - ALWAYS_FRESH_INSTALL=${ALWAYS_FRESH_INSTALL}

View File

@@ -1,10 +1,11 @@
[![GitHub Committed](https://img.shields.io/github/last-commit/jokob-sk/NetAlertX?color=40ba12&label=Committed&logo=GitHub&logoColor=fff)](https://github.com/jokob-sk/NetAlertX) [![GitHub Committed](https://img.shields.io/github/last-commit/jokob-sk/NetAlertX?color=40ba12&label=Committed&logo=GitHub&logoColor=fff&style=for-the-badge)](https://github.com/jokob-sk/NetAlertX)
[![Docker Size](https://img.shields.io/docker/image-size/jokobsk/netalertx?label=Size&logo=Docker&color=0aa8d2&logoColor=fff)](https://hub.docker.com/r/jokobsk/netalertx) [![Docker Size](https://img.shields.io/docker/image-size/jokobsk/netalertx?label=Size&logo=Docker&color=0aa8d2&logoColor=fff&style=for-the-badge)](https://hub.docker.com/r/jokobsk/netalertx)
[![Docker Pulls](https://img.shields.io/docker/pulls/jokobsk/netalertx?label=Pulls&logo=docker&color=0aa8d2&logoColor=fff)](https://hub.docker.com/r/jokobsk/netalertx) [![Docker Pulls](https://img.shields.io/docker/pulls/jokobsk/netalertx?label=Pulls&logo=docker&color=0aa8d2&logoColor=fff&style=for-the-badge)](https://hub.docker.com/r/jokobsk/netalertx)
![GitHub Release](https://img.shields.io/github/v/release/jokob-sk/NetAlertX?color=0aa8d2&logoColor=fff&logo=GitHub) [![GitHub Release](https://img.shields.io/github/v/release/jokob-sk/NetAlertX?color=0aa8d2&logoColor=fff&logo=GitHub&style=for-the-badge)](https://github.com/jokob-sk/NetAlertX/releases)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/jokob-sk?style=social)](https://github.com/sponsors/jokob-sk) [![Discord](https://img.shields.io/discord/1274490466481602755?color=0aa8d2&logoColor=fff&logo=Discord&style=for-the-badge)](https://discord.gg/UQnnHNYV)
# NetAlertX 💻🔍 Network scanner & notification framework
# NetAlertX 🖧🔍 Network scanner & notification framework
| 🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/netalertx) | 📑 [Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) |🆕 [Release notes](https://github.com/jokob-sk/NetAlertX/releases) | 📚 [All Docs](https://github.com/jokob-sk/NetAlertX/tree/main/docs) | | 🐳 [Docker hub](https://registry.hub.docker.com/r/jokobsk/netalertx) | 📑 [Docker guide](https://github.com/jokob-sk/NetAlertX/blob/main/dockerfiles/README.md) |🆕 [Release notes](https://github.com/jokob-sk/NetAlertX/releases) | 📚 [All Docs](https://github.com/jokob-sk/NetAlertX/tree/main/docs) |
|----------------------|----------------------| ----------------------| ----------------------| |----------------------|----------------------| ----------------------| ----------------------|
@@ -89,9 +90,10 @@ Use the official installation guides at first and use community content as suppl
- 📄 [How to Install NetAlertX on Your Synology NAS - Marius hosting](https://mariushosting.com/how-to-install-pi-alert-on-your-synology-nas/) (Updated frequently) - 📄 [How to Install NetAlertX on Your Synology NAS - Marius hosting](https://mariushosting.com/how-to-install-pi-alert-on-your-synology-nas/) (Updated frequently)
- 📄 [Using the PiAlert Network Security Scanner on a Raspberry Pi - PiMyLifeUp](https://pimylifeup.com/raspberry-pi-pialert/) - 📄 [Using the PiAlert Network Security Scanner on a Raspberry Pi - PiMyLifeUp](https://pimylifeup.com/raspberry-pi-pialert/)
- ▶ [How to Setup Pi.Alert on Your Synology NAS - Digital Aloha](https://www.youtube.com/watch?v=M4YhpuRFaUg) - ▶ [How to Setup Pi.Alert on Your Synology NAS - Digital Aloha](https://www.youtube.com/watch?v=M4YhpuRFaUg)
- 📄 [시놀/헤놀에서 네트워크 스캐너 Pi.Alert Docker로 설치 및 사용하기 (Korean)](https://blog.dalso.org/article/%EC%8B%9C%EB%86%80-%ED%97%A4%EB%86%80%EC%97%90%EC%84%9C-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%8A%A4%EC%BA%90%EB%84%88-pi-alert-docker%EB%A1%9C-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9) (July 2023) - 📄 [防蹭网神器,网络安全助手 | 极空间部署网络扫描和通知系统『NetAlertX』](https://blog.csdn.net/qq_63499861/article/details/141105273)
- 📄 [시놀/헤놀에서 네트워크 스캐너 Pi.Alert Docker로 설치 및 사용하기](https://blog.dalso.org/article/%EC%8B%9C%EB%86%80-%ED%97%A4%EB%86%80%EC%97%90%EC%84%9C-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%8A%A4%EC%BA%90%EB%84%88-pi-alert-docker%EB%A1%9C-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9) (July 2023)
- 📄 [网络入侵探测器Pi.Alert (Chinese)](https://codeantenna.com/a/VgUvIAjZ7J) (May 2023) - 📄 [网络入侵探测器Pi.Alert (Chinese)](https://codeantenna.com/a/VgUvIAjZ7J) (May 2023)
- ▶ [Pi.Alert auf Synology & Docker by - Jürgen Barth (German)](https://www.youtube.com/watch?v=-ouvA2UNu-A) (March 2023) - ▶ [Pi.Alert auf Synology & Docker by - Jürgen Barth](https://www.youtube.com/watch?v=-ouvA2UNu-A) (March 2023)
- ▶ [Top Docker Container for Home Server Security - VirtualizationHowto](https://www.youtube.com/watch?v=tY-w-enLF6Q) (March 2023) - ▶ [Top Docker Container for Home Server Security - VirtualizationHowto](https://www.youtube.com/watch?v=tY-w-enLF6Q) (March 2023)
- ▶ [Pi.Alert or WatchYourLAN can alert you to unknown devices appearing on your WiFi or LAN network - Danie van der Merwe](https://www.youtube.com/watch?v=v6an9QG2xF0) (November 2022) - ▶ [Pi.Alert or WatchYourLAN can alert you to unknown devices appearing on your WiFi or LAN network - Danie van der Merwe](https://www.youtube.com/watch?v=v6an9QG2xF0) (November 2022)

View File

@@ -41,6 +41,16 @@ if [ "$ALWAYS_FRESH_INSTALL" = true ]; then
rm -rf "$INSTALL_DIR_OLD/db/"* rm -rf "$INSTALL_DIR_OLD/db/"*
fi fi
# OVERRIDE settings: Handling APP_CONF_OVERRIDE
# Check if APP_CONF_OVERRIDE is set
if [ -z "$APP_CONF_OVERRIDE" ]; then
echo "APP_CONF_OVERRIDE is not set. Skipping config file creation."
else
# Save the APP_CONF_OVERRIDE env variable as a JSON file
echo "$APP_CONF_OVERRIDE" > "${INSTALL_DIR}/config/app_conf_override.json"
echo "Config file saved to ${INSTALL_DIR}/config/app_conf_override.json"
fi
# 🔻 FOR BACKWARD COMPATIBILITY - REMOVE AFTER 12/12/2024 # 🔻 FOR BACKWARD COMPATIBILITY - REMOVE AFTER 12/12/2024
# Check if pialert.db exists, then create a symbolic link to app.db # Check if pialert.db exists, then create a symbolic link to app.db

View File

@@ -11,7 +11,7 @@ There are 3 artifacts that can be used to backup the application:
| `/config/app.conf` | Configuration file | Doesn't contain settings from the Maintenance section | | `/config/app.conf` | Configuration file | Doesn't contain settings from the Maintenance section |
| `/config/devices.csv` | CSV file containing device information | Doesn't contain historical data | | `/config/devices.csv` | CSV file containing device information | Doesn't contain historical data |
## Data and cackup storage ## Data and backup storage
To decide on a backup strategy, check where the data is stored: To decide on a backup strategy, check where the data is stored:

View File

@@ -17,7 +17,7 @@
| Pholus_Scan | Scan results of the Pholus python network penetration script. | ![Screen8][screen8] | | Pholus_Scan | Scan results of the Pholus python network penetration script. | ![Screen8][screen8] |
| Plugins_Events | For capturing events exposed by a plugin via the `last_result.log` file. If unique then saved into the `Plugins_Objects` table. Entries are deleted once processed and stored in the `Plugins_History` and/or `Plugins_Objects` tables. | ![Screen10][screen10] | | Plugins_Events | For capturing events exposed by a plugin via the `last_result.log` file. If unique then saved into the `Plugins_Objects` table. Entries are deleted once processed and stored in the `Plugins_History` and/or `Plugins_Objects` tables. | ![Screen10][screen10] |
| Plugins_History | History of all entries from the `Plugins_Events` table | ![Screen11][screen11] | | Plugins_History | History of all entries from the `Plugins_Events` table | ![Screen11][screen11] |
| Plugins_Language_Strings | Language strings colelcted from the plugin `config.json` files used for string resolution in the frontend. | ![Screen12][screen12] | | Plugins_Language_Strings | Language strings collected from the plugin `config.json` files used for string resolution in the frontend. | ![Screen12][screen12] |
| Plugins_Objects | Unique objects detected by individual plugins. | ![Screen13][screen13] | | Plugins_Objects | Unique objects detected by individual plugins. | ![Screen13][screen13] |
| Sessions | Used to display sessions in the charts | ![Screen15][screen15] | | Sessions | Used to display sessions in the charts | ![Screen15][screen15] |
| Settings | Database representation of the sum of all settings from `app.conf` and plugins coming from `config.json` files. | ![Screen16][screen16] | | Settings | Database representation of the sum of all settings from `app.conf` and plugins coming from `config.json` files. | ![Screen16][screen16] |

View File

@@ -15,6 +15,7 @@ You need to specify the network interface and the network mask. You can also con
* One subnet: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0']` * One subnet: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0']`
* Two subnets: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0','192.168.1.0/24 --interface=eth1 -vlan=107']` * Two subnets: `SCAN_SUBNETS = ['192.168.1.0/24 --interface=eth0','192.168.1.0/24 --interface=eth1 -vlan=107']`
If you get timeout messages, decrease the network mask (e.g.: from a `/16` to `/24`) or increase the `TIMEOUT` setting (e.g.: `ARPSCAN_RUN_TIMEOUT` to `300` (a timeout of 5min)) for the plugin and the interval between scans (e.g.: `ARPSCAN_RUN_SCHD` to `*/10 * * * *` (scans every 10 min)).
## Explanation ## Explanation

View File

@@ -745,6 +745,18 @@ height: 50px;
.infobox_label { .infobox_label {
font-size: 16px !important; font-size: 16px !important;
} }
.deviceSelector
{
display: block;
}
.deviceSelector input
{
width: 100% !important;
display: inline-grid;
}
/* --------------------------------------------------------- */ /* --------------------------------------------------------- */
/* report */ /* report */
/* --------------------------------------------------------- */ /* --------------------------------------------------------- */
@@ -1079,6 +1091,27 @@ input[readonly] {
margin-bottom:20px; margin-bottom:20px;
} }
#settingsPage .select2-selection
{
width: initial;
display: inline-block;
}
#settingsPage .select2-selection
{
background-color: rgb(96, 96, 96);
}
#settingsPage .select2-container
{
width: 100% !important;
}
#settingsPage .select2-container .selection
{
width: 100% !important;
display: inline-grid;
}
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
/* Devices page */ /* Devices page */
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
@@ -1110,18 +1143,18 @@ input[readonly] {
cursor: -webkit-grab; cursor: -webkit-grab;
} }
.db_info_table_row .select2-container--default .select2-selection--multiple .select2-selection__choice .select2-container--default .select2-selection--multiple .select2-selection__choice
{ {
background-color:#258744; background-color:#258744 !important;
} }
.db_info_table_row .select2-container--default .select2-selection--multiple .select2-container--default .select2-selection--multiple
{ {
background-color:#606060; background-color:#606060 !important;
} }
.select2-container .select2-dropdown .select2-container .select2-dropdown
{ {
background-color:#606060; background-color:#606060 !important;
} }
.networkPageHelp{ .networkPageHelp{
@@ -1390,7 +1423,7 @@ input[readonly] {
opacity: 0.8; opacity: 0.8;
background-color: #fff; background-color: #fff;
z-index: 99; z-index: 800;
} }
.pa_spinner { .pa_spinner {
@@ -1403,7 +1436,7 @@ input[readonly] {
padding: 15px; padding: 15px;
width: 200px; width: 200px;
background-color: #fff; background-color: #fff;
z-index: 100; z-index: 801;
} }
#loadingSpinner #loadingSpinner

View File

@@ -693,7 +693,6 @@ if ($ENABLED_DARKMODE === True) {
var pos = -1; var pos = -1;
var parPeriod = 'Front_Details_Period'; var parPeriod = 'Front_Details_Period';
var parTab = 'Front_Details_Tab';
var parSessionsRows = 'Front_Details_Sessions_Rows'; var parSessionsRows = 'Front_Details_Sessions_Rows';
var parEventsRows = 'Front_Details_Events_Rows'; var parEventsRows = 'Front_Details_Events_Rows';
var parEventsHide = 'Front_Details_Events_Hide'; var parEventsHide = 'Front_Details_Events_Hide';
@@ -736,7 +735,7 @@ function main () {
$('#chkHideConnectionEvents')[0].checked = eval(eventsHide == 'true'); $('#chkHideConnectionEvents')[0].checked = eval(eventsHide == 'true');
// Initialize components with parameters // Initialize components with parameters
initializeTabs(); initializeTabsNew();
initializeiCheck(); initializeiCheck();
initializeCombos(); initializeCombos();
initializeDatatables(); initializeDatatables();
@@ -763,17 +762,6 @@ function main () {
} }
// -----------------------------------------------------------------------------
function initializeTabs () {
// Activate panel
$('.nav-tabs a[id='+ tab +']').tab('show');
// When changed save new current tab
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
setParameter (parTab, $(e.target).attr('id'));
});
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function initializeiCheck () { function initializeiCheck () {
// Blue // Blue

View File

@@ -137,136 +137,70 @@
<!-- page script ----------------------------------------------------------- --> <!-- page script ----------------------------------------------------------- -->
<script> <script>
var deviceStatus = 'all'; var deviceStatus = 'all';
var parTableRows = 'Front_Devices_Rows'; var tableRows = getCookie ("nax_parTableRows") == "" ? 10 : getCookie ("nax_parTableRows") ;
var parTableOrder = 'Front_Devices_Order'; var tableOrder = getCookie ("nax_parTableOrder") == "" ? [[3,'desc'], [0,'asc']] : JSON.parse(getCookie ("nax_parTableOrder")) ;
var tableRows = 10;
var tableOrder = [[3,'desc'], [0,'asc']];
var tableColumnHide = []; var tableColumnHide = [];
var tableColumnOrder = []; var tableColumnOrder = [];
var tableColumnVisible = []; var tableColumnVisible = [];
// Read parameters & Initialize components // Read parameters & Initialize components
callAfterAppInitialized(main) callAfterAppInitialized(main)
showSpinner(); showSpinner();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function main () { function main () {
//initialize the table headers in the correct order //initialize the table headers in the correct order
var headersDefaultOrder = [ var availableColumns = getSettingOptions("UI_device_columns").split(",");
getString('Device_TableHead_Name'), var headersDefaultOrder = availableColumns.map(val => getString(val));
getString('Device_TableHead_Owner'), var selectedColumns = JSON.parse(getSetting("UI_device_columns").replace(/'/g, '"'));
getString('Device_TableHead_Type'),
getString('Device_TableHead_Icon'),
getString('Device_TableHead_Favorite'),
getString('Device_TableHead_Group'),
getString('Device_TableHead_FirstSession'),
getString('Device_TableHead_LastSession'),
getString('Device_TableHead_LastIP'),
getString('Device_TableHead_MAC'),
getString('Device_TableHead_Status'),
getString('Device_TableHead_MAC_full'),
getString('Device_TableHead_LastIPOrder'),
getString('Device_TableHead_Rowid'),
getString('Device_TableHead_Parent_MAC'),
getString('Device_TableHead_Connected_Devices'),
getString('Device_TableHead_Location'),
getString('Device_TableHead_Vendor'),
getString('Device_TableHead_Port'),
getString('Device_TableHead_GUID'),
getString('Device_TableHead_SyncHubNodeName'),
getString('Device_TableHead_NetworkSite'),
getString('Device_TableHead_SSID')
];
// generate default order lists of given length // generate default order lists of given length
var columnsStr = JSON.stringify(Array.from({ length: headersDefaultOrder.length }, (_, i) => i)); var columnsStr = JSON.stringify(Array.from({ length: headersDefaultOrder.length }, (_, i) => i));
tableColumnOrder = Array.from({ length: headersDefaultOrder.length }, (_, i) => i); tableColumnOrder = Array.from({ length: headersDefaultOrder.length }, (_, i) => i);
tableColumnVisible = tableColumnOrder; tableColumnVisible = [];
handleLoadingDialog() // Initialize tableColumnVisible by including all columns from selectedColumns, preserving their order.
tableColumnVisible = selectedColumns.map(column => availableColumns.indexOf(column)).filter(index => index !== -1);
// Add any columns from availableColumns that are not in selectedColumns to the end.
const remainingColumns = availableColumns.map((column, index) => index).filter(index => !tableColumnVisible.includes(index));
// Combine both arrays.
tableColumnOrder = tableColumnVisible.concat(remainingColumns);
// Generate the full array of numbers from 0 to totalLength - 1 of tableColumnOrder
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));
// 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 // Hide UI elements as per settings
// setTimeout(() => { // setTimeout(() => {
hideUIelements("UI_DEV_SECTIONS") hideUIelements("UI_DEV_SECTIONS")
// }, 10); // }, 10);
// Initialize components with parameters
initializeDatatable(getUrlAnchor('my_devices'));
// check if data outdated and show spinner if so
handleLoadingDialog()
// get from cookie if available (need to use decodeURI as saved as part of URI in PHP)
cookieColumnsVisibleStr = decodeURI(getCookie("Front_Devices_Columns_Visible")).replaceAll('%2C',',')
defaultValue = cookieColumnsVisibleStr == "" ? columnsStr : cookieColumnsVisibleStr;
// get visible columns
$.get('php/server/parameters.php?action=get&expireMinutes=525600&defaultValue='+defaultValue+'&parameter=Front_Devices_Columns_Visible&skipcache', function(data) {
handle_locked_DB(data)
// save which columns are in the Devices page visible
tableColumnVisible = numberArrayFromString(data);
// get from cookie if available (need to use decodeURI as saved as part of URI in PHP)
cookieColumnsOrderStr = decodeURI(getCookie("Front_Devices_Columns_Order")).replaceAll('%2C',',')
defaultValue = cookieColumnsOrderStr == "" ? columnsStr : cookieColumnsOrderStr;
// get the custom order specified by the user
$.get('php/server/parameters.php?action=get&expireMinutes=525600&defaultValue='+defaultValue+'&parameter=Front_Devices_Columns_Order&skipcache', function(data) {
handle_locked_DB(data)
// save the columns order in the Devices page
tableColumnOrder = numberArrayFromString(data);
html = '';
for(index = 0; index < tableColumnOrder.length; index++)
{
html += '<th>' + headersDefaultOrder[tableColumnOrder[index]] + '</th>';
}
$('#tableDevices tr').html(html);
// get parameter value
$.get('php/server/parameters.php?action=get&defaultValue=50&parameter='+ parTableRows, function(data) {
var result = JSON.parse(data);
result = parseInt(result, 10)
if (Number.isInteger (result) ) {
tableRows = result;
}
// get parameter value
$.get('php/server/parameters.php?action=get&defaultValue=[[3,"desc"],[0,"asc"]]&parameter='+ parTableOrder, function(data) {
var result = JSON.parse(data);
result = JSON.parse(result);
if (Array.isArray (result) ) {
tableOrder = result;
}
// Initialize components with parameters
initializeDatatable(getUrlAnchor('my_devices'));
// check if data outdated and show spinner if so
handleLoadingDialog()
});
});
});
});
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -467,6 +401,11 @@ function initializeDatatable (status) {
} }
$.get('api/table_devices.json?nocache=' + Date.now(), function(result) { $.get('api/table_devices.json?nocache=' + Date.now(), function(result) {
// refresh devices cache
devicesListAll_JSON = result["data"]
devicesListAll_JSON_str = JSON.stringify(devicesListAll_JSON)
setCache('devicesListAll_JSON', devicesListAll_JSON_str)
// query data // query data
getDevicesTotals(result.data); getDevicesTotals(result.data);
@@ -515,10 +454,6 @@ function initializeDatatable (status) {
}) })
}; };
// TODO displayed columns
// Check if the DataTable already exists // Check if the DataTable already exists
if ($.fn.dataTable.isDataTable('#tableDevices')) { if ($.fn.dataTable.isDataTable('#tableDevices')) {
// The DataTable exists, so destroy it // The DataTable exists, so destroy it
@@ -526,12 +461,12 @@ function initializeDatatable (status) {
table.clear().destroy(); table.clear().destroy();
} }
var table= var table =
$('#tableDevices').DataTable({ $('#tableDevices').DataTable({
'data' : dataArray["data"], 'data' : dataArray["data"],
'paging' : true, 'paging' : true,
'lengthChange' : true, 'lengthChange' : true,
'lengthMenu' : [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, getString('Device_Tablelenght_all')]], 'lengthMenu' : [[10, 25, 50, 100, 500, 100000], [10, 25, 50, 100, 500, getString('Device_Tablelenght_all')]],
'searching' : true, 'searching' : true,
'ordering' : true, 'ordering' : true,
@@ -679,11 +614,11 @@ function initializeDatatable (status) {
// Save cookie Rows displayed, and Parameters rows & order // Save cookie Rows displayed, and Parameters rows & order
$('#tableDevices').on( 'length.dt', function ( e, settings, len ) { $('#tableDevices').on( 'length.dt', function ( e, settings, len ) {
setParameter (parTableRows, len); setCookie ("nax_parTableRows", len);
} ); } );
$('#tableDevices').on( 'order.dt', function () { $('#tableDevices').on( 'order.dt', function () {
setParameter (parTableOrder, JSON.stringify (table.order()) ); setCookie ("nax_parTableOrder", JSON.stringify (table.order()) );
setCache ('devicesList', getDevicesFromTable(table) ); setCache ('devicesList', getDevicesFromTable(table) );
} ); } );
@@ -703,8 +638,6 @@ function initializeDatatable (status) {
// Check if any row is selected // Check if any row is selected
var anyRowSelected = $('#tableDevices tr.selected').length > 0; var anyRowSelected = $('#tableDevices tr.selected').length > 0;
console.log(anyRowSelected);
// Toggle visibility of element with ID 'multiEdit' // Toggle visibility of element with ID 'multiEdit'
$('#multiEdit').toggle(anyRowSelected); $('#multiEdit').toggle(anyRowSelected);
}, 200); }, 200);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -0,0 +1,374 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="200"
height="200"
viewBox="0 0 52.916667 52.916668"
version="1.1"
id="svg5"
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
sodipodi:docname="netalertx_red_1_backup_clened.svg"
inkscape:export-filename="C:\Users\jokob\netalertx_red_1.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="true"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.8284271"
inkscape:cx="132.22897"
inkscape:cy="118.44039"
inkscape:window-width="3440"
inkscape:window-height="1377"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="layer6"
units="px"
width="50px" />
<defs
id="defs2">
<inkscape:path-effect
effect="powermask"
id="path-effect51283"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect51283"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect51278"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect51278"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect51273"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect51273"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<inkscape:path-effect
effect="powermask"
id="path-effect48754"
is_visible="true"
lpeversion="1"
uri="#mask-powermask-path-effect48754"
invert="false"
hide_mask="false"
background="true"
background_color="#ffffffff" />
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath48972">
<path
style="fill:#000000;stroke-width:0.280643"
id="path48974"
width="56.128242"
height="56.128246"
x="-18.924671"
y="-56.198174"
transform="rotate(45.438374)"
mask="none"
sodipodi:type="rect" />
</clipPath>
<mask
maskUnits="userSpaceOnUse"
id="mask49405">
<text
xml:space="preserve"
style="font-size:60.8695px;line-height:1.25;font-family:Amiri;-inkscape-font-specification:Amiri;display:inline;stroke-width:1.52174"
x="66.930733"
y="78.642288"
id="text49409"
transform="scale(1.4861626,0.67287388)"><tspan
sodipodi:role="line"
id="tspan49407"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Tw Cen MT';-inkscape-font-specification:'Tw Cen MT';fill:#ffffff;stroke-width:1.52174"
x="66.930733"
y="78.642288">A</tspan></text>
</mask>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath50306">
<circle
style="mix-blend-mode:normal;fill:#d40000;stroke-width:0.176318"
id="circle50308"
cy="26.458334"
cx="26.458334"
r="26.458334"
clip-path="url(#clipPath48972)"
transform="matrix(1.0038771,0,0.00391255,1.0073928,-0.04603368,-0.1228191)" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath48972-7">
<path
style="fill:#000000;stroke-width:0.280643"
id="path48974-5"
width="56.128242"
height="56.128246"
x="-18.924671"
y="-56.198174"
transform="rotate(45.438374)"
mask="none"
sodipodi:type="rect" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath50306-6">
<circle
style="mix-blend-mode:normal;fill:#d40000;stroke-width:0.176318"
id="circle50308-5"
cy="26.458334"
cx="26.458334"
r="26.458334"
clip-path="url(#clipPath48972)"
transform="matrix(1.0038771,0,0.00391255,1.0073928,-0.04603368,-0.1228191)" />
</clipPath>
<mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect51273">
<path
id="mask-powermask-path-effect51273_box"
style="fill:#ffffff;fill-opacity:1"
d="m 71.788348,33.677177 h 2.00083 v 2.173766 h -2.00083 z" />
<path
style="fill:#000000"
id="path51263"
sodipodi:type="arc"
sodipodi:cx="66.211845"
sodipodi:cy="37.490814"
sodipodi:rx="3.9464016"
sodipodi:ry="1.4616301"
sodipodi:start="0"
sodipodi:end="0.031086059"
sodipodi:open="true"
sodipodi:arc-type="arc"
d="m 70.158247,37.490814 a 3.9464016,1.4616301 0 0 1 -0.0019,0.04543" />
</mask>
<mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect51278">
<path
style="fill:#000000"
id="path51267"
sodipodi:type="arc"
sodipodi:cx="66.211845"
sodipodi:cy="37.490814"
sodipodi:rx="3.9464016"
sodipodi:ry="1.4616301"
sodipodi:start="0"
sodipodi:end="0.031086059"
sodipodi:open="true"
sodipodi:arc-type="arc" />
</mask>
<mask
maskUnits="userSpaceOnUse"
id="mask-powermask-path-effect51283">
<path
style="fill:#000000"
id="path51271"
sodipodi:type="arc"
sodipodi:cx="66.211845"
sodipodi:cy="37.490814"
sodipodi:rx="3.9464016"
sodipodi:ry="1.4616301"
sodipodi:start="0"
sodipodi:end="0.031086059"
sodipodi:open="true"
sodipodi:arc-type="arc" />
</mask>
<filter
id="mask-powermask-path-effect51273_inverse"
inkscape:label="filtermask-powermask-path-effect51273"
style="color-interpolation-filters:sRGB"
height="100"
width="100"
x="-50"
y="-50">
<feColorMatrix
id="mask-powermask-path-effect51273_primitive1"
values="1"
type="saturate"
result="fbSourceGraphic" />
<feColorMatrix
id="mask-powermask-path-effect51273_primitive2"
values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 "
in="fbSourceGraphic" />
</filter>
</defs>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="Red 1"
style="display:none">
<circle
style="fill:#ff2a2a;stroke-width:0.176318"
id="path31-8"
cy="26.458334"
cx="26.458334"
r="26.458334" />
</g>
<g
inkscape:label="Black"
inkscape:groupmode="layer"
id="layer1"
style="display:inline">
<ellipse
style="fill:#000000;stroke-width:0.176146"
id="path31"
cy="26.51001"
cx="26.458334"
rx="26.458334"
ry="26.406658" />
<circle
style="display:inline;fill:#ffffff;stroke-width:0.176318"
id="path31-89"
mask="url(#mask49405)"
transform="translate(-99.990036,0.02979629)"
r="26.458334"
cy="26.458334"
cx="126.45834" />
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="A - Layer 2"
style="display:none">
<rect
style="fill:#ffffff;stroke-width:0.328992"
id="rect48998"
width="26.0966"
height="6.0620313"
x="13.255443"
y="41.262722" />
</g>
<g
inkscape:groupmode="layer"
id="g48055"
inkscape:label="Red top"
style="display:none;mix-blend-mode:normal">
<circle
style="mix-blend-mode:normal;fill:#d40000;stroke-width:0.176318"
id="circle48752"
cy="26.458334"
cx="26.458334"
r="26.458334"
clip-path="url(#clipPath48972)"
transform="matrix(1.0038771,0,0.00391255,1.0073928,-0.04603368,-0.1228191)" />
<ellipse
style="display:inline;mix-blend-mode:normal;fill:#000000;stroke-width:0.43638"
id="path50080"
clip-path="url(#clipPath50306)"
ry="13.739323"
rx="16.735666"
cy="22.874514"
cx="26.36149"
transform="translate(0,0.09980904)" />
<path
style="fill:#000000"
id="path51325"
sodipodi:type="arc"
sodipodi:cx="16.772207"
sodipodi:cy="26.090099"
sodipodi:rx="4.1291056"
sodipodi:ry="7.6004772"
sodipodi:start="0"
sodipodi:end="0.031086059"
sodipodi:arc-type="slice"
d="m 20.901313,26.090099 a 4.1291056,7.6004772 0 0 1 -0.002,0.236231 l -4.127111,-0.236231 z" />
<path
style="fill:#d40000"
id="path51717"
sodipodi:type="arc"
sodipodi:cx="26.441042"
sodipodi:cy="-26.531424"
sodipodi:rx="10.418671"
sodipodi:ry="9.5820541"
sodipodi:start="0.82219863"
sodipodi:end="2.3054129"
sodipodi:arc-type="slice"
d="m 33.532115,-19.511189 a 10.418671,9.5820541 0 0 1 -14.074736,0.09049 l 6.983663,-7.110726 z"
transform="matrix(1,0,0.0048047,-0.99998846,0,0)" />
<path
style="fill:#ffffff;stroke-width:0.276214"
d="M 145.28835,50.354872 C 127.01317,34.62734 98.057144,30.012421 73.710372,38.947003 c -6.518003,2.391924 -14.288822,6.834002 -19.265958,11.01311 -1.198654,1.006465 -2.270358,1.829935 -2.381565,1.829935 -0.111206,0 -5.210052,-5.102002 -11.33077,-11.337781 L 29.603503,29.114489 30.822139,27.851613 c 0.670251,-0.69458 2.51592,-2.384634 4.101489,-3.755674 C 50.725112,10.43241 69.462577,2.3767456 90.736164,0.10085492 95.380582,-0.39601422 106.33043,-0.31105699 111.03786,0.25837091 133.04363,2.9202648 151.46536,11.26468 167.83762,25.986722 l 3.30701,2.97369 -2.29392,2.320103 c -1.26165,1.276057 -6.58213,6.517685 -11.82329,11.648065 l -9.52936,9.327957 z"
id="path52311"
transform="scale(0.26458333)" />
<path
style="fill:#ffffff;stroke-width:0.276214"
d="M 86.538548,86.634546 74.145111,73.25799 74.899337,72.758689 c 4.93766,-3.268754 10.138703,-6.508578 16.602198,-7.437693 5.484021,-0.788317 12.228205,-0.984814 16.377135,-0.09119 6.77689,1.459652 11.87156,4.340971 17.02452,7.792011 l 0.97468,0.652765 -1.37124,1.269268 c -0.86863,0.804036 -6.82647,6.676301 -13.34742,13.259175 L 99.423152,99.796276 Z"
id="path52350"
transform="scale(0.26458333)"
inkscape:export-filename="C:\Users\jokob\path52350.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
sodipodi:nodetypes="ccsssscsscc" />
</g>
<g
inkscape:groupmode="layer"
id="layer6"
inkscape:label="Circle"
style="display:inline">
<path
style="fill:#000000"
id="path50026"
sodipodi:type="arc"
sodipodi:cx="71.071762"
sodipodi:cy="34.677177"
sodipodi:rx="1.7174155"
sodipodi:ry="5.5907354"
sodipodi:start="0"
sodipodi:end="0.031086059"
sodipodi:open="true"
sodipodi:arc-type="arc"
mask="url(#mask-powermask-path-effect51273)"
d="m 72.789178,34.677177 a 1.7174155,5.5907354 0 0 1 -8.3e-4,0.173766"
inkscape:path-effect="#path-effect51273" />
<path
style="fill:#ffffff;stroke-width:0.276214"
d="m 151.08883,181.46994 -2.76213,-2.60427 -48.802077,-0.009 -48.802075,-0.009 -2.292573,2.48592 c -1.260915,1.36726 -2.431589,2.48592 -2.601499,2.48592 -0.869396,0 -9.118995,-6.36599 -13.713669,-10.58246 l -2.688104,-2.46684 34.973647,-35.11455 c 19.235503,-19.313 34.922993,-35.39075 35.029879,-35.39075 0.106889,0 16.231201,16.10588 35.663001,35.45326 l 35.33055,35.17705 -2.48592,2.35505 c -3.08951,2.92687 -7.41515,6.40509 -11.09719,8.92319 -1.54594,1.05725 -2.85105,1.91728 -2.90024,1.9112 -0.0492,-0.006 -1.33242,-1.183 -2.8516,-2.61535 z m -38.4631,-38.32188 -13.050732,-13.05073 -13.050727,13.05073 -13.050725,13.05072 h 26.101452 26.101452 z"
id="path52389"
transform="scale(0.26458333)"
inkscape:export-filename="C:\Users\jokob\path52389.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
sodipodi:nodetypes="ccccssscssscsscccccccccc" />
<path
style="fill:#d40000;stroke-width:0.276214"
d="M 86.416478,86.793237 C 73.427951,73.815968 73.387119,73.801376 73.387119,73.801376 c 3.874197,-3.341721 11.025508,-6.981646 17.312424,-8.529335 2.339787,-0.576001 4.881362,-1.25628 8.810591,-1.259564 4.438736,-0.0037 8.292516,0.857843 13.253396,2.535104 4.59135,1.552325 7.8315,3.224336 11.49958,5.934101 l 1.61476,1.192897 -2.31005,2.336325 c -1.27053,1.284978 -7.22284,7.16236 -13.22736,13.060849 L 99.423152,99.796276 C 95.128284,95.409033 87.282899,87.658907 86.416478,86.793237 Z"
id="path52465"
transform="scale(0.26458333)"
sodipodi:nodetypes="sssssscsscs" />
<path
style="fill:#d40000;stroke-width:0.074168"
d="M 38.412677,13.39572 C 34.322163,9.945267 28.437517,8.4874766 22.684204,9.4993379 19.419721,10.073478 16.752307,11.410793 13.835187,13.872492 l -0.14691,0.126732 -0.587936,-0.661605 c -0.268568,-0.30222 -1.619514,-1.65761 -2.963235,-3.048642 L 7.7265561,7.8632145 7.9975963,7.5868118 C 9.8344314,5.713635 13.005888,3.476019 15.380049,2.3878744 20.659765,-0.03196726 26.24205,-0.73479764 31.856076,0.42838695 36.599757,1.4112419 40.746004,3.5106537 44.46876,7.1557672 l 0.709881,0.6950753 -0.663694,0.69037 C 44.080041,8.9935983 42.672626,10.391271 41.3963,11.655819 L 39.075708,13.955 Z"
id="path52504"
inkscape:export-filename="C:\Users\jokob\path52504.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
sodipodi:nodetypes="ssscsccsssscsscs" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -12,7 +12,7 @@ var timerRefreshData = ''
var emptyArr = ['undefined', "", undefined, null, 'null']; var emptyArr = ['undefined', "", undefined, null, 'null'];
var UI_LANG = "English"; var UI_LANG = "English";
const allLanguages = ["en_us", "es_es", "de_de", "fr_fr", "it_it", "ru_ru", "nb_no", "pl_pl", "zh_cn"]; // 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"]; // needs to be same as in lang.php
var settingsJSON = {} var settingsJSON = {}
@@ -212,7 +212,8 @@ function cacheStrings() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Create a promise for each language // Create a promise for each language
const languagePromises = allLanguages.map((language_code) => { languagesToLoad = ['en_us', getLangCode()]
const languagePromises = languagesToLoad.map((language_code) => {
return new Promise((resolveLang, rejectLang) => { return new Promise((resolveLang, rejectLang) => {
// Fetch core strings and translations // Fetch core strings and translations
@@ -267,6 +268,29 @@ function cacheStrings() {
function getString(key) { function getString(key) {
function fetchString(key) { function fetchString(key) {
lang_code = getLangCode();
let result = getCache(`pia_lang_${key}_${lang_code}`, true);
if (isEmpty(result)) {
result = getCache(`pia_lang_${key}_en_us`, true);
}
return result;
}
if (isAppInitialized()) {
return fetchString(key);
} else {
callAfterAppInitialized(() => fetchString(key));
}
}
// -----------------------------------------------------------------------------
// Get current language ISO code
function getLangCode() {
UI_LANG = getSetting("UI_LANG"); UI_LANG = getSetting("UI_LANG");
let lang_code = 'en_us'; let lang_code = 'en_us';
@@ -305,22 +329,12 @@ function getString(key) {
case 'Chinese (zh_cn)': case 'Chinese (zh_cn)':
lang_code = 'zh_cn'; lang_code = 'zh_cn';
break; break;
case 'Czech (cs_cz)':
lang_code = 'cs_cz';
break;
} }
let result = getCache(`pia_lang_${key}_${lang_code}`, true); return lang_code;
if (isEmpty(result)) {
result = getCache(`pia_lang_${key}_en_us`, true);
}
return result;
}
if (isAppInitialized()) {
return fetchString(key);
} else {
callAfterAppInitialized(() => fetchString(key));
}
} }
@@ -396,6 +410,7 @@ function handle_locked_DB(data)
showSpinner() showSpinner()
setTimeout(function() { setTimeout(function() {
console.warn("Database locked - reload")
location.reload(); location.reload();
}, 5000); }, 5000);
} }
@@ -666,7 +681,7 @@ function openUrl(urls) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function navigateToDeviceWithIp (ip) { function navigateToDeviceWithIp (ip) {
$.get('api/table_devices.json', function(res) { $.get('api/table_devices.json?nocache=' + Date.now(), function(res) {
devices = res["data"]; devices = res["data"];
@@ -876,9 +891,9 @@ function cacheDevices()
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if(!getCache('completedCalls').includes('cacheDevices')) // if(!getCache('completedCalls').includes('cacheDevices'))
{ // {
$.get('api/table_devices.json', function(data) { $.get('api/table_devices.json?nocache=' + Date.now(), function(data) {
// console.log(data) // console.log(data)
@@ -901,7 +916,8 @@ function cacheDevices()
// console.log(getCache('devicesListAll_JSON')) // console.log(getCache('devicesListAll_JSON'))
}).then(() => handleSuccess('cacheDevices', resolve())).catch(() => handleFailure('cacheDevices', reject("cacheDevices already completed"))); // handle AJAX synchronization }).then(() => handleSuccess('cacheDevices', resolve())).catch(() => handleFailure('cacheDevices', reject("cacheDevices already completed"))); // handle AJAX synchronization
} }
}); // }
);
} }
var devicesListAll_JSON = []; // this will contain a list off all devices var devicesListAll_JSON = []; // this will contain a list off all devices
@@ -1130,6 +1146,54 @@ function arraysContainSameValues(arr1, arr2) {
} }
} }
// -----------------------------------------------------------------------------
// Hide elements on the page based on the supplied setting
function hideUIelements(settingKey) {
hiddenSectionsSetting = getSetting(settingKey)
if(hiddenSectionsSetting != "") // handle if settings not yet initialized
{
sectionsArray = createArray(hiddenSectionsSetting)
// remove spaces to get IDs
var newArray = $.map(sectionsArray, function(value) {
return value.replace(/\s/g, '');
});
$.each(newArray, function(index, hiddenSection) {
if($('#' + hiddenSection))
{
$('#' + hiddenSection).hide()
}
});
}
}
// -----------------------------------------------------------------------------
// apply dark mode
$(document).ready(function() {
// Assume getSetting is a function that returns true or false for dark mode
if (getSetting("UI_dark_mode") === "True") {
// Add the dark mode stylesheet
setCookie("UI_dark_mode", "True")
$('head').append('<link rel="stylesheet" href="css/dark-patch.css">');
// Set the background image for dark mode
$('body').attr('style', 'background-image: url(\'img/boxed-bg-dark.png\');');
} else {
setCookie("UI_dark_mode", "False")
// Set the background image for light mode
$('body').attr('style', 'background-image: url(\'img/background.png\');');
}
});
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// initialize // initialize
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -1140,7 +1204,7 @@ const sessionStorageKey = "myScriptExecuted_common_js";
var completedCalls = [] var completedCalls = []
var completedCalls_final = ['cacheSettings', 'cacheStrings', 'cacheDevices']; var completedCalls_final = ['cacheSettings', 'cacheStrings', 'cacheDevices'];
var completedCallsCount = 0; var completedCallsCount = 0;
var completedCallsCount_final = allLanguages.length + 2; // number of language files + cacheDevices + cacheSettings var completedCallsCount_final;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Clearing all the caches // Clearing all the caches
@@ -1149,8 +1213,9 @@ function clearCache() {
sessionStorage.clear(); sessionStorage.clear();
localStorage.clear(); localStorage.clear();
setTimeout(() => { setTimeout(() => {
window.location.reload(); console.warn("clearChache called");
}, 500); window.location.reload();
}, 500);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -1195,7 +1260,11 @@ function callAfterAppInitialized(callback) {
// Check if the code has been executed before by checking sessionStorage // Check if the code has been executed before by checking sessionStorage
function isAppInitialized() { function isAppInitialized() {
// return arraysContainSameValues(getCache("completedCalls").split(',').filter(Boolean), completedCalls_final); // return arraysContainSameValues(getCache("completedCalls").split(',').filter(Boolean), completedCalls_final);
return (parseInt(getCache("completedCallsCount")) == completedCallsCount_final);
// loading settings + 1 (or 2 language files if not english) + device cache.
completedCallsCount_final = getLangCode() == 'en_us' ? 3 : 4 ;
return (parseInt(getCache("completedCallsCount")) >= completedCallsCount_final);
} }
// Define a function that will execute the code only once // Define a function that will execute the code only once
@@ -1281,12 +1350,13 @@ const areAllStringsInitialized = () => {
// Call the function to execute the code // Call the function to execute the code
executeOnce(); executeOnce();
// Set timer for regular checks // Set timer for regular UI refresh if enabled
setTimeout(() => { setTimeout(() => {
// page refresh if configured // page refresh if configured
const refreshTime = getSetting("UI_REFRESH"); const refreshTime = getSetting("UI_REFRESH");
if (refreshTime && refreshTime !== "0" && refreshTime !== "") { if (refreshTime && refreshTime !== "0" && refreshTime !== "") {
console.log("Refreshing page becasue UI_REFRESH setting enabled.");
newTimerRefreshData(clearCache, parseInt(refreshTime)*1000); newTimerRefreshData(clearCache, parseInt(refreshTime)*1000);
} }

View File

@@ -242,6 +242,18 @@ $(document).ready(function () {
}); });
// -----------------------------------------------------------------------------
// Escape text
function safeDecodeURIComponent(content) {
try {
return decodeURIComponent(content);
} catch (error) {
console.warn('Failed to decode URI component:', error);
return content; // Return the original content if decoding fails
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Backend notification Polling // Backend notification Polling
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -266,7 +278,9 @@ function checkNotification() {
if (oldestInterruptNotification) { if (oldestInterruptNotification) {
// Show modal dialog with the oldest unread notification // Show modal dialog with the oldest unread notification
const decodedContent = decodeURIComponent(oldestInterruptNotification.content); console.log(oldestInterruptNotification.content);
const decodedContent = safeDecodeURIComponent(oldestInterruptNotification.content);
showModalOK("Notification", decodedContent, function() { showModalOK("Notification", decodedContent, function() {
// Mark the notification as read // Mark the notification as read

View File

@@ -304,6 +304,54 @@ function removeAllOptions(element) {
$(`#${$(element).attr("my-input-to")}`).empty(); $(`#${$(element).attr("my-input-to")}`).empty();
} }
// -------------------------------------------------------------------
// Add all options
function selectAll(element) {
settingsChanged();
// Get the <select> element with the class 'deviceSelector'
// var selectElement = $('.deviceSelector select');
var selectElement = $(`#${$(element).attr("my-input-to")}`);
// Iterate over each option within the select element
selectElement.find('option').each(function() {
// Mark each option as selected
$(this).prop('selected', true);
});
// Trigger the 'change' event to notify Bootstrap Select of the changes
selectElement.trigger('change');
}
// -----------------------------------------------------------------------------
// UN-Select All
function unselectAll(element) {
settingsChanged();
// Get the <select> element with the class 'deviceSelector'
// var selectElement = $('.deviceSelector select');
var selectElement = $(`#${$(element).attr("my-input-to")}`);
// Iterate over each option within the select element
selectElement.find('option').each(function() {
// Unselect each option
$(this).prop('selected', false);
});
// Trigger the 'change' event to notify Bootstrap Select of the changes
selectElement.trigger('change');
}
// -----------------------------------------------------------------------------
// Trigger change to open up the dropdown filed
function selectChange(element) {
settingsChanged();
// Get the <select> element with the class 'deviceSelector'
// var selectElement = $('.deviceSelector select');
var selectElement = $(`#${$(element).attr("my-input-to")}`);
selectElement.parent().find("input").focus().click();
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Function to initialize remove functionality on select options // Function to initialize remove functionality on select options
@@ -437,8 +485,6 @@ function filterRows(inputText) {
} }
setTimeout(() => { setTimeout(() => {
// Event listener for input change // Event listener for input change
$("#settingsSearch").on("input", function () { $("#settingsSearch").on("input", function () {
@@ -568,6 +614,10 @@ function applyTransformers(val, transformers) {
val = btoa(val); val = btoa(val);
} }
break; break;
case "getString":
// no change
val = val;
break;
default: default:
console.warn(`Unknown transformer: ${transformer}`); console.warn(`Unknown transformer: ${transformer}`);
} }
@@ -590,6 +640,10 @@ function reverseTransformers(val, transformers) {
val = atob(val); val = atob(val);
} }
break; break;
case "getString":
// retrieve string
val = getString(val);
break;
default: default:
console.warn(`Unknown transformer: ${transformer}`); console.warn(`Unknown transformer: ${transformer}`);
} }
@@ -604,6 +658,7 @@ const handleElementOptions = (codeName, elementOptions, transformers, val) => {
let inputType = "text"; let inputType = "text";
let readOnly = ""; let readOnly = "";
let isMultiSelect = false; let isMultiSelect = false;
let isOrdeable = false;
let cssClasses = ""; let cssClasses = "";
let placeholder = ""; let placeholder = "";
let suffix = ""; let suffix = "";
@@ -627,6 +682,9 @@ const handleElementOptions = (codeName, elementOptions, transformers, val) => {
if (option.multiple === "true") { if (option.multiple === "true") {
isMultiSelect = true; isMultiSelect = true;
} }
if (option.ordeable === "true") {
isOrdeable = true;
}
if (option.editable === "true") { if (option.editable === "true") {
editable = true; editable = true;
} }
@@ -663,6 +721,7 @@ const handleElementOptions = (codeName, elementOptions, transformers, val) => {
inputType, inputType,
readOnly, readOnly,
isMultiSelect, isMultiSelect,
isOrdeable,
cssClasses, cssClasses,
placeholder, placeholder,
suffix, suffix,
@@ -698,8 +757,9 @@ function generateOptions(options, valuesArray, targetField, transformers, placeh
resultArray = [] resultArray = []
selectedArray = [] selectedArray = []
cssClass = "" cssClass = ""
// determine if options or values are used in teh listing // determine if options or values are used in the listing
if (valuesArray.length > 0 && options.length > 0){ if (valuesArray.length > 0 && options.length > 0){
// multiselect list -> options only + selected the ones in valuesArray // multiselect list -> options only + selected the ones in valuesArray
@@ -717,21 +777,31 @@ function generateOptions(options, valuesArray, targetField, transformers, placeh
resultArray = options; resultArray = options;
} }
// Create a map to track the index of each item in valuesArray
const orderMap = new Map(valuesArray.map((item, index) => [item, index]));
// Sort resultArray based on the order in valuesArray
resultArray.sort((a, b) => {
const indexA = orderMap.has(a.id) ? orderMap.get(a.id) : valuesArray.length;
const indexB = orderMap.has(b.id) ? orderMap.get(b.id) : valuesArray.length;
return indexA - indexB;
});
resultArray.forEach(function(item) { resultArray.forEach(function(item) {
let labelName = item.name;
labelName = item.name if (labelName !== '❌None') {
labelName = reverseTransformers(labelName, transformers);
if(labelName != '❌None')
{
labelName = reverseTransformers(labelName, transformers)
} }
// needs to happen always if options ued as source // Always include selected if options are used as a source
let selected = options.length != 0 && valuesArray.includes(item.id) ? 'selected' : ''; let selected = options.length !== 0 && valuesArray.includes(item.id) ? 'selected' : '';
optionsHtml += `<option class="${cssClass}" value="${item.id}" ${selected}>${labelName}</option>`; optionsHtml += `<option class="${cssClass}" value="${item.id}" ${selected}>${labelName}</option>`;
}); });
// Place the resulting HTML into the specified placeholder div // Place the resulting HTML into the specified placeholder div
$("#" + placeholder).replaceWith(optionsHtml); $("#" + placeholder).replaceWith(optionsHtml);
} }

View File

@@ -68,38 +68,6 @@ function initDeviceSelectors(devicesListAll_JSON) {
} }
// -----------------------------------------------------------------------------
// Hide elements on the page based on the supplied setting
function hideUIelements(settingKey) {
hiddenSectionsSetting = getSetting(settingKey)
if(hiddenSectionsSetting != "") // handle if settings not yet initialized
{
sectionsArray = createArray(hiddenSectionsSetting)
// remove spaces to get IDs
var newArray = $.map(sectionsArray, function(value) {
return value.replace(/\s/g, '');
});
$.each(newArray, function(index, hiddenSection) {
if($('#' + hiddenSection))
{
$('#' + hiddenSection).hide()
}
});
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Updates the icon preview // Updates the icon preview
function updateIconPreview (inputId) { function updateIconPreview (inputId) {
@@ -249,6 +217,7 @@ function initSelect2() {
// -------------------------------------------------------- // --------------------------------------------------------
//Initialize Select2 Elements and make them sortable //Initialize Select2 Elements and make them sortable
$(function () { $(function () {
// Iterate over each Select2 dropdown // Iterate over each Select2 dropdown
$('.select2').each(function() { $('.select2').each(function() {
@@ -283,10 +252,15 @@ function initSelect2() {
} }
} }
// try to initialize select2 // init select2 after dom laoded
setTimeout(() => { window.addEventListener("load", function() {
initSelect2() // try to initialize select2
}, 500); setTimeout(() => {
initSelect2()
}, 1000);
});
console.log("init ui_components.js") console.log("init ui_components.js")

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

View File

@@ -11,25 +11,7 @@
# cvc90 2023 https://github.com/cvc90 GNU GPLv3 # # cvc90 2023 https://github.com/cvc90 GNU GPLv3 #
#---------------------------------------------------------------------------------# #---------------------------------------------------------------------------------#
// Skin selector config ----------------------------------------------------
//
// For security reasons, new language files must be entered into this array.
// The files in the language directory are compared with this array and only
// then accepted.
//
$pia_installed_skins = array('skin-black-light',
'skin-black',
'skin-blue-light',
'skin-blue',
'skin-green-light',
'skin-green',
'skin-purple-light',
'skin-purple',
'skin-red-light',
'skin-red',
'skin-yellow-light',
'skin-yellow');
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
?> ?>
@@ -38,7 +20,7 @@ $pia_installed_skins = array('skin-black-light',
require 'php/templates/header.php'; require 'php/templates/header.php';
?> ?>
<!-- Page ------------------------------------------------------------------ --> <!-- Page ------------------------------------------------------------------ -->
<div class="content-wrapper"> <div class="content-wrapper" id="maintenancePage">
<!-- Content header--------------------------------------------------------- --> <!-- Content header--------------------------------------------------------- -->
<section class="content-header"> <section class="content-header">
@@ -91,34 +73,6 @@ if (count($latestfiles) > 0)
$latestbackup_date = date ("Y-m-d H:i:s", filemtime($latestbackup)); $latestbackup_date = date ("Y-m-d H:i:s", filemtime($latestbackup));
} }
// Skin selector -----------------------------------------------------------------
if (isset($_POST['submit']) && submit && isset($_POST['skinselector_set'])) {
$pia_skin_set_dir = '../db/';
$pia_skin_selector = htmlspecialchars($_POST['skinselector']);
if (in_array($pia_skin_selector, $pia_installed_skins)) {
foreach ($pia_installed_skins as $file) {
unlink ($pia_skin_set_dir.'/setting_'.$file);
}
foreach ($pia_installed_skins as $file) {
if (file_exists($pia_skin_set_dir.'/setting_'.$file)) {
$pia_skin_error = True;
break;
} else {
$pia_skin_error = False;
}
}
if ($pia_skin_error == False) {
$testskin = fopen($pia_skin_set_dir.'setting_'.$pia_skin_selector, 'w');
$pia_skin_test = '';
echo("<meta http-equiv='refresh' content='1'>");
} else {
$pia_skin_test = '';
echo("<meta http-equiv='refresh' content='1'>");
}
}
}
// Table sizes ----------------------------------------------------------------- // Table sizes -----------------------------------------------------------------
$tableSizesHTML = ""; $tableSizesHTML = "";
@@ -142,10 +96,6 @@ while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
$db->close(); $db->close();
// Language selector -----------------------------------------------------------------
?> ?>
<div class="row"> <div class="row">
@@ -219,13 +169,7 @@ $db->close();
<div class="nav-tabs-custom"> <div class="nav-tabs-custom">
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="active"> <li class="active">
<a id="tab_Settings_id" href="#tab_Settings" data-toggle="tab">
<i class="fa fa-cogs"></i>
<?= lang('Maintenance_Tools_Tab_UISettings');?>
</a>
</li>
<li>
<a id="tab_DBTools_id" href="#tab_DBTools" data-toggle="tab"> <a id="tab_DBTools_id" href="#tab_DBTools" data-toggle="tab">
<i class="fa fa-toolbox"></i> <i class="fa fa-toolbox"></i>
<?= lang('Maintenance_Tools_Tab_Tools');?> <?= lang('Maintenance_Tools_Tab_Tools');?>
@@ -251,84 +195,7 @@ $db->close();
</li> </li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="tab_Settings"> <div class="tab-pane active" id="tab_DBTools">
<div class="db_info_table">
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" style="text-align: center;">
<form method="post" action="maintenance.php">
<div style="display: inline-block; text-align: center;">
<select name="skinselector" class="form-control bg-green" style="width:160px; margin-bottom:5px;">
<option value=""><?= lang('Maintenance_themeselector_empty');?></option>
<option value="skin-black-light">black light</option>
<option value="skin-black">black</option>
<option value="skin-blue-light">blue light</option>
<option value="skin-blue">blue</option>
<option value="skin-green-light">green light</option>
<option value="skin-green">green</option>
<option value="skin-purple-light">purple light</option>
<option value="skin-purple">purple</option>
<option value="skin-red-light">red light</option>
<option value="skin-red">red</option>
<option value="skin-yellow-light">yellow light</option>
<option value="skin-yellow">yellow</option>
</select></div>
<div style="display: block;"><input type="submit" name="skinselector_set" value="<?= lang('Maintenance_themeselector_apply');?>" class="btn bg-green" style="width:160px;">
<?php // echo $pia_skin_test; ?>
</div>
</form>
</div>
<div class="db_info_table_cell" style="padding: 10px; height:40px; text-align:left; vertical-align: middle;">
<?= lang('Maintenance_themeselector_text'); ?>
</div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a">
<button type="button" class="btn bg-green dbtools-button" id="btnToggleDarkmode" onclick="askToggleDarkmode()"><?= lang('Maintenance_Tool_darkmode');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_darkmode_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a">
<div class="form-group" >
<div class="input-group" >
<select id="columnsSelect" class="form-control select2 select2-hidden-accessible" multiple="" style="width: 100%;" tabindex="-1" aria-hidden="true">
<option value="0"><?= lang('Device_TableHead_Name');?></option>
<option value="1"><?= lang('Device_TableHead_Owner');?></option>
<option value="2"><?= lang('Device_TableHead_Type');?></option>
<option value="3"><?= lang('Device_TableHead_Icon');?></option>
<option value="4"><?= lang('Device_TableHead_Favorite');?></option>
<option value="5"><?= lang('Device_TableHead_Group');?></option>
<option value="6"><?= lang('Device_TableHead_FirstSession');?></option>
<option value="7"><?= lang('Device_TableHead_LastSession');?></option>
<option value="8"><?= lang('Device_TableHead_LastIP');?></option>
<option value="9"><?= lang('Device_TableHead_MAC');?></option>
<option value="10"><?= lang('Device_TableHead_Status');?></option>
<option value="11"><?= lang('Device_TableHead_MAC_full');?></option>
<option value="12"><?= lang('Device_TableHead_LastIPOrder');?></option>
<option value="13"><?= lang('Device_TableHead_Rowid');?></option>
<option value="14"><?= lang('Device_TableHead_Parent_MAC');?></option>
<option value="15"><?= lang('Device_TableHead_Connected_Devices');?></option>
<option value="16"><?= lang('Device_TableHead_Location');?></option>
<option value="17"><?= lang('Device_TableHead_Vendor');?></option>
<option value="18"><?= lang('Device_TableHead_Port');?></option>
<option value="19"><?= lang('Device_TableHead_GUID');?></option>
<option value="20"><?= lang('Device_TableHead_SyncHubNodeName');?></option>
<option value="21"><?= lang('Device_TableHead_NetworkSite');?></option>
<option value="22"><?= lang('Device_TableHead_SSID');?></option>
</select>
<span class="input-group-addon"><i title="<?= lang('Gen_Save');?>" class="fa fa-save pointer" onclick="saveSelectedColumns();"></i></span>
</div>
</div>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_displayed_columns_text');?></div>
</div>
</div>
</div>
<div class="tab-pane" id="tab_DBTools">
<div class="db_info_table"> <div class="db_info_table">
<div class="db_info_table_row"> <div class="db_info_table_row">
<div class="db_tools_table_cell_a" > <div class="db_tools_table_cell_a" >
@@ -487,7 +354,7 @@ $db->close();
<script> <script>
var emptyArr = ['undefined', "", undefined, null]; var emptyArr = ['undefined', "", undefined, null];
var selectedTab = 'tab_Settings_id'; var selectedTab = 'tab_DBTools_id';
initializeTabs(); initializeTabs();
@@ -713,42 +580,6 @@ function ImportPastedCSV()
} }
// --------------------------------------------------------
// Switch Darkmode
function askToggleDarkmode() {
// Ask
showModalWarning('<?= lang('Maintenance_Tool_darkmode_noti');?>', '<?= lang('Maintenance_Tool_darkmode_noti_text');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Switch');?>', 'ToggleDarkmode');
}
// --------------------------------------------------------
function ToggleDarkmode()
{
// get parameter Front_Dark_Mode_Enabled value
$.get('php/server/parameters.php?action=get&defaultValue=false&expireMinutes=525600&parameter=Front_Dark_Mode_Enabled', function(data) {
var result = JSON.parse(data);
if (result) {
darkModeEnabled = result == 'true';
// invert value
darkModeEnabled = !darkModeEnabled;
// save inverted value
$.get('php/server/parameters.php?action=set&parameter=Front_Dark_Mode_Enabled&expireMinutes=525600&value='+ darkModeEnabled,
function(data) {
if (data != "OK") {
showMessage (data);
setTimeout(function (){location.reload()}, 1000);
} else {
showMessage (data);
};
} );
}
});
}
// -------------------------------------------------------- // --------------------------------------------------------
// Clean log file // Clean log file
@@ -801,122 +632,56 @@ function scrollDown() {
} }
// --------------------------------------------------------
// Manage displayed columns
// --------------------------------------------------------
colDefaultOrder = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17'];
colDefaultOrderTxt = '[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]';
function saveSelectedColumns () {
$.get('php/server/parameters.php?action=set&expireMinutes=525600&value=['+ $('#columnsSelect').val().toString() +']&parameter=Front_Devices_Columns_Visible', function(data) {
// save full order of all columns to simplify mapping later on
colDisplayed = $('#columnsSelect').val();
colNewOrder = colDisplayed;
// append the remaining columns in the previous order
for(i = 0; i < colDefaultOrder.length; i++)
{
if(!colDisplayed.includes(colDefaultOrder[i]))
{
colNewOrder.push(colDefaultOrder[i])
}
}
// save the setting in the DB
$.get('php/server/parameters.php?action=set&expireMinutes=525600&value=['+ colNewOrder.toString() +']&parameter=Front_Devices_Columns_Order', function(data) {
showMessage(data);
});
});
}
// --------------------------------------------------------
function initializeSelectedColumns () {
$.get('php/server/parameters.php?action=get&expireMinutes=525600&defaultValue='+colDefaultOrderTxt+'&parameter=Front_Devices_Columns_Visible', function(data) {
handle_locked_DB(data)
tableColumnShow = numberArrayFromString(data);
for(i=0; i < tableColumnShow.length; i++)
{
// create the option and append to Select2
var option = new Option($('#columnsSelect option[value='+tableColumnShow[i]+']').html(), tableColumnShow[i] , true, true);
$("#columnsSelect").append(option).trigger('change');
}
});
}
// -------------------------------------------------------- // --------------------------------------------------------
// General initialization // General initialization
// -------------------------------------------------------- // --------------------------------------------------------
function initializeTabs () { function initializeTabs() {
setTimeout(() => {
setTimeout(function() { const key = "activeMaintenanceTab";
key = "activeMaintenanceTab"
// default selection // default selection
selectedTab = "tab_Settings" let selectedTab = "tab_DBTools_id";
// the #target from the url // the #target from the URL
target = window.location.hash.substr(1) let target = window.location.hash.substr(1);
console.log(selectedTab);
// get only the part between #...? // get only the part between #...?
if(target.includes('?')) if (target.includes('?')) {
{ target = target.split('?')[0];
target = target.split('?')[0]
} }
console.log(target);
// update cookie if target specified // update cookie if target specified
if(target != "") if (target) {
{ selectedTab = target.endsWith("_id") ? target : `${target}_id`;
setCache(key, selectedTab); // _id is added so it doesn't conflict with AdminLTE tab behavior
if (!selectedTab.endsWith("_id")) {
selectedTab = target + "_id";
}
setCache(key, selectedTab) // _id is added so it doesn't conflict with AdminLTE tab behavior
} }
// get the tab id from the cookie (already overriden by the target) // get the tab id from the cookie (already overridden by the target)
if(!emptyArr.includes(getCache(key))) const cachedTab = getCache(key);
{ if (cachedTab && !emptyArr.includes(cachedTab)) {
selectedTab = getCache(key); selectedTab = cachedTab;
} }
// Activate panel // Activate panel
$('.nav-tabs a[id='+ selectedTab +']').tab('show'); $('.nav-tabs a[id='+ selectedTab +']').tab('show');
// When changed save new current tab // When changed save new current tab
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { $('a[data-toggle="tab"]').on('shown.bs.tab', (e) => {
setCache(key, $(e.target).attr('id')) const newTabId = $(e.target).attr('id');
setCache(key, newTabId);
}); });
// events on tab change // events on tab change
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { $('a[data-toggle="tab"]').on('shown.bs.tab', (e) => {
var target = $(e.target).attr("href") // activated tab const newTarget = $(e.target).attr("href"); // activated tab
}); });
hideSpinner(); hideSpinner();
}, 50); }, 50);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Logs render functionality // Logs render functionality
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -936,7 +701,7 @@ function toggleAutoRefresh() {
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Manages thefilter application // Manages the filter application on the logs
function applyFilter() { function applyFilter() {
const filterText = $("#logsFilter").val().toLowerCase(); const filterText = $("#logsFilter").val().toLowerCase();
@@ -982,19 +747,20 @@ function renderLogs(customData) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Init // Init
window.onload = function asyncFooter() window.onload = function asyncFooter() {
{
initializeSelectedColumns();
renderLogs(); renderLogs();
// initializeTabs(); // initializeTabs();
$("#lastCommit").append('<a href="https://github.com/jokob-sk/NetAlertX/commits" target="_blank"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/jokob-sk/netalertx/main?logo=github"></a>'); try {
$("#lastCommit").append('<a href="https://github.com/jokob-sk/NetAlertX/commits" target="_blank"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/jokob-sk/netalertx/main?logo=github"></a>');
$("#lastDockerUpdate").append( $("#lastDockerUpdate").append(
'<a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank"><img alt="Docker last pushed" src="https://img.shields.io/github/v/release/jokob-sk/NetAlertX?color=0aa8d2&logoColor=fff&logo=GitHub&label=Latest"></a>'); '<a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank"><img alt="Docker last pushed" src="https://img.shields.io/github/v/release/jokob-sk/NetAlertX?color=0aa8d2&logoColor=fff&logo=GitHub&label=Latest"></a>');
} catch (error) {
} console.error('Failed to load GitHub badges:', error);
}
};
</script> </script>

View File

@@ -13,7 +13,7 @@
<h3 class="box-title"><?= lang('Gen_Selected_Devices');?></h3> <h3 class="box-title"><?= lang('Gen_Selected_Devices');?></h3>
</div> </div>
<div class="deviceSelector col-md-9" style="z-index:5"></div> <div class="deviceSelector col-md-9 col-sm-12" style="z-index:5"></div>
<div class="col-md-3"> <div class="col-md-3">
<button type="button" class="btn btn-default" onclick="markAllSelected()"> <button type="button" class="btn btn-default" onclick="markAllSelected()">
@@ -118,6 +118,7 @@
inputType, inputType,
readOnly, readOnly,
isMultiSelect, isMultiSelect,
isOrdeable,
cssClasses, cssClasses,
placeholder, placeholder,
suffix, suffix,

View File

@@ -359,12 +359,17 @@
<?php <?php
// Get all Unassigned / unconnected nodes // Get all Unassigned / unconnected nodes
$func_sql = 'SELECT dev_MAC as mac, $func_sql = 'SELECT
dev_PresentLastScan as online, dev_MAC AS mac,
dev_Name as name, dev_PresentLastScan AS online,
dev_LastIP as last_ip, dev_Name AS name,
dev_Network_Node_MAC_ADDR dev_LastIP AS last_ip,
FROM Devices WHERE (dev_Network_Node_MAC_ADDR is null or dev_Network_Node_MAC_ADDR = "" or dev_Network_Node_MAC_ADDR = " " or dev_Network_Node_MAC_ADDR = "undefined") and dev_MAC not like "%internet%" order by name asc'; dev_Network_Node_MAC_ADDR
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%"
ORDER BY name ASC;';
global $db; global $db;
$func_result = $db->query($func_sql); $func_result = $db->query($func_sql);

View File

@@ -54,7 +54,7 @@
<!-- NetAlertX --> <!-- NetAlertX -->
<script src="js/handle_version.js"></script> <script src="js/handle_version.js"></script>
<script src="js/ui_components.js?v=<?php include 'php/templates/version.php'; ?>"></script> <script defer src="js/ui_components.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<!-- Select2 JavaScript --> <!-- Select2 JavaScript -->

View File

@@ -67,14 +67,16 @@ require dirname(__FILE__).'/security.php';
<link id="favicon" rel="icon" type="image/x-icon" href="img/NetAlertX_logo.png"> <link id="favicon" rel="icon" type="image/x-icon" href="img/NetAlertX_logo.png">
<!-- For better UX on Mobile Devices using the Shortcut on the Homescreen --> <!-- For better UX on Mobile Devices using the Shortcut on the Homescreen -->
<link rel="manifest" href="img/manifest.json"> <link rel="manifest" href="img/manifest.json" crossorigin="use-credentials">
<!-- Dark-Mode Patch --> <!-- Dark-Mode Patch -->
<?php
if ($ENABLED_DARKMODE === True) { <?php
echo '<link rel="stylesheet" href="css/dark-patch.css">'; if ($ENABLED_DARKMODE === True) {
$BACKGROUND_IMAGE_PATCH='style="background-image: url(\'img/boxed-bg-dark.png\');"'; echo '<link rel="stylesheet" href="css/dark-patch.css">';
} else { $BACKGROUND_IMAGE_PATCH='style="background-image: url(\'img/background.png\');"';} $BACKGROUND_IMAGE_PATCH='style="background-image: url(\'img/boxed-bg-dark.png\');"';
?> } else { $BACKGROUND_IMAGE_PATCH='style="background-image: url(\'img/background.png\');"';}
?>
<!-- Servertime to the right of the hostname --> <!-- Servertime to the right of the hostname -->
@@ -312,9 +314,6 @@ if ($ENABLED_DARKMODE === True) {
</span> </span>
</a> </a>
<ul class="treeview-menu" style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('maintenance.php') ) ){ echo 'block'; } else {echo 'none';} ?>;"> <ul class="treeview-menu" style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('maintenance.php') ) ){ echo 'block'; } else {echo 'none';} ?>;">
<li>
<a href="maintenance.php#tab_Settings" onclick="initializeTabs()"> <?= lang("Maintenance_Tools_Tab_UISettings");?> </a>
</li>
<li> <li>
<a href="maintenance.php#tab_DBTools" onclick="initializeTabs()"> <?= lang("Maintenance_Tools_Tab_Tools");?> </a> <a href="maintenance.php#tab_DBTools" onclick="initializeTabs()"> <?= lang("Maintenance_Tools_Tab_Tools");?> </a>
</li> </li>

View File

@@ -0,0 +1,697 @@
{
"API_CUSTOM_SQL_description": "",
"API_CUSTOM_SQL_name": "",
"API_display_name": "",
"API_icon": "",
"About_Design": "",
"About_Exit": "",
"About_Title": "",
"AppEvents_DateTimeCreated": "",
"AppEvents_Extra": "",
"AppEvents_GUID": "",
"AppEvents_Helper1": "",
"AppEvents_Helper2": "",
"AppEvents_Helper3": "",
"AppEvents_ObjectForeignKey": "",
"AppEvents_ObjectIndex": "",
"AppEvents_ObjectIsArchived": "",
"AppEvents_ObjectIsNew": "",
"AppEvents_ObjectPlugin": "",
"AppEvents_ObjectPrimaryID": "",
"AppEvents_ObjectSecondaryID": "",
"AppEvents_ObjectStatus": "",
"AppEvents_ObjectStatusColumn": "",
"AppEvents_ObjectType": "",
"AppEvents_Plugin": "",
"AppEvents_Type": "",
"BackDevDetail_Actions_Ask_Run": "",
"BackDevDetail_Actions_Not_Registered": "",
"BackDevDetail_Actions_Title_Run": "",
"BackDevDetail_Copy_Ask": "",
"BackDevDetail_Copy_Title": "",
"BackDevDetail_Tools_WOL_error": "",
"BackDevDetail_Tools_WOL_okay": "",
"BackDevices_Arpscan_disabled": "",
"BackDevices_Arpscan_enabled": "",
"BackDevices_Backup_CopError": "",
"BackDevices_Backup_Failed": "",
"BackDevices_Backup_okay": "",
"BackDevices_DBTools_DelDevError_a": "",
"BackDevices_DBTools_DelDevError_b": "",
"BackDevices_DBTools_DelDev_a": "",
"BackDevices_DBTools_DelDev_b": "",
"BackDevices_DBTools_DelEvents": "",
"BackDevices_DBTools_DelEventsError": "",
"BackDevices_DBTools_ImportCSV": "",
"BackDevices_DBTools_ImportCSVError": "",
"BackDevices_DBTools_ImportCSVMissing": "",
"BackDevices_DBTools_Purge": "",
"BackDevices_DBTools_UpdDev": "",
"BackDevices_DBTools_UpdDevError": "",
"BackDevices_DBTools_Upgrade": "",
"BackDevices_DBTools_UpgradeError": "",
"BackDevices_Device_UpdDevError": "",
"BackDevices_Restore_CopError": "",
"BackDevices_Restore_Failed": "",
"BackDevices_Restore_okay": "",
"BackDevices_darkmode_disabled": "",
"BackDevices_darkmode_enabled": "",
"DAYS_TO_KEEP_EVENTS_description": "",
"DAYS_TO_KEEP_EVENTS_name": "",
"DevDetail_Copy_Device_Title": "",
"DevDetail_Copy_Device_Tooltip": "",
"DevDetail_EveandAl_AlertAllEvents": "",
"DevDetail_EveandAl_AlertDown": "",
"DevDetail_EveandAl_Archived": "",
"DevDetail_EveandAl_NewDevice": "",
"DevDetail_EveandAl_NewDevice_Tooltip": "",
"DevDetail_EveandAl_RandomMAC": "",
"DevDetail_EveandAl_ScanCycle": "",
"DevDetail_EveandAl_ScanCycle_a": "",
"DevDetail_EveandAl_ScanCycle_z": "",
"DevDetail_EveandAl_Skip": "",
"DevDetail_EveandAl_Title": "",
"DevDetail_Events_CheckBox": "",
"DevDetail_GoToNetworkNode": "",
"DevDetail_Icon": "",
"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": "",
"DevDetail_MainInfo_mac": "",
"DevDetail_Network_Node_hover": "",
"DevDetail_Network_Port_hover": "",
"DevDetail_Nmap_Scans": "",
"DevDetail_Nmap_Scans_desc": "",
"DevDetail_Nmap_buttonDefault": "",
"DevDetail_Nmap_buttonDefault_text": "",
"DevDetail_Nmap_buttonDetail": "",
"DevDetail_Nmap_buttonDetail_text": "",
"DevDetail_Nmap_buttonFast": "",
"DevDetail_Nmap_buttonFast_text": "",
"DevDetail_Nmap_buttonSkipDiscovery": "",
"DevDetail_Nmap_buttonSkipDiscovery_text": "",
"DevDetail_Nmap_resultsLink": "",
"DevDetail_Owner_hover": "",
"DevDetail_Periodselect_All": "",
"DevDetail_Periodselect_LastMonth": "",
"DevDetail_Periodselect_LastWeek": "",
"DevDetail_Periodselect_LastYear": "",
"DevDetail_Periodselect_today": "",
"DevDetail_Run_Actions_Title": "",
"DevDetail_Run_Actions_Tooltip": "",
"DevDetail_SessionInfo_FirstSession": "",
"DevDetail_SessionInfo_LastIP": "",
"DevDetail_SessionInfo_LastSession": "",
"DevDetail_SessionInfo_StaticIP": "",
"DevDetail_SessionInfo_Status": "",
"DevDetail_SessionInfo_Title": "",
"DevDetail_SessionTable_Additionalinfo": "",
"DevDetail_SessionTable_Connection": "",
"DevDetail_SessionTable_Disconnection": "",
"DevDetail_SessionTable_Duration": "",
"DevDetail_SessionTable_IP": "",
"DevDetail_SessionTable_Order": "",
"DevDetail_Shortcut_CurrentStatus": "",
"DevDetail_Shortcut_DownAlerts": "",
"DevDetail_Shortcut_Presence": "",
"DevDetail_Shortcut_Sessions": "",
"DevDetail_Tab_Details": "",
"DevDetail_Tab_Events": "",
"DevDetail_Tab_EventsTableDate": "",
"DevDetail_Tab_EventsTableEvent": "",
"DevDetail_Tab_EventsTableIP": "",
"DevDetail_Tab_EventsTableInfo": "",
"DevDetail_Tab_Nmap": "",
"DevDetail_Tab_NmapEmpty": "",
"DevDetail_Tab_NmapTableExtra": "",
"DevDetail_Tab_NmapTableHeader": "",
"DevDetail_Tab_NmapTableIndex": "",
"DevDetail_Tab_NmapTablePort": "",
"DevDetail_Tab_NmapTableService": "",
"DevDetail_Tab_NmapTableState": "",
"DevDetail_Tab_NmapTableText": "",
"DevDetail_Tab_NmapTableTime": "",
"DevDetail_Tab_Plugins": "",
"DevDetail_Tab_Presence": "",
"DevDetail_Tab_Sessions": "",
"DevDetail_Tab_Tools": "",
"DevDetail_Tab_Tools_Internet_Info_Description": "",
"DevDetail_Tab_Tools_Internet_Info_Error": "",
"DevDetail_Tab_Tools_Internet_Info_Start": "",
"DevDetail_Tab_Tools_Internet_Info_Title": "",
"DevDetail_Tab_Tools_Nslookup_Description": "",
"DevDetail_Tab_Tools_Nslookup_Error": "",
"DevDetail_Tab_Tools_Nslookup_Start": "",
"DevDetail_Tab_Tools_Nslookup_Title": "",
"DevDetail_Tab_Tools_Speedtest_Description": "",
"DevDetail_Tab_Tools_Speedtest_Start": "",
"DevDetail_Tab_Tools_Speedtest_Title": "",
"DevDetail_Tab_Tools_Traceroute_Description": "",
"DevDetail_Tab_Tools_Traceroute_Error": "",
"DevDetail_Tab_Tools_Traceroute_Start": "",
"DevDetail_Tab_Tools_Traceroute_Title": "",
"DevDetail_Tools_WOL": "",
"DevDetail_Tools_WOL_noti": "",
"DevDetail_Tools_WOL_noti_text": "",
"DevDetail_Type_hover": "",
"DevDetail_Vendor_hover": "",
"DevDetail_WOL_Title": "",
"DevDetail_button_AddIcon": "",
"DevDetail_button_AddIcon_Help": "",
"DevDetail_button_AddIcon_Tooltip": "",
"DevDetail_button_Delete": "",
"DevDetail_button_DeleteEvents": "",
"DevDetail_button_DeleteEvents_Warning": "",
"DevDetail_button_OverwriteIcons": "",
"DevDetail_button_OverwriteIcons_Tooltip": "",
"DevDetail_button_OverwriteIcons_Warning": "",
"DevDetail_button_Reset": "",
"DevDetail_button_Save": "",
"Device_MultiEdit": "",
"Device_MultiEdit_Backup": "",
"Device_MultiEdit_Fields": "",
"Device_MultiEdit_MassActions": "",
"Device_MultiEdit_Tooltip": "",
"Device_Searchbox": "",
"Device_Shortcut_AllDevices": "",
"Device_Shortcut_Archived": "",
"Device_Shortcut_Connected": "",
"Device_Shortcut_Devices": "",
"Device_Shortcut_DownAlerts": "",
"Device_Shortcut_DownOnly": "",
"Device_Shortcut_Favorites": "",
"Device_Shortcut_NewDevices": "",
"Device_Shortcut_OnlineChart": "",
"Device_TableHead_Connected_Devices": "",
"Device_TableHead_Favorite": "",
"Device_TableHead_FirstSession": "",
"Device_TableHead_GUID": "",
"Device_TableHead_Group": "",
"Device_TableHead_Icon": "",
"Device_TableHead_LastIP": "",
"Device_TableHead_LastIPOrder": "",
"Device_TableHead_LastSession": "",
"Device_TableHead_Location": "",
"Device_TableHead_MAC": "",
"Device_TableHead_MAC_full": "",
"Device_TableHead_Name": "",
"Device_TableHead_NetworkSite": "",
"Device_TableHead_Owner": "",
"Device_TableHead_Parent_MAC": "",
"Device_TableHead_Port": "",
"Device_TableHead_RowID": "",
"Device_TableHead_Rowid": "",
"Device_TableHead_SSID": "",
"Device_TableHead_Status": "",
"Device_TableHead_SyncHubNodeName": "",
"Device_TableHead_Type": "",
"Device_TableHead_Vendor": "",
"Device_Table_Not_Network_Device": "",
"Device_Table_info": "",
"Device_Table_nav_next": "",
"Device_Table_nav_prev": "",
"Device_Tablelenght": "",
"Device_Tablelenght_all": "",
"Device_Title": "",
"Donations_Others": "",
"Donations_Platforms": "",
"Donations_Text": "",
"Donations_Title": "",
"ENABLE_PLUGINS_description": "",
"ENABLE_PLUGINS_name": "",
"Email_display_name": "",
"Email_icon": "",
"Events_Loading": "",
"Events_Periodselect_All": "",
"Events_Periodselect_LastMonth": "",
"Events_Periodselect_LastWeek": "",
"Events_Periodselect_LastYear": "",
"Events_Periodselect_today": "",
"Events_Searchbox": "",
"Events_Shortcut_AllEvents": "",
"Events_Shortcut_DownAlerts": "",
"Events_Shortcut_Events": "",
"Events_Shortcut_MissSessions": "",
"Events_Shortcut_NewDevices": "",
"Events_Shortcut_Sessions": "",
"Events_Shortcut_VoidSessions": "",
"Events_TableHead_AdditionalInfo": "",
"Events_TableHead_Connection": "",
"Events_TableHead_Date": "",
"Events_TableHead_Device": "",
"Events_TableHead_Disconnection": "",
"Events_TableHead_Duration": "",
"Events_TableHead_DurationOrder": "",
"Events_TableHead_EventType": "",
"Events_TableHead_IP": "",
"Events_TableHead_IPOrder": "",
"Events_TableHead_Order": "",
"Events_TableHead_Owner": "",
"Events_TableHead_PendingAlert": "",
"Events_Table_info": "",
"Events_Table_nav_next": "",
"Events_Table_nav_prev": "",
"Events_Tablelenght": "",
"Events_Tablelenght_all": "",
"Events_Title": "",
"Gen_Action": "",
"Gen_Add": "",
"Gen_Add_All": "",
"Gen_All_Devices": "",
"Gen_AreYouSure": "",
"Gen_Backup": "",
"Gen_Cancel": "",
"Gen_Change": "",
"Gen_Copy": "",
"Gen_DataUpdatedUITakesTime": "",
"Gen_Delete": "",
"Gen_DeleteAll": "",
"Gen_Error": "",
"Gen_Filter": "",
"Gen_LockedDB": "",
"Gen_Offline": "",
"Gen_Okay": "",
"Gen_Purge": "",
"Gen_ReadDocs": "",
"Gen_Remove_All": "",
"Gen_Remove_Last": "",
"Gen_Restore": "",
"Gen_Run": "",
"Gen_Save": "",
"Gen_Saved": "",
"Gen_Search": "",
"Gen_Selected_Devices": "",
"Gen_Switch": "",
"Gen_Upd": "",
"Gen_Upd_Fail": "",
"Gen_Update": "",
"Gen_Update_Value": "",
"Gen_Warning": "",
"Gen_Work_In_Progress": "",
"General_display_name": "",
"General_icon": "",
"HRS_TO_KEEP_NEWDEV_description": "",
"HRS_TO_KEEP_NEWDEV_name": "",
"HelpFAQ_Cat_Detail": "",
"HelpFAQ_Cat_Detail_300_head": "",
"HelpFAQ_Cat_Detail_300_text_a": "",
"HelpFAQ_Cat_Detail_300_text_b": "",
"HelpFAQ_Cat_Detail_301_head_a": "",
"HelpFAQ_Cat_Detail_301_head_b": "",
"HelpFAQ_Cat_Detail_301_text": "",
"HelpFAQ_Cat_Detail_302_head_a": "",
"HelpFAQ_Cat_Detail_302_head_b": "",
"HelpFAQ_Cat_Detail_302_text": "",
"HelpFAQ_Cat_Detail_303_head": "",
"HelpFAQ_Cat_Detail_303_text": "",
"HelpFAQ_Cat_Device_200_head": "",
"HelpFAQ_Cat_Device_200_text": "",
"HelpFAQ_Cat_General": "",
"HelpFAQ_Cat_General_100_head": "",
"HelpFAQ_Cat_General_100_text_a": "",
"HelpFAQ_Cat_General_100_text_b": "",
"HelpFAQ_Cat_General_100_text_c": "",
"HelpFAQ_Cat_General_101_head": "",
"HelpFAQ_Cat_General_101_text": "",
"HelpFAQ_Cat_General_102_head": "",
"HelpFAQ_Cat_General_102_text": "",
"HelpFAQ_Cat_General_102docker_head": "",
"HelpFAQ_Cat_General_102docker_text": "",
"HelpFAQ_Cat_General_103_head": "",
"HelpFAQ_Cat_General_103_text": "",
"HelpFAQ_Cat_Network_600_head": "",
"HelpFAQ_Cat_Network_600_text": "",
"HelpFAQ_Cat_Network_601_head": "",
"HelpFAQ_Cat_Network_601_text": "",
"HelpFAQ_Cat_Presence_400_head": "",
"HelpFAQ_Cat_Presence_400_text": "",
"HelpFAQ_Cat_Presence_401_head": "",
"HelpFAQ_Cat_Presence_401_text": "",
"HelpFAQ_Title": "",
"LOADED_PLUGINS_description": "",
"LOADED_PLUGINS_name": "",
"LOG_LEVEL_description": "",
"LOG_LEVEL_name": "",
"Loading": "",
"Login_Box": "",
"Login_Default_PWD": "",
"Login_Psw-box": "",
"Login_Psw_alert": "",
"Login_Psw_folder": "",
"Login_Psw_new": "",
"Login_Psw_run": "",
"Login_Remember": "",
"Login_Remember_small": "",
"Login_Submit": "",
"Login_Toggle_Alert_headline": "",
"Login_Toggle_Info": "",
"Login_Toggle_Info_headline": "",
"Maint_PurgeLog": "",
"Maint_RestartServer": "",
"Maint_Restart_Server_noti_text": "",
"Maintenance_Running_Version": "",
"Maintenance_Status": "",
"Maintenance_Title": "",
"Maintenance_Tool_ExportCSV": "",
"Maintenance_Tool_ExportCSV_noti": "",
"Maintenance_Tool_ExportCSV_noti_text": "",
"Maintenance_Tool_ExportCSV_text": "",
"Maintenance_Tool_ImportCSV": "",
"Maintenance_Tool_ImportCSV_noti": "",
"Maintenance_Tool_ImportCSV_noti_text": "",
"Maintenance_Tool_ImportCSV_text": "",
"Maintenance_Tool_ImportPastedCSV": "",
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_arpscansw": "",
"Maintenance_Tool_arpscansw_noti": "",
"Maintenance_Tool_arpscansw_noti_text": "",
"Maintenance_Tool_arpscansw_text": "",
"Maintenance_Tool_backup": "",
"Maintenance_Tool_backup_noti": "",
"Maintenance_Tool_backup_noti_text": "",
"Maintenance_Tool_backup_text": "",
"Maintenance_Tool_check_visible": "",
"Maintenance_Tool_darkmode": "",
"Maintenance_Tool_darkmode_noti": "",
"Maintenance_Tool_darkmode_noti_text": "",
"Maintenance_Tool_darkmode_text": "",
"Maintenance_Tool_del_ActHistory": "",
"Maintenance_Tool_del_ActHistory_noti": "",
"Maintenance_Tool_del_ActHistory_noti_text": "",
"Maintenance_Tool_del_ActHistory_text": "",
"Maintenance_Tool_del_alldev": "",
"Maintenance_Tool_del_alldev_noti": "",
"Maintenance_Tool_del_alldev_noti_text": "",
"Maintenance_Tool_del_alldev_text": "",
"Maintenance_Tool_del_allevents": "",
"Maintenance_Tool_del_allevents30": "",
"Maintenance_Tool_del_allevents30_noti": "",
"Maintenance_Tool_del_allevents30_noti_text": "",
"Maintenance_Tool_del_allevents30_text": "",
"Maintenance_Tool_del_allevents_noti": "",
"Maintenance_Tool_del_allevents_noti_text": "",
"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_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_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_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_saved": "",
"settings_system_icon": "",
"settings_system_label": "",
"settings_update_item_warning": "",
"test_event_icon": "",
"test_event_tooltip": ""
}

View File

@@ -28,7 +28,7 @@
"AppEvents_ObjectPrimaryID": "Primär ID", "AppEvents_ObjectPrimaryID": "Primär ID",
"AppEvents_ObjectSecondaryID": "Sekundär ID", "AppEvents_ObjectSecondaryID": "Sekundär ID",
"AppEvents_ObjectStatus": "", "AppEvents_ObjectStatus": "",
"AppEvents_ObjectStatusColumn": "", "AppEvents_ObjectStatusColumn": "Statusspalte",
"AppEvents_ObjectType": "Objekttyp", "AppEvents_ObjectType": "Objekttyp",
"AppEvents_Plugin": "Plugin", "AppEvents_Plugin": "Plugin",
"AppEvents_Type": "Typ", "AppEvents_Type": "Typ",
@@ -98,7 +98,7 @@
"DevDetail_MainInfo_Network_Site": "", "DevDetail_MainInfo_Network_Site": "",
"DevDetail_MainInfo_Network_Title": "<i class=\"fa fa-network-wired\"></i> Network", "DevDetail_MainInfo_Network_Title": "<i class=\"fa fa-network-wired\"></i> Network",
"DevDetail_MainInfo_Owner": "Eigen&shy;tümer", "DevDetail_MainInfo_Owner": "Eigen&shy;tümer",
"DevDetail_MainInfo_SSID": "", "DevDetail_MainInfo_SSID": "SSID",
"DevDetail_MainInfo_Title": "<i class=\"fa fa-pencil\"></i> Hauptinformation", "DevDetail_MainInfo_Title": "<i class=\"fa fa-pencil\"></i> Hauptinformation",
"DevDetail_MainInfo_Type": "Typ", "DevDetail_MainInfo_Type": "Typ",
"DevDetail_MainInfo_Vendor": "Hersteller", "DevDetail_MainInfo_Vendor": "Hersteller",
@@ -126,7 +126,7 @@
"DevDetail_Run_Actions_Tooltip": "Eine Aktion aus der Dropdown-Liste auf dem aktuellen Gerät ausführen.", "DevDetail_Run_Actions_Tooltip": "Eine Aktion aus der Dropdown-Liste auf dem aktuellen Gerät ausführen.",
"DevDetail_SessionInfo_FirstSession": "Erste Sitzung", "DevDetail_SessionInfo_FirstSession": "Erste Sitzung",
"DevDetail_SessionInfo_LastIP": "Letzte IP", "DevDetail_SessionInfo_LastIP": "Letzte IP",
"DevDetail_SessionInfo_LastSession": "Letzte Sitzung", "DevDetail_SessionInfo_LastSession": "Zuletzt offline",
"DevDetail_SessionInfo_StaticIP": "Statische IP", "DevDetail_SessionInfo_StaticIP": "Statische IP",
"DevDetail_SessionInfo_Status": "Status", "DevDetail_SessionInfo_Status": "Status",
"DevDetail_SessionInfo_Title": "<i class=\"fa fa-calendar\"></i> Sitzungsinformation", "DevDetail_SessionInfo_Title": "<i class=\"fa fa-calendar\"></i> Sitzungsinformation",
@@ -202,7 +202,7 @@
"Device_Shortcut_Archived": "Archiviert", "Device_Shortcut_Archived": "Archiviert",
"Device_Shortcut_Connected": "Verbunden", "Device_Shortcut_Connected": "Verbunden",
"Device_Shortcut_Devices": "Geräte", "Device_Shortcut_Devices": "Geräte",
"Device_Shortcut_DownAlerts": "Offline & Nicht erreichbar", "Device_Shortcut_DownAlerts": "Nicht erreichbar & offline",
"Device_Shortcut_DownOnly": "Offline", "Device_Shortcut_DownOnly": "Offline",
"Device_Shortcut_Favorites": "Favoriten", "Device_Shortcut_Favorites": "Favoriten",
"Device_Shortcut_NewDevices": "Neue Geräte", "Device_Shortcut_NewDevices": "Neue Geräte",
@@ -210,12 +210,12 @@
"Device_TableHead_Connected_Devices": "Verbundene Geräte", "Device_TableHead_Connected_Devices": "Verbundene Geräte",
"Device_TableHead_Favorite": "Favorit", "Device_TableHead_Favorite": "Favorit",
"Device_TableHead_FirstSession": "Erste Sitzung", "Device_TableHead_FirstSession": "Erste Sitzung",
"Device_TableHead_GUID": "", "Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Gruppe", "Device_TableHead_Group": "Gruppe",
"Device_TableHead_Icon": "Icon", "Device_TableHead_Icon": "Icon",
"Device_TableHead_LastIP": "Letzte IP", "Device_TableHead_LastIP": "Letzte IP",
"Device_TableHead_LastIPOrder": "Last IP Order", "Device_TableHead_LastIPOrder": "Last IP Order",
"Device_TableHead_LastSession": "Letzte Sitzung", "Device_TableHead_LastSession": "Zuletzt offline",
"Device_TableHead_Location": "Standort", "Device_TableHead_Location": "Standort",
"Device_TableHead_MAC": "MAC", "Device_TableHead_MAC": "MAC",
"Device_TableHead_MAC_full": "Gesamte MAC", "Device_TableHead_MAC_full": "Gesamte MAC",
@@ -226,9 +226,9 @@
"Device_TableHead_Port": "Port", "Device_TableHead_Port": "Port",
"Device_TableHead_RowID": "Zeilen ID", "Device_TableHead_RowID": "Zeilen ID",
"Device_TableHead_Rowid": "Zeilennummer", "Device_TableHead_Rowid": "Zeilennummer",
"Device_TableHead_SSID": "", "Device_TableHead_SSID": "SSID",
"Device_TableHead_Status": "Status", "Device_TableHead_Status": "Status",
"Device_TableHead_SyncHubNodeName": "", "Device_TableHead_SyncHubNodeName": "Synchronisationsknoten",
"Device_TableHead_Type": "Typ", "Device_TableHead_Type": "Typ",
"Device_TableHead_Vendor": "Hersteller", "Device_TableHead_Vendor": "Hersteller",
"Device_Table_Not_Network_Device": "Nicht konfiguriert als Netzwerkgerät", "Device_Table_Not_Network_Device": "Nicht konfiguriert als Netzwerkgerät",
@@ -272,7 +272,7 @@
"Events_TableHead_IPOrder": "IP Order", "Events_TableHead_IPOrder": "IP Order",
"Events_TableHead_Order": "Order", "Events_TableHead_Order": "Order",
"Events_TableHead_Owner": "Eigentümer", "Events_TableHead_Owner": "Eigentümer",
"Events_TableHead_PendingAlert": "", "Events_TableHead_PendingAlert": "Ausstehender Alarm",
"Events_Table_info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen", "Events_Table_info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
"Events_Table_nav_next": "Nächste", "Events_Table_nav_next": "Nächste",
"Events_Table_nav_prev": "Zurück", "Events_Table_nav_prev": "Zurück",
@@ -280,36 +280,37 @@
"Events_Tablelenght_all": "Alle", "Events_Tablelenght_all": "Alle",
"Events_Title": "Ereignisse", "Events_Title": "Ereignisse",
"Gen_Action": "Action", "Gen_Action": "Action",
"Gen_Add": "", "Gen_Add": "Hinzufügen",
"Gen_Add_All": "", "Gen_Add_All": "Alle hinzufügen",
"Gen_All_Devices": "", "Gen_All_Devices": "Alle Geräte",
"Gen_AreYouSure": "Sind Sie sich sicher?", "Gen_AreYouSure": "Sind Sie sich sicher?",
"Gen_Backup": "Sichern", "Gen_Backup": "Sichern",
"Gen_Cancel": "Abbrechen", "Gen_Cancel": "Abbrechen",
"Gen_Change": "",
"Gen_Copy": "Run", "Gen_Copy": "Run",
"Gen_DataUpdatedUITakesTime": "OK - It may take a while for the UI to update if a scan is runnig", "Gen_DataUpdatedUITakesTime": "OK - It may take a while for the UI to update if a scan is runnig",
"Gen_Delete": "Löschen", "Gen_Delete": "Löschen",
"Gen_DeleteAll": "Delete all", "Gen_DeleteAll": "Delete all",
"Gen_Error": "Fehler", "Gen_Error": "Fehler",
"Gen_Filter": "", "Gen_Filter": "Filter",
"Gen_LockedDB": "ERROR - DB eventuell gesperrt - Nutze die Konsole in den Entwickler Werkzeugen (F12) zur Überprüfung oder probiere es später erneut.", "Gen_LockedDB": "ERROR - DB eventuell gesperrt - Nutze die Konsole in den Entwickler Werkzeugen (F12) zur Überprüfung oder probiere es später erneut.",
"Gen_Offline": "", "Gen_Offline": "Offline",
"Gen_Okay": "Ok", "Gen_Okay": "Ok",
"Gen_Purge": "Aufräumen", "Gen_Purge": "Aufräumen",
"Gen_ReadDocs": "Mehr in der Dokumentation", "Gen_ReadDocs": "Mehr in der Dokumentation",
"Gen_Remove_All": "", "Gen_Remove_All": "Alle entfernen",
"Gen_Remove_Last": "", "Gen_Remove_Last": "Letzte entfernen",
"Gen_Restore": "Wiederherstellen", "Gen_Restore": "Wiederherstellen",
"Gen_Run": "Run", "Gen_Run": "Run",
"Gen_Save": "Speichern", "Gen_Save": "Speichern",
"Gen_Saved": "Gespeichert", "Gen_Saved": "Gespeichert",
"Gen_Search": "", "Gen_Search": "Suchen",
"Gen_Selected_Devices": "Ausgewählte Geräte:", "Gen_Selected_Devices": "Ausgewählte Geräte:",
"Gen_Switch": "Umschalten", "Gen_Switch": "Umschalten",
"Gen_Upd": "Aktualisierung erfolgreich", "Gen_Upd": "Aktualisierung erfolgreich",
"Gen_Upd_Fail": "Aktualisierung fehlgeschlagen", "Gen_Upd_Fail": "Aktualisierung fehlgeschlagen",
"Gen_Update": "", "Gen_Update": "Aktualisieren",
"Gen_Update_Value": "", "Gen_Update_Value": "Wert aktualisieren",
"Gen_Warning": "Warnung", "Gen_Warning": "Warnung",
"Gen_Work_In_Progress": "Keine Finalversion, feedback bitte unter: https://github.com/jokob-sk/NetAlertX/issues", "Gen_Work_In_Progress": "Keine Finalversion, feedback bitte unter: https://github.com/jokob-sk/NetAlertX/issues",
"General_display_name": "Allgemein", "General_display_name": "Allgemein",
@@ -353,7 +354,7 @@
"HelpFAQ_Cat_Presence_401_text": "Wenn dies geschieht hast du die Möglickeit, bei dem betreffenden Gerät (Detailsansicht) die Events zu löschen. Eine andere Möglichkeit wäre, das Gerät einzuschalten und zu warten, bis NetAlertX mit dem nächsten Scan das Gerät als \"Online\" erkennt und anschließend das Gerät einfach wieder ausschalten. Nun sollte NetAlertX mit dem nächsten Scan den Zustand des Gerätes ordentlich in der Datenbank vermerken.", "HelpFAQ_Cat_Presence_401_text": "Wenn dies geschieht hast du die Möglickeit, bei dem betreffenden Gerät (Detailsansicht) die Events zu löschen. Eine andere Möglichkeit wäre, das Gerät einzuschalten und zu warten, bis NetAlertX mit dem nächsten Scan das Gerät als \"Online\" erkennt und anschließend das Gerät einfach wieder ausschalten. Nun sollte NetAlertX mit dem nächsten Scan den Zustand des Gerätes ordentlich in der Datenbank vermerken.",
"HelpFAQ_Title": "Hilfe / FAQ", "HelpFAQ_Title": "Hilfe / FAQ",
"LOADED_PLUGINS_description": "", "LOADED_PLUGINS_description": "",
"LOADED_PLUGINS_name": "", "LOADED_PLUGINS_name": "Geladene Plugins",
"LOG_LEVEL_description": "Diese Einstellung aktiviert die erweiterte Protokollierung. Nützlich fürs Debuggen von in die Datenbank geschriebenen Events.", "LOG_LEVEL_description": "Diese Einstellung aktiviert die erweiterte Protokollierung. Nützlich fürs Debuggen von in die Datenbank geschriebenen Events.",
"LOG_LEVEL_name": "Erweiterte Protokollierung", "LOG_LEVEL_name": "Erweiterte Protokollierung",
"Loading": "Laden...", "Loading": "Laden...",
@@ -384,8 +385,8 @@
"MQTT_USER_name": "MQTT user", "MQTT_USER_name": "MQTT user",
"MQTT_display_name": "MQTT", "MQTT_display_name": "MQTT",
"MQTT_icon": "<i class=\"fa fa-square-rss\"></i>", "MQTT_icon": "<i class=\"fa fa-square-rss\"></i>",
"Maint_PurgeLog": "", "Maint_PurgeLog": "Protokoll bereinigen",
"Maint_RestartServer": "", "Maint_RestartServer": "Server neu starten",
"Maint_Restart_Server_noti_text": "", "Maint_Restart_Server_noti_text": "",
"Maintenance_Running_Version": "Installierte Version", "Maintenance_Running_Version": "Installierte Version",
"Maintenance_Status": "Status", "Maintenance_Status": "Status",
@@ -398,7 +399,7 @@
"Maintenance_Tool_ImportCSV_noti": "CSV Import", "Maintenance_Tool_ImportCSV_noti": "CSV Import",
"Maintenance_Tool_ImportCSV_noti_text": "Sind Sie sich sicher, dass Sie die CSV-Datei importieren wollen? Dies wird <b>alle Geräte in der Datenbank überschreiben</b>.", "Maintenance_Tool_ImportCSV_noti_text": "Sind Sie sich sicher, dass Sie die CSV-Datei importieren wollen? Dies wird <b>alle Geräte in der Datenbank überschreiben</b>.",
"Maintenance_Tool_ImportCSV_text": "Machen Sie ein Backup, bevor Sie diese Funk­tion nutzen. Importiere eine CSV-Datei (comma separated values) mit einer Liste aller Geräte und deren Beziehungen zwischen Netzwerkknoten und verbundenen Geräten. Um dies zu tun platziere die <b>devices.csv</b> benannte CSV-Datei in deinen <b>/config</b> Ordner.", "Maintenance_Tool_ImportCSV_text": "Machen Sie ein Backup, bevor Sie diese Funk­tion nutzen. Importiere eine CSV-Datei (comma separated values) mit einer Liste aller Geräte und deren Beziehungen zwischen Netzwerkknoten und verbundenen Geräten. Um dies zu tun platziere die <b>devices.csv</b> benannte CSV-Datei in deinen <b>/config</b> Ordner.",
"Maintenance_Tool_ImportPastedCSV": "", "Maintenance_Tool_ImportPastedCSV": "CSV-Import (Einfügen)",
"Maintenance_Tool_ImportPastedCSV_noti_text": "", "Maintenance_Tool_ImportPastedCSV_noti_text": "",
"Maintenance_Tool_ImportPastedCSV_text": "", "Maintenance_Tool_ImportPastedCSV_text": "",
"Maintenance_Tool_arpscansw": "arp-Scan stoppen/starten", "Maintenance_Tool_arpscansw": "arp-Scan stoppen/starten",
@@ -493,7 +494,7 @@
"NTFY_USER_name": "NTFY user", "NTFY_USER_name": "NTFY user",
"NTFY_display_name": "NTFY", "NTFY_display_name": "NTFY",
"NTFY_icon": "<i class=\"fa fa-terminal\"></i>", "NTFY_icon": "<i class=\"fa fa-terminal\"></i>",
"Navigation_About": "", "Navigation_About": "Über",
"Navigation_Devices": "Geräte", "Navigation_Devices": "Geräte",
"Navigation_Donations": "Donations", "Navigation_Donations": "Donations",
"Navigation_Events": "Ereignisse", "Navigation_Events": "Ereignisse",
@@ -503,10 +504,10 @@
"Navigation_Maintenance": "Wartung", "Navigation_Maintenance": "Wartung",
"Navigation_Monitoring": "Überwachung", "Navigation_Monitoring": "Überwachung",
"Navigation_Network": "Netzwerk", "Navigation_Network": "Netzwerk",
"Navigation_Notifications": "", "Navigation_Notifications": "Benachrichtigungen",
"Navigation_Plugins": "Plugins", "Navigation_Plugins": "Plugins",
"Navigation_Presence": "Anwesenheit", "Navigation_Presence": "Anwesenheit",
"Navigation_Report": "Bericht", "Navigation_Report": "Gesendete Berichte",
"Navigation_Settings": "Einstellungen", "Navigation_Settings": "Einstellungen",
"Navigation_SystemInfo": "Systeminfo", "Navigation_SystemInfo": "Systeminfo",
"Navigation_Workflows": "Arbeitsabläufe", "Navigation_Workflows": "Arbeitsabläufe",
@@ -545,7 +546,7 @@
"Network_Node": "Netzwerkknoten", "Network_Node": "Netzwerkknoten",
"Network_Node_Name": "Knotenname", "Network_Node_Name": "Knotenname",
"Network_Parent": "Übergeordnetes Netzwerkgerät", "Network_Parent": "Übergeordnetes Netzwerkgerät",
"Network_Root": "", "Network_Root": "Wurzelknoten",
"Network_Root_Not_Configured": "", "Network_Root_Not_Configured": "",
"Network_Root_Unconfigurable": "Nicht konfigurierbare Wurzel", "Network_Root_Unconfigurable": "Nicht konfigurierbare Wurzel",
"Network_Table_Hostname": "Gerätename", "Network_Table_Hostname": "Gerätename",
@@ -553,8 +554,8 @@
"Network_Table_State": "Status", "Network_Table_State": "Status",
"Network_Title": "Netzwerkübersicht", "Network_Title": "Netzwerkübersicht",
"Network_UnassignedDevices": "Nicht zugewiesene Geräte", "Network_UnassignedDevices": "Nicht zugewiesene Geräte",
"Notifications_All": "", "Notifications_All": "Alle Benachrichtigungen",
"Notifications_Mark_All_Read": "", "Notifications_Mark_All_Read": "Alle als gelesen markieren",
"PIALERT_WEB_PASSWORD_description": "Das Standardpasswort ist <code>123456</code>. Um das Passwort zu ändern, entweder <code>/app/back/pialert-cli</code> im Container starten oder <a onclick=\"toggleAllSettings()\" href=\"#SETPWD_RUN\"><code>SETPWD_RUN</code> Set password plugin</a> nutzen.", "PIALERT_WEB_PASSWORD_description": "Das Standardpasswort ist <code>123456</code>. Um das Passwort zu ändern, entweder <code>/app/back/pialert-cli</code> im Container starten oder <a onclick=\"toggleAllSettings()\" href=\"#SETPWD_RUN\"><code>SETPWD_RUN</code> Set password plugin</a> nutzen.",
"PIALERT_WEB_PASSWORD_name": "Login-Passwort", "PIALERT_WEB_PASSWORD_name": "Login-Passwort",
"PIALERT_WEB_PROTECTION_description": "Ein Loginfenster wird angezeigt wenn aktiviert. Untere Beschreibung genau durchlesen falls Sie sich aus Ihrer Instanz aussperren.", "PIALERT_WEB_PROTECTION_description": "Ein Loginfenster wird angezeigt wenn aktiviert. Untere Beschreibung genau durchlesen falls Sie sich aus Ihrer Instanz aussperren.",
@@ -609,8 +610,9 @@
"REPORT_WEBHOOK_description": "Enable webhooks for notifications. Webhooks help you to connect to a lot of 3rd party tools, such as IFTTT, Zapier or <a href=\"https://n8n.io/\" target=\"_blank\">n8n</a> to name a few. Check out this simple <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/WEBHOOK_N8N.md\" target=\"_blank\">n8n guide here</a> to get started. If enabled, configure related settings below.", "REPORT_WEBHOOK_description": "Enable webhooks for notifications. Webhooks help you to connect to a lot of 3rd party tools, such as IFTTT, Zapier or <a href=\"https://n8n.io/\" target=\"_blank\">n8n</a> to name a few. Check out this simple <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/WEBHOOK_N8N.md\" target=\"_blank\">n8n guide here</a> to get started. If enabled, configure related settings below.",
"REPORT_WEBHOOK_name": "Enable Webhooks", "REPORT_WEBHOOK_name": "Enable Webhooks",
"RandomMAC_hover": "Autodetected - indicates if the device randomizes it's MAC address.", "RandomMAC_hover": "Autodetected - indicates if the device randomizes it's MAC address.",
"Reports_Sent_Log": "", "Reports_Sent_Log": "Protokoll gesendeter Berichte",
"SCAN_SUBNETS_description": "Arp-scan is a command-line tool that uses the ARP protocol to discover and fingerprint IP hosts on the local network. An alternative to ARP scan is to enable the <a onclick=\"toggleAllSettings()\" href=\"#PIHOLE_RUN\"><code>PIHOLE_RUN</code>PiHole integration settings</a>. The arp-scan time itself depends on the number of IP addresses to check so set this up carefully with the appropriate network mask and interface. Check the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\">subnets documentation</a> for help on setting up VLANs, what VLANs are supported, or how to figure out the network mask and your interface.", "SCAN_SUBNETS_description": "",
"SCAN_SUBNETS_name": "",
"SMTP_FORCE_SSL_description": "Force SSL when connecting to your SMTP server.", "SMTP_FORCE_SSL_description": "Force SSL when connecting to your SMTP server.",
"SMTP_FORCE_SSL_name": "Force SSL", "SMTP_FORCE_SSL_name": "Force SSL",
"SMTP_PASS_description": "The SMTP server password. ", "SMTP_PASS_description": "The SMTP server password. ",
@@ -629,7 +631,7 @@
"Setting_Override": "Override value", "Setting_Override": "Override value",
"Setting_Override_Description": "Enabling this option will override an App supplied default value with the value specified above.", "Setting_Override_Description": "Enabling this option will override an App supplied default value with the value specified above.",
"Settings_Metadata_Toggle": "Show/hide metadata for the given setting.", "Settings_Metadata_Toggle": "Show/hide metadata for the given setting.",
"Settings_device_Scanners_desync": "", "Settings_device_Scanners_desync": "⚠ Die Zeitpläne des Gerätescanners sind nicht synchronisiert.",
"Settings_device_Scanners_desync_popup": "", "Settings_device_Scanners_desync_popup": "",
"Speedtest_Results": "Ergebnisse des Geschwindigkeitstests", "Speedtest_Results": "Ergebnisse des Geschwindigkeitstests",
"Systeminfo_CPU": "CPU", "Systeminfo_CPU": "CPU",
@@ -723,6 +725,8 @@
"UI_PRESENCE_name": "Anzeige im Präsenzdiagramm", "UI_PRESENCE_name": "Anzeige im Präsenzdiagramm",
"UI_REFRESH_description": "", "UI_REFRESH_description": "",
"UI_REFRESH_name": "Automatisch Aktualisieren", "UI_REFRESH_name": "Automatisch Aktualisieren",
"VERSION_description": "",
"VERSION_name": "",
"WEBHOOK_PAYLOAD_description": "The Webhook payload data format for the <code>body</code> > <code>attachments</code> > <code>text</code> attribute in the payload json. See an example of the payload <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/front/report_templates/webhook_json_sample.json\">here</a>. (e.g.: for discord use <code>text</code>)", "WEBHOOK_PAYLOAD_description": "The Webhook payload data format for the <code>body</code> > <code>attachments</code> > <code>text</code> attribute in the payload json. See an example of the payload <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/front/report_templates/webhook_json_sample.json\">here</a>. (e.g.: for discord use <code>text</code>)",
"WEBHOOK_PAYLOAD_name": "Payload type", "WEBHOOK_PAYLOAD_name": "Payload type",
"WEBHOOK_REQUEST_METHOD_description": "The HTTP request method to be used for the webhook call.", "WEBHOOK_REQUEST_METHOD_description": "The HTTP request method to be used for the webhook call.",
@@ -744,31 +748,31 @@
"report_time": "Benachrichtigungszeit:", "report_time": "Benachrichtigungszeit:",
"run_event_icon": "fa-play", "run_event_icon": "fa-play",
"run_event_tooltip": "Enable the setting and save your changes at first before you run it.", "run_event_tooltip": "Enable the setting and save your changes at first before you run it.",
"settings_core_icon": "fa-solid fa-gem", "settings_core_icon": "",
"settings_core_label": "", "settings_core_label": "Kern",
"settings_device_scanners": "", "settings_device_scanners": "",
"settings_device_scanners_icon": "fa-solid fa-magnifying-glass-plus", "settings_device_scanners_icon": "",
"settings_device_scanners_info": "", "settings_device_scanners_info": "",
"settings_device_scanners_label": "Gerätescanner", "settings_device_scanners_label": "Gerätescanner",
"settings_enabled": "Aktive Einstellungen", "settings_enabled": "Aktive Einstellungen",
"settings_enabled_icon": "fa-solid fa-toggle-on", "settings_enabled_icon": "",
"settings_expand_all": "Expand all", "settings_expand_all": "Expand all",
"settings_imported": "Last time settings were imported from the app.conf file:", "settings_imported": "Last time settings were imported from the app.conf file:",
"settings_imported_label": "Einstellungen importiert", "settings_imported_label": "Einstellungen importiert",
"settings_missing": "Not all settings loaded, refresh the page! This is probably caused by a high load on the database or app startup sequence.", "settings_missing": "",
"settings_missing_block": "You can not save your settings without specifying all setting keys. Refresh the page. This is probably caused by a high load on the database.", "settings_missing_block": "",
"settings_old": "Importing settings and re-initializing...", "settings_old": "Importing settings and re-initializing...",
"settings_other_scanners": "", "settings_other_scanners": "",
"settings_other_scanners_icon": "fa-solid fa-recycle", "settings_other_scanners_icon": "",
"settings_other_scanners_label": "Andere Scanner", "settings_other_scanners_label": "Andere Scanner",
"settings_publishers": "", "settings_publishers": "",
"settings_publishers_icon": "fa-solid fa-paper-plane", "settings_publishers_icon": "fa-solid fa-paper-plane",
"settings_publishers_info": "", "settings_publishers_info": "",
"settings_publishers_label": "Veröffentlicher", "settings_publishers_label": "Veröffentlicher",
"settings_saved": "<br/>Settings saved to the <code>app.conf</code> file.<br/><br/>A time-stamped backup of the previous file created. <br/><br/> Reloading...<br/>", "settings_saved": "",
"settings_system_icon": "fa-solid fa-gear", "settings_system_icon": "",
"settings_system_label": "System", "settings_system_label": "System",
"settings_update_item_warning": "", "settings_update_item_warning": "",
"test_event_icon": "fa-vial-circle-check", "test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Save your changes at first before you test your settings." "test_event_tooltip": "Save your changes at first before you test your settings."
} }

View File

@@ -274,6 +274,7 @@
"Gen_AreYouSure": "Are you sure?", "Gen_AreYouSure": "Are you sure?",
"Gen_Backup": "Run Backup", "Gen_Backup": "Run Backup",
"Gen_Cancel": "Cancel", "Gen_Cancel": "Cancel",
"Gen_Change": "Change",
"Gen_Copy": "Run", "Gen_Copy": "Run",
"Gen_DataUpdatedUITakesTime": "OK - It may take a while for the UI to update if a scan is running.", "Gen_DataUpdatedUITakesTime": "OK - It may take a while for the UI to update if a scan is running.",
"Gen_Delete": "Delete", "Gen_Delete": "Delete",
@@ -556,6 +557,7 @@
"RandomMAC_hover": "Autodetected - indicates if the device randomizes it's MAC address.", "RandomMAC_hover": "Autodetected - indicates if the device randomizes it's MAC address.",
"Reports_Sent_Log": "Sent Reports Log", "Reports_Sent_Log": "Sent Reports Log",
"SCAN_SUBNETS_description": "Most on-network scanners (ARP-SCAN, NMAP, NSLOOKUP, DIG, PHOLUS) rely on scanning specific network interfaces and subnets. Check the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\">subnets documentation</a> for help on this setting, especially VLANs, what VLANs are supported, or how to figure out the network mask and your interface. <br/> <br/> An alternative to on-network scanners is to enable some other Device scanners/importers that don't rely on NetAlert<sup>X</sup> having access to the network (UNIFI, dhcp.leases, PiHole, etc.). <br/> <br/> Note: The scan time itself depends on the number of IP addresses to check, so set this up carefully with the appropriate network mask and interface.", "SCAN_SUBNETS_description": "Most on-network scanners (ARP-SCAN, NMAP, NSLOOKUP, DIG, PHOLUS) rely on scanning specific network interfaces and subnets. Check the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\">subnets documentation</a> for help on this setting, especially VLANs, what VLANs are supported, or how to figure out the network mask and your interface. <br/> <br/> An alternative to on-network scanners is to enable some other Device scanners/importers that don't rely on NetAlert<sup>X</sup> having access to the network (UNIFI, dhcp.leases, PiHole, etc.). <br/> <br/> Note: The scan time itself depends on the number of IP addresses to check, so set this up carefully with the appropriate network mask and interface.",
"SCAN_SUBNETS_name": "Networks to scan",
"SYSTEM_TITLE": "System Information", "SYSTEM_TITLE": "System Information",
"Setting_Override": "Override value", "Setting_Override": "Override value",
"Setting_Override_Description": "Enabling this option will override an App supplied default value with the value specified above.", "Setting_Override_Description": "Enabling this option will override an App supplied default value with the value specified above.",
@@ -654,6 +656,8 @@
"UI_PRESENCE_name": "Show in presence chart", "UI_PRESENCE_name": "Show in presence chart",
"UI_REFRESH_description": "Enter number of seconds after which the UI reloads. Set to <code>0</code> to disable.", "UI_REFRESH_description": "Enter number of seconds after which the UI reloads. Set to <code>0</code> to disable.",
"UI_REFRESH_name": "Auto-refresh UI", "UI_REFRESH_name": "Auto-refresh UI",
"VERSION_description": "Version or timestamp helper value to check if app was upgraded.",
"VERSION_name": "Version or timestamp",
"devices_old": "Refreshing...", "devices_old": "Refreshing...",
"general_event_description": "The event you have triggered might take a while until background processes finish. The execution ended once the below execution queue empties (Check the <a href='/maintenance.php#tab_Logging'>error log</a> if you encounter issues). <br/> <br/> Execution queue:", "general_event_description": "The event you have triggered might take a while until background processes finish. The execution ended once the below execution queue empties (Check the <a href='/maintenance.php#tab_Logging'>error log</a> if you encounter issues). <br/> <br/> Execution queue:",
"general_event_title": "Executing an ad-hoc event", "general_event_title": "Executing an ad-hoc event",
@@ -690,4 +694,4 @@
"settings_update_item_warning": "Update the value below. Be careful to follow the previous format. <b>Validation is not performed.</b>", "settings_update_item_warning": "Update the value below. Be careful to follow the previous format. <b>Validation is not performed.</b>",
"test_event_icon": "fa-vial-circle-check", "test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Save your changes at first before you test your settings." "test_event_tooltip": "Save your changes at first before you test your settings."
} }

View File

@@ -284,6 +284,7 @@
"Gen_AreYouSure": "¿Estás seguro?", "Gen_AreYouSure": "¿Estás seguro?",
"Gen_Backup": "Ejecutar copia de seguridad", "Gen_Backup": "Ejecutar copia de seguridad",
"Gen_Cancel": "Cancelar", "Gen_Cancel": "Cancelar",
"Gen_Change": "",
"Gen_Copy": "Ejecutar", "Gen_Copy": "Ejecutar",
"Gen_DataUpdatedUITakesTime": "Correcto - La interfaz puede tardar en actualizarse si se está ejecutando un escaneo.", "Gen_DataUpdatedUITakesTime": "Correcto - La interfaz puede tardar en actualizarse si se está ejecutando un escaneo.",
"Gen_Delete": "Eliminar", "Gen_Delete": "Eliminar",
@@ -723,6 +724,8 @@
"UI_PRESENCE_name": "Mostrar en el gráfico de presencia", "UI_PRESENCE_name": "Mostrar en el gráfico de presencia",
"UI_REFRESH_description": "Ingrese el número de segundos después de los cuales se recarga la interfaz de usuario. Ajustado a <code> 0 </code> para desactivar.", "UI_REFRESH_description": "Ingrese el número de segundos después de los cuales se recarga la interfaz de usuario. Ajustado a <code> 0 </code> para desactivar.",
"UI_REFRESH_name": "Actualización automática de la interfaz de usuario", "UI_REFRESH_name": "Actualización automática de la interfaz de usuario",
"VERSION_description": "",
"VERSION_name": "",
"WEBHOOK_PAYLOAD_description": "El formato de datos de carga de Webhook para el atributo <code>body</code> > <code>attachments</code> > <code>text</code> en el json de carga. Vea un ejemplo de la carga <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/front/report_templates/webhook_json_sample.json\">aquí</a>. (por ejemplo: para discord use <code>text</code>)", "WEBHOOK_PAYLOAD_description": "El formato de datos de carga de Webhook para el atributo <code>body</code> > <code>attachments</code> > <code>text</code> en el json de carga. Vea un ejemplo de la carga <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/blob/main/front/report_templates/webhook_json_sample.json\">aquí</a>. (por ejemplo: para discord use <code>text</code>)",
"WEBHOOK_PAYLOAD_name": "Tipo de carga", "WEBHOOK_PAYLOAD_name": "Tipo de carga",
"WEBHOOK_REQUEST_METHOD_description": "El método de solicitud HTTP que se utilizará para la llamada de webhook.", "WEBHOOK_REQUEST_METHOD_description": "El método de solicitud HTTP que se utilizará para la llamada de webhook.",
@@ -735,7 +738,7 @@
"Webhooks_icon": "<i class=\"fa fa-circle-nodes\"></i>", "Webhooks_icon": "<i class=\"fa fa-circle-nodes\"></i>",
"Webhooks_settings_group": "<i class=\"fa fa-circle-nodes\"></i> Webhooks", "Webhooks_settings_group": "<i class=\"fa fa-circle-nodes\"></i> Webhooks",
"devices_old": "Volviendo a actualizar....", "devices_old": "Volviendo a actualizar....",
"general_event_description": "El evento que ha desencadenado puede tardar un tiempo hasta que finalicen los procesos en segundo plano. La ejecución finalizó una vez que se vac la siguiente cola de ejecución (compruebe el registro de errores <a href='/maintenance.php#tab_Logging'>si</a> tiene problemas). <br/> <br/> Cola de ejecución:", "general_event_description": "El evento que ha activado puede tardar un poco hasta que finalicen los procesos en segundo plano. La ejecución finalizó una vez que se vacía la cola de ejecución a continuación (consulte el <a href='/maintenance.php#tab_Logging'>registro de errores</a> si encuentra problemas). <br/> <br/> Cola de ejecución:",
"general_event_title": "Ejecutar un evento ad-hoc", "general_event_title": "Ejecutar un evento ad-hoc",
"report_guid": "Guía de las notificaciones:", "report_guid": "Guía de las notificaciones:",
"report_guid_missing": "No se ha encontrado la notificación vinculada. Hay un pequeño retraso entre las notificaciones enviadas recientemente y su disponibilidad. Actualiza tu página y la caché después de unos segundos. También es posible que la notificación seleccionada se haya eliminado durante el mantenimiento, tal y como se especifica en la configuración <code>de DBCLNP_NOTIFI_HIST</code>. <br/> <br/>En su lugar, se muestra la notificación más reciente. La notificación que falta tiene el siguiente GUID:", "report_guid_missing": "No se ha encontrado la notificación vinculada. Hay un pequeño retraso entre las notificaciones enviadas recientemente y su disponibilidad. Actualiza tu página y la caché después de unos segundos. También es posible que la notificación seleccionada se haya eliminado durante el mantenimiento, tal y como se especifica en la configuración <code>de DBCLNP_NOTIFI_HIST</code>. <br/> <br/>En su lugar, se muestra la notificación más reciente. La notificación que falta tiene el siguiente GUID:",
@@ -770,4 +773,4 @@
"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>", "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_icon": "fa-vial-circle-check",
"test_event_tooltip": "Guarda tus cambios antes de probar nuevos ajustes." "test_event_tooltip": "Guarda tus cambios antes de probar nuevos ajustes."
} }

794
front/php/templates/language/fr_fr.json Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -274,6 +274,7 @@
"Gen_AreYouSure": "Sei sicuro?", "Gen_AreYouSure": "Sei sicuro?",
"Gen_Backup": "Esegui backup", "Gen_Backup": "Esegui backup",
"Gen_Cancel": "Annulla", "Gen_Cancel": "Annulla",
"Gen_Change": "Modifica",
"Gen_Copy": "Esegui", "Gen_Copy": "Esegui",
"Gen_DataUpdatedUITakesTime": "OK: l'aggiornamento dell'interfaccia utente potrebbe richiedere del tempo se è in esecuzione una scansione.", "Gen_DataUpdatedUITakesTime": "OK: l'aggiornamento dell'interfaccia utente potrebbe richiedere del tempo se è in esecuzione una scansione.",
"Gen_Delete": "Elimina", "Gen_Delete": "Elimina",
@@ -556,6 +557,7 @@
"RandomMAC_hover": "Rilevato automaticamente: indica se il dispositivo genera il suo indirizzo MAC casualmente.", "RandomMAC_hover": "Rilevato automaticamente: indica se il dispositivo genera il suo indirizzo MAC casualmente.",
"Reports_Sent_Log": "Log rapporti inviati", "Reports_Sent_Log": "Log rapporti inviati",
"SCAN_SUBNETS_description": "La maggior parte degli scanner di rete (ARP-SCAN, NMAP, NSLOOKUP, DIG, PHOLUS) si basano sulla scansione di interfacce di rete e sottoreti specifiche. Consulta la <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\">documentazione sulle sottoreti</a> per assistenza su questa impostazione, in particolare VLAN, quali VLAN sono supportate o come individuare la maschera di rete e l'interfaccia. <br/> <br/> Un'alternativa agli scanner in rete è abilitare altri scanner/importatori di dispositivi che non si affidano a NetAlert<sup>X</sup> che hanno accesso alla rete (UNIFI, dhcp.leases , PiHole, ecc.). <br/> <br/> Nota: il tempo di scansione stesso dipende dal numero di indirizzi IP da controllare, quindi impostalo attentamente con la maschera di rete e l'interfaccia appropriate.", "SCAN_SUBNETS_description": "La maggior parte degli scanner di rete (ARP-SCAN, NMAP, NSLOOKUP, DIG, PHOLUS) si basano sulla scansione di interfacce di rete e sottoreti specifiche. Consulta la <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\">documentazione sulle sottoreti</a> per assistenza su questa impostazione, in particolare VLAN, quali VLAN sono supportate o come individuare la maschera di rete e l'interfaccia. <br/> <br/> Un'alternativa agli scanner in rete è abilitare altri scanner/importatori di dispositivi che non si affidano a NetAlert<sup>X</sup> che hanno accesso alla rete (UNIFI, dhcp.leases , PiHole, ecc.). <br/> <br/> Nota: il tempo di scansione stesso dipende dal numero di indirizzi IP da controllare, quindi impostalo attentamente con la maschera di rete e l'interfaccia appropriate.",
"SCAN_SUBNETS_name": "",
"SYSTEM_TITLE": "Informazioni sistema", "SYSTEM_TITLE": "Informazioni sistema",
"Setting_Override": "Sovrascrivi valore", "Setting_Override": "Sovrascrivi valore",
"Setting_Override_Description": "L'abilitazione di questa opzione sovrascriverà il valore predefinito fornito dall'app con il valore specificato sopra.", "Setting_Override_Description": "L'abilitazione di questa opzione sovrascriverà il valore predefinito fornito dall'app con il valore specificato sopra.",
@@ -654,6 +656,8 @@
"UI_PRESENCE_name": "Mostra nel grafico delle presenze", "UI_PRESENCE_name": "Mostra nel grafico delle presenze",
"UI_REFRESH_description": "Inserisci il numero di secondi dopo il quale la UI si ricarica. Imposta a <code>0</code> per disabilitare.", "UI_REFRESH_description": "Inserisci il numero di secondi dopo il quale la UI si ricarica. Imposta a <code>0</code> per disabilitare.",
"UI_REFRESH_name": "Aggiorna automaticamente la UI", "UI_REFRESH_name": "Aggiorna automaticamente la UI",
"VERSION_description": "Valore di supporto della versione o della marca temporale per verificare se l'app è stata aggiornata.",
"VERSION_name": "Versione o marca temporale",
"devices_old": "Aggiornamento...", "devices_old": "Aggiornamento...",
"general_event_description": "L'evento che hai attivato potrebbe richiedere del tempo prima che i processi in background vengano completati. L'esecuzione è terminata una volta che la coda di esecuzione sottostante si è svuotata (controlla il <a href='/maintenance.php#tab_Logging'>log degli errori</a> se riscontri problemi). <br/> <br/> Coda di esecuzione:", "general_event_description": "L'evento che hai attivato potrebbe richiedere del tempo prima che i processi in background vengano completati. L'esecuzione è terminata una volta che la coda di esecuzione sottostante si è svuotata (controlla il <a href='/maintenance.php#tab_Logging'>log degli errori</a> se riscontri problemi). <br/> <br/> Coda di esecuzione:",
"general_event_title": "Esecuzione di un evento ad-hoc", "general_event_title": "Esecuzione di un evento ad-hoc",
@@ -690,4 +694,4 @@
"settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. <b>La convalida non viene eseguita.</b>", "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_icon": "fa-vial-circle-check",
"test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni." "test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni."
} }

View File

@@ -5,7 +5,8 @@
// ################################### // ###################################
$defaultLang = "en_us"; $defaultLang = "en_us";
$allLanguages = ["en_us","es_es","de_de", "nb_no", "pl_pl", "pt_br", "ru_ru", "fr_fr", "it_it", "zh_cn"]; $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"];
global $db; global $db;
@@ -21,6 +22,7 @@ switch($result){
case 'Turkish (tr_tr)': $pia_lang_selected = 'tr_tr'; break; case 'Turkish (tr_tr)': $pia_lang_selected = 'tr_tr'; break;
case 'French': $pia_lang_selected = 'fr_fr'; break; case 'French': $pia_lang_selected = 'fr_fr'; break;
case 'Chinese (zh_cn)': $pia_lang_selected = 'zh_cn'; break; case 'Chinese (zh_cn)': $pia_lang_selected = 'zh_cn'; break;
case 'Czech (cs_cz)': $pia_lang_selected = 'cs_cz'; break;
default: $pia_lang_selected = 'en_us'; break; default: $pia_lang_selected = 'en_us'; break;
} }

View File

@@ -33,6 +33,6 @@ def merge_translations(main_file, other_files):
if __name__ == "__main__": if __name__ == "__main__":
current_path = os.path.dirname(os.path.abspath(__file__)) current_path = os.path.dirname(os.path.abspath(__file__))
# language codes can be found here: http://www.lingoes.net/en/translator/langcode.htm # 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"] 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"]
file_paths = [os.path.join(current_path, file) for file in json_files] file_paths = [os.path.join(current_path, file) for file in json_files]
merge_translations(file_paths[0], file_paths[1:]) merge_translations(file_paths[0], file_paths[1:])

View File

@@ -274,6 +274,7 @@
"Gen_AreYouSure": "Er du sikker?", "Gen_AreYouSure": "Er du sikker?",
"Gen_Backup": "Kjør sikkerhetskopiering", "Gen_Backup": "Kjør sikkerhetskopiering",
"Gen_Cancel": "Avbryt", "Gen_Cancel": "Avbryt",
"Gen_Change": "",
"Gen_Copy": "Kjør", "Gen_Copy": "Kjør",
"Gen_DataUpdatedUITakesTime": "OK - Det kan ta litt tid før brukergrensesnittet oppdateres hvis en skanning kjøres.", "Gen_DataUpdatedUITakesTime": "OK - Det kan ta litt tid før brukergrensesnittet oppdateres hvis en skanning kjøres.",
"Gen_Delete": "Slett", "Gen_Delete": "Slett",
@@ -556,6 +557,7 @@
"RandomMAC_hover": "Autodetektert - indikerer om enheten randomiserer MAC-adressen sin.", "RandomMAC_hover": "Autodetektert - indikerer om enheten randomiserer MAC-adressen sin.",
"Reports_Sent_Log": "Sendte rapport logger", "Reports_Sent_Log": "Sendte rapport logger",
"SCAN_SUBNETS_description": "De fleste skannere på nettet (ARP-Scan, NMAP, NSlookup, Dig, Pholus) er avhengige av å skanne spesifikke nettverksgrensesnitt og undernett. Sjekk <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\">subnett dokumentasjonen</a> for hjelp på denne innstillingen, spesielt VLAN-er, hvilke VLAN-er som støttes, eller hvordan du kan finne ut nettverksmasken og grensesnittet ditt. <br/> <br/> Et alternativ til skannere på nettet er å aktivere noen andre enhetsskannere/importører som ikke er avhengige av Netalert<sup>X</sup> med tilgang til nettverket (UniFi, DHCP-Leaser, Pihole, osv.). <br/> <br/> Merk: Selve skanningstiden avhenger av antall IP -adresser som skal sjekkes, så sett dette opp nøye med riktig nettverksmaske og grensesnitt.", "SCAN_SUBNETS_description": "De fleste skannere på nettet (ARP-Scan, NMAP, NSlookup, Dig, Pholus) er avhengige av å skanne spesifikke nettverksgrensesnitt og undernett. Sjekk <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\">subnett dokumentasjonen</a> for hjelp på denne innstillingen, spesielt VLAN-er, hvilke VLAN-er som støttes, eller hvordan du kan finne ut nettverksmasken og grensesnittet ditt. <br/> <br/> Et alternativ til skannere på nettet er å aktivere noen andre enhetsskannere/importører som ikke er avhengige av Netalert<sup>X</sup> med tilgang til nettverket (UniFi, DHCP-Leaser, Pihole, osv.). <br/> <br/> Merk: Selve skanningstiden avhenger av antall IP -adresser som skal sjekkes, så sett dette opp nøye med riktig nettverksmaske og grensesnitt.",
"SCAN_SUBNETS_name": "",
"SYSTEM_TITLE": "Systeminformasjon", "SYSTEM_TITLE": "Systeminformasjon",
"Setting_Override": "Overstyr verdi", "Setting_Override": "Overstyr verdi",
"Setting_Override_Description": "Aktivering av dette alternativet vil overstyre en App som leveres standard-verdi med verdien som er spesifisert ovenfor.", "Setting_Override_Description": "Aktivering av dette alternativet vil overstyre en App som leveres standard-verdi med verdien som er spesifisert ovenfor.",
@@ -654,6 +656,8 @@
"UI_PRESENCE_name": "Vis i tilstedeværelse-diagrammet", "UI_PRESENCE_name": "Vis i tilstedeværelse-diagrammet",
"UI_REFRESH_description": "Skriv inn antall sekunder før UI laster inn på nytt. Sett til <code>0</code> for å deaktivere.", "UI_REFRESH_description": "Skriv inn antall sekunder før UI laster inn på nytt. Sett til <code>0</code> for å deaktivere.",
"UI_REFRESH_name": "Oppdater UI automatisk", "UI_REFRESH_name": "Oppdater UI automatisk",
"VERSION_description": "",
"VERSION_name": "",
"devices_old": "Oppdaterer...", "devices_old": "Oppdaterer...",
"general_event_description": "Hendelsen du har utløst kan ta en stund til før bakgrunnsprosesser er ferdig. Utførelsen ble avsluttet når utførelseskøen nedenfor tømmes (sjekk <a href='/maintenance.php#tab_Logging'>Feillogg</a> Hvis du møter problemer). <br/> <br/> Utførelseskø:", "general_event_description": "Hendelsen du har utløst kan ta en stund til før bakgrunnsprosesser er ferdig. Utførelsen ble avsluttet når utførelseskøen nedenfor tømmes (sjekk <a href='/maintenance.php#tab_Logging'>Feillogg</a> Hvis du møter problemer). <br/> <br/> Utførelseskø:",
"general_event_title": "Utfører en ad-hoc hendelse", "general_event_title": "Utfører en ad-hoc hendelse",
@@ -690,4 +694,4 @@
"settings_update_item_warning": "Oppdater verdien nedenfor. Pass på å følge forrige format. <b>Validering etterpå utføres ikke.</b>", "settings_update_item_warning": "Oppdater verdien nedenfor. Pass på å følge forrige format. <b>Validering etterpå utføres ikke.</b>",
"test_event_icon": "fa-vial-circle-check", "test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Lagre endringene først, før du tester innstillingene dine." "test_event_tooltip": "Lagre endringene først, før du tester innstillingene dine."
} }

View File

@@ -274,6 +274,7 @@
"Gen_AreYouSure": "Jesteś pewien?", "Gen_AreYouSure": "Jesteś pewien?",
"Gen_Backup": "Wykonaj Kopie Zapasową", "Gen_Backup": "Wykonaj Kopie Zapasową",
"Gen_Cancel": "Anuluj", "Gen_Cancel": "Anuluj",
"Gen_Change": "",
"Gen_Copy": "Wykonaj", "Gen_Copy": "Wykonaj",
"Gen_DataUpdatedUITakesTime": "OK - Aktualizacja UI może chwile potrwać jeżeli wykonywany jest skan.", "Gen_DataUpdatedUITakesTime": "OK - Aktualizacja UI może chwile potrwać jeżeli wykonywany jest skan.",
"Gen_Delete": "Usuń", "Gen_Delete": "Usuń",
@@ -556,6 +557,7 @@
"RandomMAC_hover": "Auto wykrywanie - oznacza czy urządzenie randomizuje swój adres MAC.", "RandomMAC_hover": "Auto wykrywanie - oznacza czy urządzenie randomizuje swój adres MAC.",
"Reports_Sent_Log": "Wyślij zgłoszenie logów", "Reports_Sent_Log": "Wyślij zgłoszenie logów",
"SCAN_SUBNETS_description": "Większość skanerów sieciowych (ARP-SCAN, NMAP, NSLOOKUP, DIG, PHOLUS) opiera się na konkretnych interfejsach sieciowych oraz podsieci. Sprawdź <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\"> dokumentacji podsieci</a> jeżeli potrzebujesz pomocy w ustawieniach, a szczególnie z VLAN'ami, jakie VLAN'y są wspierane oraz jak rozgryźć maskę podsieci twojego interfejsu.<br/><br/> Alternatywą do skanerów sieciowych jest uruchomienie innego Skanera Urządzeń/Importera który nie polega by NetAlert<sup>X</sup> miał dostęp do sieci (UNIFI, dhcp.leases, PiHole, itp.).<br/><br/> Notatka: Czas skanu zależy od liczby adresów IP do sprawdzenia, więc ustaw go tak by skanował odpowiedni interfejs i maskę sieciową.", "SCAN_SUBNETS_description": "Większość skanerów sieciowych (ARP-SCAN, NMAP, NSLOOKUP, DIG, PHOLUS) opiera się na konkretnych interfejsach sieciowych oraz podsieci. Sprawdź <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\"> dokumentacji podsieci</a> jeżeli potrzebujesz pomocy w ustawieniach, a szczególnie z VLAN'ami, jakie VLAN'y są wspierane oraz jak rozgryźć maskę podsieci twojego interfejsu.<br/><br/> Alternatywą do skanerów sieciowych jest uruchomienie innego Skanera Urządzeń/Importera który nie polega by NetAlert<sup>X</sup> miał dostęp do sieci (UNIFI, dhcp.leases, PiHole, itp.).<br/><br/> Notatka: Czas skanu zależy od liczby adresów IP do sprawdzenia, więc ustaw go tak by skanował odpowiedni interfejs i maskę sieciową.",
"SCAN_SUBNETS_name": "",
"SYSTEM_TITLE": "Informacje o Systemie", "SYSTEM_TITLE": "Informacje o Systemie",
"Setting_Override": "Nadpisz wartość", "Setting_Override": "Nadpisz wartość",
"Setting_Override_Description": "Włączanie tej opcji nadpisze podstawową wartość na wartość podaną powyżej.", "Setting_Override_Description": "Włączanie tej opcji nadpisze podstawową wartość na wartość podaną powyżej.",
@@ -654,6 +656,8 @@
"UI_PRESENCE_name": "Pokaż w tabeli obecności", "UI_PRESENCE_name": "Pokaż w tabeli obecności",
"UI_REFRESH_description": "Wprowadź liczbę sekund po której UI ma się przeładować. Ustaw na <code>0</code> by wyłączyć.", "UI_REFRESH_description": "Wprowadź liczbę sekund po której UI ma się przeładować. Ustaw na <code>0</code> by wyłączyć.",
"UI_REFRESH_name": "Automatycznie odświeżaj UI", "UI_REFRESH_name": "Automatycznie odświeżaj UI",
"VERSION_description": "",
"VERSION_name": "",
"devices_old": "Odświeżanie...", "devices_old": "Odświeżanie...",
"general_event_description": "Wydarzenie które wyzwoliłeś może chwilę zająć dopóki procesy w tle nie zakończą się. Wykonanie zakończy się kiedy kolejka się opróżni (Sprawdź <a href='/maintenance.php#tab_Logging'>logi błędów</a> jeżeli napotkasz błędy).<br/><br/> Kolejka wykonywania:", "general_event_description": "Wydarzenie które wyzwoliłeś może chwilę zająć dopóki procesy w tle nie zakończą się. Wykonanie zakończy się kiedy kolejka się opróżni (Sprawdź <a href='/maintenance.php#tab_Logging'>logi błędów</a> jeżeli napotkasz błędy).<br/><br/> Kolejka wykonywania:",
"general_event_title": "Wykonywanie wydarzeń ad-hoc", "general_event_title": "Wykonywanie wydarzeń ad-hoc",
@@ -690,4 +694,4 @@
"settings_update_item_warning": "Zaktualizuj poniższą wartość. Zachowaj ostrożność i postępuj zgodnie z poprzednim formatem. <b>Walidacja nie jest wykonywana.</b>", "settings_update_item_warning": "Zaktualizuj poniższą wartość. Zachowaj ostrożność i postępuj zgodnie z poprzednim formatem. <b>Walidacja nie jest wykonywana.</b>",
"test_event_icon": "fa-vial-circle-check", "test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Zapisz zmiany zanim będziesz testować swoje ustawienia." "test_event_tooltip": "Zapisz zmiany zanim będziesz testować swoje ustawienia."
} }

View File

@@ -3,7 +3,7 @@
"API_CUSTOM_SQL_name": "Endpoint customizado", "API_CUSTOM_SQL_name": "Endpoint customizado",
"API_display_name": "API", "API_display_name": "API",
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>", "API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
"About_Design": "Desenhado por:", "About_Design": "Desenvolvido por:",
"About_Exit": "Sair", "About_Exit": "Sair",
"About_Title": "Analisador de segurança de rede & framework de notificação", "About_Title": "Analisador de segurança de rede & framework de notificação",
"AppEvents_DateTimeCreated": "Registrado em", "AppEvents_DateTimeCreated": "Registrado em",
@@ -145,7 +145,7 @@
"DevDetail_Tab_NmapTableText": "Configure uma programação em <a href=\"/settings.php#NMAP_ACTIVE\">Configurações</a>", "DevDetail_Tab_NmapTableText": "Configure uma programação em <a href=\"/settings.php#NMAP_ACTIVE\">Configurações</a>",
"DevDetail_Tab_NmapTableTime": "Tempo", "DevDetail_Tab_NmapTableTime": "Tempo",
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"> </i> Plugins", "DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"> </i> Plugins",
"DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"> Presença", "DevDetail_Tab_Presence": "<i class=\"fa fa-calendar\"></i> Presença",
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessões", "DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Sessões",
"DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Ferramentas", "DevDetail_Tab_Tools": "<i class=\"fa fa-screwdriver-wrench\"></i> Ferramentas",
"DevDetail_Tab_Tools_Internet_Info_Description": "A ferramenta info Internet exibe informações sobre a conexão com a Internet, como endereço IP, cidade, país, código de área e fuso horário.", "DevDetail_Tab_Tools_Internet_Info_Description": "A ferramenta info Internet exibe informações sobre a conexão com a Internet, como endereço IP, cidade, país, código de área e fuso horário.",
@@ -202,7 +202,7 @@
"Device_TableHead_Group": "Grupo", "Device_TableHead_Group": "Grupo",
"Device_TableHead_Icon": "Ícone", "Device_TableHead_Icon": "Ícone",
"Device_TableHead_LastIP": "Último IP", "Device_TableHead_LastIP": "Último IP",
"Device_TableHead_LastIPOrder": "", "Device_TableHead_LastIPOrder": "Último pedido de IP",
"Device_TableHead_LastSession": "Último off-line", "Device_TableHead_LastSession": "Último off-line",
"Device_TableHead_Location": "Localização", "Device_TableHead_Location": "Localização",
"Device_TableHead_MAC": "MAC aleatório", "Device_TableHead_MAC": "MAC aleatório",
@@ -233,7 +233,7 @@
"ENABLE_PLUGINS_description": "Ativa a funcionalidade de <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a>. Carregar plug-ins requer mais recursos de hardware, então você pode querer desativá-los em sistemas de baixa potência.", "ENABLE_PLUGINS_description": "Ativa a funcionalidade de <a target=\"_blank\" href=\"https://github.com/jokob-sk/NetAlertX/tree/main/front/plugins\">plugins</a>. Carregar plug-ins requer mais recursos de hardware, então você pode querer desativá-los em sistemas de baixa potência.",
"ENABLE_PLUGINS_name": "Habilitar plug-ins", "ENABLE_PLUGINS_name": "Habilitar plug-ins",
"Email_display_name": "Email", "Email_display_name": "Email",
"Email_icon": "<i class=\"fa fa-at\">", "Email_icon": "<i class=\"fa fa-at\"></i>",
"Events_Loading": "Carregando...", "Events_Loading": "Carregando...",
"Events_Periodselect_All": "Todas as informações", "Events_Periodselect_All": "Todas as informações",
"Events_Periodselect_LastMonth": "Mês passado", "Events_Periodselect_LastMonth": "Mês passado",
@@ -242,7 +242,7 @@
"Events_Periodselect_today": "Hoje", "Events_Periodselect_today": "Hoje",
"Events_Searchbox": "Procurar", "Events_Searchbox": "Procurar",
"Events_Shortcut_AllEvents": "Todos os eventos", "Events_Shortcut_AllEvents": "Todos os eventos",
"Events_Shortcut_DownAlerts": "", "Events_Shortcut_DownAlerts": "Alertas de queda",
"Events_Shortcut_Events": "Eventos", "Events_Shortcut_Events": "Eventos",
"Events_Shortcut_MissSessions": "Sessões ausentes", "Events_Shortcut_MissSessions": "Sessões ausentes",
"Events_Shortcut_NewDevices": "Novos dispositivos", "Events_Shortcut_NewDevices": "Novos dispositivos",
@@ -254,76 +254,77 @@
"Events_TableHead_Device": "Dispositivo", "Events_TableHead_Device": "Dispositivo",
"Events_TableHead_Disconnection": "Desconexão", "Events_TableHead_Disconnection": "Desconexão",
"Events_TableHead_Duration": "Duração", "Events_TableHead_Duration": "Duração",
"Events_TableHead_DurationOrder": "", "Events_TableHead_DurationOrder": "Duração do pedido",
"Events_TableHead_EventType": "Tipo de evento", "Events_TableHead_EventType": "Tipo de evento",
"Events_TableHead_IP": "IP", "Events_TableHead_IP": "IP",
"Events_TableHead_IPOrder": "", "Events_TableHead_IPOrder": "Pedido de IP",
"Events_TableHead_Order": "Ordem", "Events_TableHead_Order": "Ordem",
"Events_TableHead_Owner": "Proprietário", "Events_TableHead_Owner": "Proprietário",
"Events_TableHead_PendingAlert": "", "Events_TableHead_PendingAlert": "Alerta Pendente",
"Events_Table_info": "", "Events_Table_info": "Mostrando_START_ to _END_ of _TOTAL_ entradas",
"Events_Table_nav_next": "", "Events_Table_nav_next": "Próxima",
"Events_Table_nav_prev": "", "Events_Table_nav_prev": "Anterior",
"Events_Tablelenght": "", "Events_Tablelenght": "Mostrar entradas do _MENU_",
"Events_Tablelenght_all": "", "Events_Tablelenght_all": "Todos",
"Events_Title": "", "Events_Title": "Eventos",
"Gen_Action": "", "Gen_Action": "Ação",
"Gen_Add": "", "Gen_Add": "Adicionar",
"Gen_Add_All": "", "Gen_Add_All": "Adicionar todos",
"Gen_All_Devices": "", "Gen_All_Devices": "Todos os Dispositivos",
"Gen_AreYouSure": "", "Gen_AreYouSure": "Tem certeza?",
"Gen_Backup": "", "Gen_Backup": "Executar backup",
"Gen_Cancel": "", "Gen_Cancel": "Cancelar",
"Gen_Copy": "", "Gen_Change": "",
"Gen_DataUpdatedUITakesTime": "", "Gen_Copy": "Executar",
"Gen_Delete": "", "Gen_DataUpdatedUITakesTime": "OK - Pode levar um tempo para a interface do usuário ser atualizada se uma verificação estiver em execução.",
"Gen_DeleteAll": "", "Gen_Delete": "Excluir",
"Gen_Error": "", "Gen_DeleteAll": "Excluir todos",
"Gen_Filter": "", "Gen_Error": "Erro",
"Gen_LockedDB": "", "Gen_Filter": "Filtro",
"Gen_Offline": "", "Gen_LockedDB": "ERRO - O banco de dados pode estar bloqueado - Verifique F12 Ferramentas de desenvolvimento -> Console ou tente mais tarde.",
"Gen_Okay": "", "Gen_Offline": "Offline",
"Gen_Purge": "", "Gen_Okay": "Ok",
"Gen_ReadDocs": "", "Gen_Purge": "Purge",
"Gen_Remove_All": "", "Gen_ReadDocs": "Leia mais em documentos.",
"Gen_Remove_Last": "", "Gen_Remove_All": "Remover tudo",
"Gen_Restore": "", "Gen_Remove_Last": "Remover o último",
"Gen_Run": "", "Gen_Restore": "Executar restauração",
"Gen_Save": "", "Gen_Run": "Executar",
"Gen_Saved": "", "Gen_Save": "Salvar",
"Gen_Search": "", "Gen_Saved": "Salvo",
"Gen_Selected_Devices": "", "Gen_Search": "Procurar",
"Gen_Switch": "", "Gen_Selected_Devices": "Dispositivos selecionados:",
"Gen_Upd": "", "Gen_Switch": "Trocar",
"Gen_Upd_Fail": "", "Gen_Upd": "Atualizado com sucesso",
"Gen_Update": "", "Gen_Upd_Fail": "A atualização falhou",
"Gen_Update_Value": "", "Gen_Update": "Atualizar",
"Gen_Warning": "", "Gen_Update_Value": "Atualizar valor",
"Gen_Work_In_Progress": "", "Gen_Warning": "Aviso",
"General_display_name": "", "Gen_Work_In_Progress": "Trabalho em andamento, um bom momento para enviar feedback em https://github.com/jokob-sk/NetAlertX/issues",
"General_icon": "", "General_display_name": "Geral",
"HRS_TO_KEEP_NEWDEV_description": "", "General_icon": "<i class=\"fa fa-gears\"></i>",
"HRS_TO_KEEP_NEWDEV_name": "", "HRS_TO_KEEP_NEWDEV_description": "Esta é uma configuração de manutenção. Se habilitada (<code>0</code> is disabled), dispositivos marcados como <b>Novo Dispositivo</b> serão excluídos se o tempo de <b>Primeira Sessão</b> for mais antigo que as horas especificadas nesta configuração. Use esta configuração se quiser excluir automaticamente <b>Novos Dispositivos</b> após <code>X</code> horas.",
"HelpFAQ_Cat_Detail": "", "HRS_TO_KEEP_NEWDEV_name": "Manter novos dispositivos por",
"HelpFAQ_Cat_Detail_300_head": "", "HelpFAQ_Cat_Detail": "Detalhes",
"HelpFAQ_Cat_Detail_300_text_a": "", "HelpFAQ_Cat_Detail_300_head": "O que significa ",
"HelpFAQ_Cat_Detail_300_text_b": "", "HelpFAQ_Cat_Detail_300_text_a": "Significa um dispositivo de rede (um dispositivo do tipo AP, Gateway, Firewall, Hypervisor, Powerline, Switch, WLAN, PLC, Roteador, Adaptador LAN USB, Adaptador Wi-Fi USB ou Internet). Tipos personalizados podem ser adicionados através da configuração <code>NETWORK_DEVICE_TYPES</code>.",
"HelpFAQ_Cat_Detail_301_head_a": "", "HelpFAQ_Cat_Detail_300_text_b": "Indica o número da porta onde o dispositivo atualmente em edição está conectado a este dispositivo de rede. Leia <a target='_blank' href='https://github.com/jokob-sk/NetAlertX/blob/main/docs/NETWORK_TREE.md'>este guia</a> para mais informações.",
"HelpFAQ_Cat_Detail_301_head_a": "Quando está escaneando agora? ",
"HelpFAQ_Cat_Detail_301_head_b": "", "HelpFAQ_Cat_Detail_301_head_b": "",
"HelpFAQ_Cat_Detail_301_text": "", "HelpFAQ_Cat_Detail_301_text": "O intervalo de tempo entre as verificações é definido pelo 'Cronjob', que está configurado para 5min por padrão. A designação '1min' refere-se à duração esperada da verificação. Dependendo da configuração da rede, esse tempo pode variar. Para editar o cronjob, você pode usar o seguinte comando no terminal/console <span class='text-danger help_faq_code'>crontab -e</span> e alterar o intervalo.",
"HelpFAQ_Cat_Detail_302_head_a": "", "HelpFAQ_Cat_Detail_302_head_a": "",
"HelpFAQ_Cat_Detail_302_head_b": "", "HelpFAQ_Cat_Detail_302_head_b": "E por que não posso selecionar isso?",
"HelpFAQ_Cat_Detail_302_text": "", "HelpFAQ_Cat_Detail_302_text": "Alguns dispositivos modernos geram endereços MAC aleatórios por razões de privacidade, que não podem mais ser associados a nenhum fabricante e que mudam a cada nova conexão. O NetAlertX detecta se é um endereço MAC aleatório e ativa este 'campo' automaticamente. Para desativar esse comportamento, você deve verificar no seu dispositivo como desativar a randomização do endereço MAC.",
"HelpFAQ_Cat_Detail_303_head": "", "HelpFAQ_Cat_Detail_303_head": "O que é o Nmap e para que serve?",
"HelpFAQ_Cat_Detail_303_text": "", "HelpFAQ_Cat_Detail_303_text": "Nmap é um scanner de rede com múltiplas capacidades.<br>Quando um novo dispositivo aparece na sua lista, você tem a possibilidade de obter informações mais detalhadas sobre o dispositivo através da varredura do Nmap.",
"HelpFAQ_Cat_Device_200_head": "", "HelpFAQ_Cat_Device_200_head": "Eu tenho dispositivos na minha lista dos quais não sei nada. Após excluí-los, eles sempre reaparecem.",
"HelpFAQ_Cat_Device_200_text": "", "HelpFAQ_Cat_Device_200_text": "Se você usar o Pi-hole, observe que o NetAlertX recupera informações do Pi-hole. Pause o NetAlertX, vá até a página de configurações no Pi-hole e exclua o lease DHCP, se necessário. Em seguida, também no Pi-hole, vá em Ferramentas -> Rede para ver se consegue encontrar os hosts recorrentes lá. Se encontrar, exclua-os também. Agora você pode iniciar o NetAlertX novamente. Os dispositivos não devem mais aparecer.",
"HelpFAQ_Cat_General": "", "HelpFAQ_Cat_General": "Geral",
"HelpFAQ_Cat_General_100_head": "", "HelpFAQ_Cat_General_100_head": "O relógio no canto superior direito e os horários dos eventos/presença não estão corretos (diferença de horário).",
"HelpFAQ_Cat_General_100_text_a": "", "HelpFAQ_Cat_General_100_text_a": "No seu PC, o seguinte fuso horário está configurado para o ambiente PHP:",
"HelpFAQ_Cat_General_100_text_b": "", "HelpFAQ_Cat_General_100_text_b": "Se este não for o fuso horário em que você está, você deve alterar o fuso horário no arquivo de configuração do PHP. Você pode encontrá-lo neste diretório:",
"HelpFAQ_Cat_General_100_text_c": "", "HelpFAQ_Cat_General_100_text_c": "Pesquise neste arquivo pela entrada \"date.timezone\", remova o ponto e vírgula inicial \";\" se necessário, e insira o fuso horário desejado. Uma lista com os fusos horários suportados pode ser encontrada aqui (<a href='https://www.php.net/manual/en/timezones.php' target='blank'>Link</a>)",
"HelpFAQ_Cat_General_101_head": "", "HelpFAQ_Cat_General_101_head": "Minha rede parece estar lenta, o streaming fica \"congelado\".",
"HelpFAQ_Cat_General_101_text": "", "HelpFAQ_Cat_General_101_text": "",
"HelpFAQ_Cat_General_102_head": "", "HelpFAQ_Cat_General_102_head": "",
"HelpFAQ_Cat_General_102_text": "", "HelpFAQ_Cat_General_102_text": "",
@@ -556,6 +557,7 @@
"RandomMAC_hover": "", "RandomMAC_hover": "",
"Reports_Sent_Log": "", "Reports_Sent_Log": "",
"SCAN_SUBNETS_description": "", "SCAN_SUBNETS_description": "",
"SCAN_SUBNETS_name": "",
"SYSTEM_TITLE": "", "SYSTEM_TITLE": "",
"Setting_Override": "", "Setting_Override": "",
"Setting_Override_Description": "", "Setting_Override_Description": "",
@@ -654,6 +656,8 @@
"UI_PRESENCE_name": "", "UI_PRESENCE_name": "",
"UI_REFRESH_description": "", "UI_REFRESH_description": "",
"UI_REFRESH_name": "", "UI_REFRESH_name": "",
"VERSION_description": "",
"VERSION_name": "",
"devices_old": "", "devices_old": "",
"general_event_description": "", "general_event_description": "",
"general_event_title": "", "general_event_title": "",
@@ -690,4 +694,4 @@
"settings_update_item_warning": "", "settings_update_item_warning": "",
"test_event_icon": "", "test_event_icon": "",
"test_event_tooltip": "" "test_event_tooltip": ""
} }

View File

@@ -274,6 +274,7 @@
"Gen_AreYouSure": "Вы уверены?", "Gen_AreYouSure": "Вы уверены?",
"Gen_Backup": "Запустить резервное копирование", "Gen_Backup": "Запустить резервное копирование",
"Gen_Cancel": "Отмена", "Gen_Cancel": "Отмена",
"Gen_Change": "Изменить",
"Gen_Copy": "Запустить", "Gen_Copy": "Запустить",
"Gen_DataUpdatedUITakesTime": "ОК - Обновление UI может занять некоторое время, если сканирование выполняется.", "Gen_DataUpdatedUITakesTime": "ОК - Обновление UI может занять некоторое время, если сканирование выполняется.",
"Gen_Delete": "Удалить", "Gen_Delete": "Удалить",
@@ -416,7 +417,7 @@
"Maintenance_Tool_del_unknowndev_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Все названные устройства (неизвестные) будут удалены из базы данных.", "Maintenance_Tool_del_unknowndev_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Удаление невозможно отменить. Все названные устройства (неизвестные) будут удалены из базы данных.",
"Maintenance_Tool_displayed_columns_text": "Измените видимость и порядок столбцов на странице <a href=\"devices.php\"><b> <i class=\"fa fa-laptop\"></i> Устройства</b></a>.", "Maintenance_Tool_displayed_columns_text": "Измените видимость и порядок столбцов на странице <a href=\"devices.php\"><b> <i class=\"fa fa-laptop\"></i> Устройства</b></a>.",
"Maintenance_Tool_drag_me": "Перетащите элемент, чтобы изменить порядок столбцов.", "Maintenance_Tool_drag_me": "Перетащите элемент, чтобы изменить порядок столбцов.",
"Maintenance_Tool_order_columns_text": "", "Maintenance_Tool_order_columns_text": "Maintenance_Tool_order_columns_text",
"Maintenance_Tool_purgebackup": "Очистить резервные копии", "Maintenance_Tool_purgebackup": "Очистить резервные копии",
"Maintenance_Tool_purgebackup_noti": "Очистить резервные копии", "Maintenance_Tool_purgebackup_noti": "Очистить резервные копии",
"Maintenance_Tool_purgebackup_noti_text": "Вы уверены, что хотите удалить все резервные копии, кроме трех последних?", "Maintenance_Tool_purgebackup_noti_text": "Вы уверены, что хотите удалить все резервные копии, кроме трех последних?",
@@ -556,6 +557,7 @@
"RandomMAC_hover": "Автоматически обнаружено — указывает, рандомизирует ли устройство свой MAC-адрес.", "RandomMAC_hover": "Автоматически обнаружено — указывает, рандомизирует ли устройство свой MAC-адрес.",
"Reports_Sent_Log": "Отправить журнал логов", "Reports_Sent_Log": "Отправить журнал логов",
"SCAN_SUBNETS_description": "Большинство сетевых сканеров (ARP-SCAN, NMAP, NSLOOKUP, DIG, PHOLUS) полагаются на сканирование определенных сетевых интерфейсов и подсетей. Дополнительную информацию по этому параметру можно найти в <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\">документации по подсетям</a>, особенно VLAN, какие VLAN поддерживаются или как разобраться в маске сети и своем интерфейсе. <br/> <br/> Альтернативой сетевым сканерам является включение некоторых других сканеров/импортеров устройств, которые не полагаются на NetAlert<sup>X</sup>, имеющий доступ к сети (UNIFI, dhcp.leases , PiHole и др.). <br/> <br/> Примечание. Само время сканирования зависит от количества проверяемых IP-адресов, поэтому тщательно настройте его, указав соответствующую маску сети и интерфейс.", "SCAN_SUBNETS_description": "Большинство сетевых сканеров (ARP-SCAN, NMAP, NSLOOKUP, DIG, PHOLUS) полагаются на сканирование определенных сетевых интерфейсов и подсетей. Дополнительную информацию по этому параметру можно найти в <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md\" target=\"_blank\">документации по подсетям</a>, особенно VLAN, какие VLAN поддерживаются или как разобраться в маске сети и своем интерфейсе. <br/> <br/> Альтернативой сетевым сканерам является включение некоторых других сканеров/импортеров устройств, которые не полагаются на NetAlert<sup>X</sup>, имеющий доступ к сети (UNIFI, dhcp.leases , PiHole и др.). <br/> <br/> Примечание. Само время сканирования зависит от количества проверяемых IP-адресов, поэтому тщательно настройте его, указав соответствующую маску сети и интерфейс.",
"SCAN_SUBNETS_name": "",
"SYSTEM_TITLE": "Системная информация", "SYSTEM_TITLE": "Системная информация",
"Setting_Override": "Переопределить значение", "Setting_Override": "Переопределить значение",
"Setting_Override_Description": "Включение этой опции приведет к переопределению значения по умолчанию, предоставленного приложением, на значение, указанное выше.", "Setting_Override_Description": "Включение этой опции приведет к переопределению значения по умолчанию, предоставленного приложением, на значение, указанное выше.",
@@ -654,6 +656,8 @@
"UI_PRESENCE_name": "Показать в диаграмме присутствия", "UI_PRESENCE_name": "Показать в диаграмме присутствия",
"UI_REFRESH_description": "Введите количество секунд, по истечении которых пользовательский интерфейс перезагружается. Установите значение <code>0</code>, чтобы отключить.", "UI_REFRESH_description": "Введите количество секунд, по истечении которых пользовательский интерфейс перезагружается. Установите значение <code>0</code>, чтобы отключить.",
"UI_REFRESH_name": "Автоматическое обновление интерфейса", "UI_REFRESH_name": "Автоматическое обновление интерфейса",
"VERSION_description": "Вспомогательное значение версии или метки времени, позволяющее проверить, было ли приложение обновлено.",
"VERSION_name": "Версия или временная метка",
"devices_old": "Актуализируется...", "devices_old": "Актуализируется...",
"general_event_description": "Событие, которое вы инициировали, может занять некоторое время, прежде чем фоновые процессы завершатся. Выполнение завершится, как только очередь выполнения, указанная ниже, опустеет (Проверьте <a href='/maintenance.php#tab_Logging'>журнал ошибок</a> при возникновении проблем). <br/> <br/>· · Очередь выполнения:", "general_event_description": "Событие, которое вы инициировали, может занять некоторое время, прежде чем фоновые процессы завершатся. Выполнение завершится, как только очередь выполнения, указанная ниже, опустеет (Проверьте <a href='/maintenance.php#tab_Logging'>журнал ошибок</a> при возникновении проблем). <br/> <br/>· · Очередь выполнения:",
"general_event_title": "Выполнение специального события", "general_event_title": "Выполнение специального события",
@@ -690,4 +694,4 @@
"settings_update_item_warning": "Обновить значение ниже. Будьте осторожны, следуя предыдущему формату. <b>Проверка не выполняется.</b>", "settings_update_item_warning": "Обновить значение ниже. Будьте осторожны, следуя предыдущему формату. <b>Проверка не выполняется.</b>",
"test_event_icon": "fa-vial-circle-check", "test_event_icon": "fa-vial-circle-check",
"test_event_tooltip": "Сначала сохраните изменения, прежде чем проверять настройки." "test_event_tooltip": "Сначала сохраните изменения, прежде чем проверять настройки."
} }

View File

@@ -274,6 +274,7 @@
"Gen_AreYouSure": "Emin misiniz?", "Gen_AreYouSure": "Emin misiniz?",
"Gen_Backup": "", "Gen_Backup": "",
"Gen_Cancel": "İptal", "Gen_Cancel": "İptal",
"Gen_Change": "",
"Gen_Copy": "Çalıştır", "Gen_Copy": "Çalıştır",
"Gen_DataUpdatedUITakesTime": "TAMAM - Eğer bir tarama çalışıyorsa arayüzün güncellenmesi biraz zaman alabilir", "Gen_DataUpdatedUITakesTime": "TAMAM - Eğer bir tarama çalışıyorsa arayüzün güncellenmesi biraz zaman alabilir",
"Gen_Delete": "Sil", "Gen_Delete": "Sil",
@@ -556,6 +557,7 @@
"RandomMAC_hover": "", "RandomMAC_hover": "",
"Reports_Sent_Log": "", "Reports_Sent_Log": "",
"SCAN_SUBNETS_description": "", "SCAN_SUBNETS_description": "",
"SCAN_SUBNETS_name": "",
"SYSTEM_TITLE": "", "SYSTEM_TITLE": "",
"Setting_Override": "", "Setting_Override": "",
"Setting_Override_Description": "", "Setting_Override_Description": "",
@@ -654,6 +656,8 @@
"UI_PRESENCE_name": "", "UI_PRESENCE_name": "",
"UI_REFRESH_description": "", "UI_REFRESH_description": "",
"UI_REFRESH_name": "", "UI_REFRESH_name": "",
"VERSION_description": "",
"VERSION_name": "",
"devices_old": "Yenileniyor...", "devices_old": "Yenileniyor...",
"general_event_description": "", "general_event_description": "",
"general_event_title": "", "general_event_title": "",
@@ -690,4 +694,4 @@
"settings_update_item_warning": "", "settings_update_item_warning": "",
"test_event_icon": "", "test_event_icon": "",
"test_event_tooltip": "" "test_event_tooltip": ""
} }

File diff suppressed because it is too large Load Diff

View File

@@ -4,9 +4,9 @@
// ## GUI settings processing start // ## GUI settings processing start
// ################################### // ###################################
if( isset($_COOKIE['Front_Dark_Mode_Enabled'])) if( isset($_COOKIE['UI_dark_mode']))
{ {
$ENABLED_DARKMODE = $_COOKIE['Front_Dark_Mode_Enabled'] == "true"; $ENABLED_DARKMODE = $_COOKIE['UI_dark_mode'] == "True";
}else }else
{ {
$ENABLED_DARKMODE = False; $ENABLED_DARKMODE = False;

View File

@@ -11,12 +11,12 @@ NetAlertX supports additional plugins to extend its functionality, each with its
> You can load additional Plugins via the General -> `LOADED_PLUGINS` setting. Use `Ctrl + Click` to select/deselect. > You can load additional Plugins via the General -> `LOADED_PLUGINS` setting. Use `Ctrl + Click` to select/deselect.
1. Pick your `🔍 dev scanner` plugin (e.g. `ARPSCAN` or `NMAPDEV`), or import devices into the application with an `📥 importer` plugin. (See **✅Enabling plugins** below) 1. Pick your `🔍 dev scanner` plugin (e.g. `ARPSCAN` or `NMAPDEV`), or import devices into the application with an `📥 importer` plugin. (See **✅Enabling plugins** below)
1. Pick a `▶️ publisher` plugin, if you want to send notifications. If you don't see a publisher you'd like to use, look at the [📚_publisher_apprise](/front/plugins/_publisher_apprise/) plugin which is a proxy for over 80 notification services. 2. Pick a `▶️ publisher` plugin, if you want to send notifications. If you don't see a publisher you'd like to use, look at the [📚_publisher_apprise](/front/plugins/_publisher_apprise/) plugin which is a proxy for over 80 notification services.
1. Setup your [Network topology diagram](/docs/NETWORK_TREE.md) 3. Setup your [Network topology diagram](/docs/NETWORK_TREE.md)
1. Fine-tune [Notifications](/docs/NOTIFICATIONS.md) 4. Fine-tune [Notifications](/docs/NOTIFICATIONS.md)
1. [Backup your setup](/docs/BACKUPS.md) 5. [Backup your setup](/docs/BACKUPS.md)
1. Contribute and [Create custom plugins](/docs/PLUGINS_DEV.md) 6. Contribute and [Create custom plugins](/docs/PLUGINS_DEV.md)
1. Consider [donating](https://github.com/jokob-sk/NetAlertX?tab=readme-ov-file#-sponsors) to keep me going 7. Consider [donating](https://github.com/jokob-sk/NetAlertX?tab=readme-ov-file#-sponsors) to keep me going
## 📑 Available Plugins ## 📑 Available Plugins
@@ -44,7 +44,7 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
| `NSLOOKUP` | ♻ | NSLookup (DNS-based) name resolution | | | Script | [nslookup_scan](/front/plugins/nslookup_scan/) | | `NSLOOKUP` | ♻ | NSLookup (DNS-based) name resolution | | | Script | [nslookup_scan](/front/plugins/nslookup_scan/) |
| `NTFPRCS` | ⚙ | Notification processing | | Yes | Template | [notification_processing](/front/plugins/notification_processing/)| | `NTFPRCS` | ⚙ | Notification processing | | Yes | Template | [notification_processing](/front/plugins/notification_processing/)|
| `NTFY` | ▶️ | NTFY notifications | | | Script | [_publisher_ntfy](/front/plugins/_publisher_ntfy/) | | `NTFY` | ▶️ | NTFY notifications | | | Script | [_publisher_ntfy](/front/plugins/_publisher_ntfy/) |
| `OMDSDN` | 📥 | OMADA TP-Link import | 📊🔄 | | Script | [omada_sdn_imp](/front/plugins/omada_sdn_imp/) | | `OMDSDN` | 📥 | OMADA TP-Link import | 🖧 🔄 | | Script | [omada_sdn_imp](/front/plugins/omada_sdn_imp/) |
| `PHOLUS` | ♻ | Pholus name resolution | | | Script | [pholus_scan](/front/plugins/pholus_scan/) | | `PHOLUS` | ♻ | Pholus name resolution | | | Script | [pholus_scan](/front/plugins/pholus_scan/) |
| `PIHOLE` | 🔍/📥 | Pi-hole device import & sync | | | SQLite DB | [pihole_scan](/front/plugins/pihole_scan/) | | `PIHOLE` | 🔍/📥 | Pi-hole device import & sync | | | SQLite DB | [pihole_scan](/front/plugins/pihole_scan/) |
| `PUSHSAFER` | ▶️ | Pushsafer notifications | | | Script | [_publisher_pushsafer](/front/plugins/_publisher_pushsafer/) | | `PUSHSAFER` | ▶️ | Pushsafer notifications | | | Script | [_publisher_pushsafer](/front/plugins/_publisher_pushsafer/) |
@@ -52,9 +52,10 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
| `SETPWD` | ⚙ | Set password | | Yes | Template | [set_password](/front/plugins/set_password/) | | `SETPWD` | ⚙ | Set password | | Yes | Template | [set_password](/front/plugins/set_password/) |
| `SMTP` | ▶️ | Email notifications | | | Script | [_publisher_email](/front/plugins/_publisher_email/) | | `SMTP` | ▶️ | Email notifications | | | Script | [_publisher_email](/front/plugins/_publisher_email/) |
| `SNMPDSC` | 🔍/📥 | SNMP device import & sync | | | Script | [snmp_discovery](/front/plugins/snmp_discovery/) | | `SNMPDSC` | 🔍/📥 | SNMP device import & sync | | | Script | [snmp_discovery](/front/plugins/snmp_discovery/) |
| `SYNC` | 🔍/⚙/📥| Sync & import from NetAlertX instances | 📊🔄 | | Script | [sync](/front/plugins/sync/) | | `SYNC` | 🔍/⚙/📥| Sync & import from NetAlertX instances | 🖧 🔄 | | Script | [sync](/front/plugins/sync/) |
| `TELEGRAM` | ▶️ | Telegram notifications | | | Script | [_publisher_telegram](/front/plugins/_publisher_telegram/) |
| `UNDIS` | 🔍/📥 | Create dummy devices | | | Script | [undiscoverables](/front/plugins/undiscoverables/) | | `UNDIS` | 🔍/📥 | Create dummy devices | | | Script | [undiscoverables](/front/plugins/undiscoverables/) |
| `UNFIMP` | 🔍/📥 | UniFi device import & sync | | | Script | [unifi_import](/front/plugins/unifi_import/) | | `UNFIMP` | 🔍/📥 | UniFi device import & sync | 🖧 | | Script | [unifi_import](/front/plugins/unifi_import/) |
| `VNDRPDT` | ⚙ | Vendor database update | | | Script | [vendor_update](/front/plugins/vendor_update/) | | `VNDRPDT` | ⚙ | Vendor database update | | | Script | [vendor_update](/front/plugins/vendor_update/) |
| `WEBHOOK` | ▶️ | Webhook notifications | | | Script | [_publisher_webhook](/front/plugins/_publisher_webhook/) | | `WEBHOOK` | ▶️ | Webhook notifications | | | Script | [_publisher_webhook](/front/plugins/_publisher_webhook/) |
| `WEBMON` | ♻ | Website down monitoring | | | Script | [website_monitor](/front/plugins/website_monitor/) | | `WEBMON` | ♻ | Website down monitoring | | | Script | [website_monitor](/front/plugins/website_monitor/) |
@@ -81,7 +82,7 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
| Icon | Description | | Icon | Description |
|------|---------------------------------------------------------------| |------|---------------------------------------------------------------|
| 📊 | Auto-imports the network topology diagram | | 🖧 | Auto-imports the network topology diagram |
| 🔄 | Has the option to sync some data back into the plugin source | | 🔄 | Has the option to sync some data back into the plugin source |

View File

@@ -767,8 +767,8 @@
{ "elementType": "select", "elementOptions": [], "transformers": [] } { "elementType": "select", "elementOptions": [], "transformers": [] }
] ]
}, },
"default_value": 1, "default_value": 5,
"options": [1, 2], "options": [3, 5],
"localized": ["name", "description"], "localized": ["name", "description"],
"name": [ "name": [
{ {
@@ -779,7 +779,7 @@
"description": [ "description": [
{ {
"language_code": "en_us", "language_code": "en_us",
"string": "Paho MQTT API version. Depends on the MQTT <a href=\"https://eclipse.dev/paho/files/paho.mqtt.python/html/index.html#callbacks\" target=\"_blank\">version supported by the MQTT broker</a>. Usually set to <code>1</code>." "string": "MQTT Protocol version. Depends on the MQTT broker</a>. Usually set to <code>5</code>, or <code>3</code> for backwards compatibility."
} }
] ]
}, },

View File

@@ -196,7 +196,10 @@ class sensor_config:
def publish_mqtt(mqtt_client, topic, message): def publish_mqtt(mqtt_client, topic, message):
status = 1 status = 1
message = json.dumps(message).replace("'",'"') # convert anything but a simple string to json
if not isinstance(message, str):
message = json.dumps(message).replace("'",'"')
qos = get_setting_value('MQTT_QOS') qos = get_setting_value('MQTT_QOS')
mylog('verbose', [f"[{pluginName}] Sending MQTT topic: {topic}"]) mylog('verbose', [f"[{pluginName}] Sending MQTT topic: {topic}"])
@@ -268,20 +271,23 @@ def create_sensor(mqtt_client, deviceId, deviceName, sensorType, sensorName, ico
return sensorConfig return sensorConfig
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
def mqtt_create_client(): def mqtt_create_client():
mytransport = 'tcp' # or 'websockets'
def on_disconnect(mqtt_client, userdata, reason_code): def on_disconnect(mqtt_client, userdata, reason_code):
global mqtt_connected_to_broker global mqtt_connected_to_broker
# REF: If we wanted a auto reconnect, a good source is here: https://www.emqx.com/en/blog/how-to-use-mqtt-in-python
mqtt_connected_to_broker = False mqtt_connected_to_broker = False
mylog('debug', [f"[{pluginName}] Connection terminated, reason_code: {reason_code}"])
# not sure is below line is correct / necessary
# client = mqtt_create_client()
def on_connect(mqtt_client, userdata, flags, reason_code): def on_connect(mqtt_client, userdata, flags, reason_code, properties):
global mqtt_connected_to_broker global mqtt_connected_to_broker
# REF: Good docu on reason codes: https://www.emqx.com/en/blog/mqtt5-new-features-reason-code-and-ack
if reason_code == 0: if reason_code == 0:
mylog('verbose', [f"[{pluginName}] Connected to broker"]) mylog('verbose', [f"[{pluginName}] Connected to broker"])
mqtt_connected_to_broker = True # Signal connection mqtt_connected_to_broker = True # Signal connection
@@ -289,21 +295,29 @@ def mqtt_create_client():
mylog('verbose', [f"[{pluginName}] Connection failed, reason_code: {reason_code}"]) mylog('verbose', [f"[{pluginName}] Connection failed, reason_code: {reason_code}"])
mqtt_connected_to_broker = False mqtt_connected_to_broker = False
global mqtt_client global mqtt_client
if get_setting_value('MQTT_VERSION') == 1: # Paho will be soon not supporting V1 anymore, so this really should not be a user choice to start with
mqtt_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1) # This code now uses V2 by default
# Ref: https://eclipse.dev/paho/files/paho.mqtt.python/html/migrations.html
if get_setting_value('MQTT_VERSION') == 3:
version = mqtt.MQTTv311
else: else:
mqtt_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) version = mqtt.MQTTv5
mqtt_client = mqtt.Client(
callback_api_version = mqtt.CallbackAPIVersion.VERSION2,
transport=mytransport,
protocol=mqtt.MQTTv5)
mqtt_client.on_connect = on_connect
mqtt_client.on_disconnect = on_disconnect
if get_setting_value('MQTT_TLS'): if get_setting_value('MQTT_TLS'):
mqtt_client.tls_set() mqtt_client.tls_set()
mqtt_client.username_pw_set(get_setting_value('MQTT_USER'), get_setting_value('MQTT_PASSWORD')) mqtt_client.username_pw_set(username = get_setting_value('MQTT_USER'), password = get_setting_value('MQTT_PASSWORD'))
mqtt_client.on_connect = on_connect mqtt_client.connect(host = get_setting_value('MQTT_BROKER'), port = get_setting_value('MQTT_PORT'))
mqtt_client.on_disconnect = on_disconnect
mqtt_client.connect(get_setting_value('MQTT_BROKER'), get_setting_value('MQTT_PORT'))
mqtt_client.loop_start() mqtt_client.loop_start()
return mqtt_client return mqtt_client
@@ -364,7 +378,7 @@ def mqtt_start(db):
# Create devices in Home Assistant - send config messages # Create devices in Home Assistant - send config messages
deviceId = 'mac_' + device["dev_MAC"].replace(" ", "").replace(":", "_").lower() deviceId = 'mac_' + device["dev_MAC"].replace(" ", "").replace(":", "_").lower()
devDisplayName = re.sub('[^a-zA-Z0-9-_\s]', '', device["dev_Name"]) devDisplayName = re.sub('[^a-zA-Z0-9-_\\s]', '', device["dev_Name"])
sensorConfig = create_sensor(mqtt_client, deviceId, devDisplayName, 'sensor', 'last_ip', 'ip-network', device["dev_MAC"]) 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', 'mac_address', 'folder-key-network', device["dev_MAC"])

View File

@@ -0,0 +1,10 @@
## Overview
You can send notifications via Telegram
## Notes
You need Telegram bot to send notifications
### Usage
- Go to settings and fill in relevant details.

View File

@@ -0,0 +1,470 @@
{
"code_name": "_publisher_telegram",
"unique_prefix": "TELEGRAM",
"plugin_type": "publisher",
"enabled": true,
"data_source": "script",
"show_ui": true,
"localized": ["display_name", "description", "icon"],
"display_name": [
{
"language_code": "en_us",
"string": "Telegram publisher"
}
],
"icon": [
{
"language_code": "en_us",
"string": "<i class=\"fa-solid fa-bullhorn\"></i>"
}
],
"description": [
{
"language_code": "en_us",
"string": "A plugin to publish a notification via Telegram."
}
],
"params": [],
"database_column_definitions": [
{
"column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
}
]
},
{
"column": "Plugin",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
}
]
},
{
"column": "Object_PrimaryID",
"css_classes": "col-sm-2",
"show": false,
"type": "url",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
}
]
},
{
"column": "Object_SecondaryID",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
}
]
},
{
"column": "DateTimeCreated",
"css_classes": "col-sm-2",
"show": true,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Sent when"
}
]
},
{
"column": "DateTimeChanged",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Changed"
},
{
"language_code": "es_es",
"string": "Cambiado"
}
]
},
{
"column": "Watched_Value1",
"css_classes": "col-sm-2",
"show": true,
"type": "eval",
"default_value": "",
"options": [
{
"type": "eval",
"param": "`<a href='/report.php?guid=${value}'>${value}</a>`"
}
],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Notification GUID"
}
]
},
{
"column": "Watched_Value2",
"css_classes": "col-sm-8",
"show": true,
"type": "textarea_readonly",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Result"
}
]
},
{
"column": "Watched_Value3",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
}
]
},
{
"column": "Watched_Value4",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "N/A"
},
{
"language_code": "es_es",
"string": "N/A"
}
]
},
{
"column": "UserData",
"css_classes": "col-sm-2",
"show": false,
"type": "textbox_save",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Comments"
},
{
"language_code": "es_es",
"string": "Comentarios"
}
]
},
{
"column": "Status",
"css_classes": "col-sm-1",
"show": false,
"type": "replace",
"default_value": "",
"options": [
{
"equals": "watched-not-changed",
"replacement": "<div style='text-align:center'><i class='fa-solid fa-square-check'></i><div></div>"
},
{
"equals": "watched-changed",
"replacement": "<div style='text-align:center'><i class='fa-solid fa-triangle-exclamation'></i></div>"
},
{
"equals": "new",
"replacement": "<div style='text-align:center'><i class='fa-solid fa-circle-plus'></i></div>"
},
{
"equals": "missing-in-last-scan",
"replacement": "<div style='text-align:center'><i class='fa-solid fa-question'></i></div>"
}
],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Status"
},
{
"language_code": "es_es",
"string": "Estado"
}
]
},
{
"column": "Extra",
"css_classes": "col-sm-3",
"show": false,
"type": "label",
"default_value": "",
"options": [],
"localized": ["name"],
"name": [
{
"language_code": "en_us",
"string": "Extra"
},
{
"language_code": "es_es",
"string": "Extra"
}
]
}
],
"settings": [
{
"function": "RUN",
"events": ["test"],
"type": {
"dataType": "string",
"elements": [
{ "elementType": "select", "elementOptions": [], "transformers": [] }
]
},
"default_value": "disabled",
"options": ["disabled", "on_notification"],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "When to run"
},
{
"language_code": "es_es",
"string": "Cuando ejecuta"
}
],
"description": [
{
"language_code": "en_us",
"string": "Enable sending notifications via a Telegram messanger"
}
]
},
{
"function": "CMD",
"type": {
"dataType": "string",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "readonly": "true" }],
"transformers": []
}
]
},
"default_value": "python3 /app/front/plugins/_publisher_telegram/tg.py",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Command"
},
{
"language_code": "es_es",
"string": "Comando"
}
],
"description": [
{
"language_code": "en_us",
"string": "Command to run"
},
{
"language_code": "es_es",
"string": "Comando a ejecutar"
}
]
},
{
"function": "RUN_TIMEOUT",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 10,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Run timeout"
},
{
"language_code": "es_es",
"string": "Tiempo de espera de ejecución"
},
{
"language_code": "de_de",
"string": "Wartezeit"
}
],
"description": [
{
"language_code": "en_us",
"string": "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted."
},
{
"language_code": "es_es",
"string": "Tiempo máximo en segundos para esperar a que finalice el script. Si se supera este tiempo, el script se cancela."
}
]
},
{
"function": "HOST",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Telegram chat id"
}
],
"description": [
{
"language_code": "en_us",
"string": "Telegram chat id. If you want to send messages to user, paste user id (Example: <code>1234123412</code>)"
}
]
},
{
"function": "URL",
"type": {
"dataType": "string",
"elements": [
{ "elementType": "input", "elementOptions": [], "transformers": [] }
]
},
"default_value": "",
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Telegram bot token"
}
],
"description": [
{
"language_code": "en_us",
"string": "Telegram bot token. You cat get at from <a target=\"_blank\" href=\"https://t.me/BotFather\">BotFather</a>"
}
]
},
{
"function": "SIZE",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"default_value": 1024,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Max payload size"
},
{
"language_code": "es_es",
"string": "Tamaño máximo de carga útil"
}
],
"description": [
{
"language_code": "en_us",
"string": "The maximum size of the payload as number of characters in the passed string. If above limit, it will be truncated and a <code>(text was truncated)</code> message is appended."
}
]
}
]
}

View File

@@ -0,0 +1,124 @@
#!/usr/bin/env python
import json
import subprocess
import argparse
import os
import pathlib
import sys
from datetime import datetime
# Register NetAlertX directories
INSTALL_PATH = "/app"
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
import conf
from const import confFileName
from plugin_helper import Plugin_Objects
from logger import mylog, append_line_to_file
from helper import timeNowTZ, get_setting_value
from notification import Notification_obj
from database import DB
from pytz import timezone
# Make sure the TIMEZONE for logging is correct
conf.tz = timezone(get_setting_value('TIMEZONE'))
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log')
pluginName = 'TELEGRAM'
def main():
mylog('verbose', [f'[{pluginName}](publisher) In script'])
# Check if basic config settings supplied
if check_config() == False:
mylog('none', [
f'[{pluginName}] ⚠ ERROR: Publisher notification gateway not set up correctly. Check your {confFileName} {pluginName}_* variables.'])
return
# Create a database connection
db = DB() # instance of class DB
db.open()
# Initialize the Plugin obj output file
plugin_objects = Plugin_Objects(RESULT_FILE)
# Create a Notification_obj instance
notifications = Notification_obj(db)
# Retrieve new notifications
new_notifications = notifications.getNew()
# Process the new notifications (see the Notifications DB table for structure or check the /api/table_notifications.json endpoint)
for notification in new_notifications:
# Send notification
result = send(notification["Text"])
# Log result
plugin_objects.add_object(
primaryId=pluginName,
secondaryId=timeNowTZ(),
watched1=notification["GUID"],
watched2=result,
watched3='null',
watched4='null',
extra='null',
foreignKey=notification["GUID"]
)
plugin_objects.write_result_file()
# -------------------------------------------------------------------------------
def check_config():
return True
# -------------------------------------------------------------------------------
def send(text):
# limit = 1024 * 1024 # 1MB limit (1024 bytes * 1024 bytes = 1MB)
limit = get_setting_value('TELEGRAM_SIZE')
if len(text) > limit:
payloadData = text[:limit] + " (text was truncated)"
else:
payloadData = text
try:
# try runnning a subprocess
req = """curl --location 'https://api.telegram.org/bot%s/sendMessage' \\
--header 'Content-Type: application/json' \\
--data '{
"chat_id": "%s",
"text": "%s",
"disable_notification": false
}'""" % (get_setting_value('TELEGRAM_URL'), get_setting_value('TELEGRAM_HOST'), payloadData)
mylog('debug', [req])
p = subprocess.Popen(req, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
stdout, stderr = p.communicate()
# write stdout and stderr into .log files for debugging if needed
# Log the stdout and stderr
mylog('debug', [stdout, stderr])
# log result
result = stdout
except subprocess.CalledProcessError as e:
# An error occurred, handle it
mylog('none', [e.output])
# log result
result = e.output
return result
if __name__ == '__main__':
sys.exit(main())

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@@ -6,3 +6,7 @@ A plugin to publish a notification via the Webhook gateway. Webhooks help you to
- Go to settings and fill in relevant details. - Go to settings and fill in relevant details.
#### Sample Discord Setup
![image](Discord_Config.png)

View File

@@ -147,8 +147,9 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP
# Cleanup New Devices # Cleanup New Devices
if HRS_TO_KEEP_NEWDEV != 0: 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)']) mylog('verbose', [f'[{pluginName}] Devices: Delete all New Devices older than {str(HRS_TO_KEEP_NEWDEV)} hours (HRS_TO_KEEP_NEWDEV setting)'])
cursor.execute (f"""DELETE FROM Devices query = f"""DELETE FROM Devices WHERE dev_NewDevice = 1 AND dev_FirstConnection < date('now', '-{str(HRS_TO_KEEP_NEWDEV)} hour')"""
WHERE dev_NewDevice = 1 AND dev_FirstConnection < date('now', '+{str(HRS_TO_KEEP_NEWDEV)} hour')""") mylog('verbose', [f'[{pluginName}] Query: {query} '])
cursor.execute (query)
# ----------------------------------------------------- # -----------------------------------------------------
# Cleanup Pholus_Scan # Cleanup Pholus_Scan

View File

@@ -1,7 +1,7 @@
{ {
"code_name": "mikrotik_scan", "code_name": "mikrotik_scan",
"unique_prefix": "MTSCAN", "unique_prefix": "MTSCAN",
"plugin_type": "other", "plugin_type": "device_scanner",
"execution_order" : "Layer_4", "execution_order" : "Layer_4",
"enabled": true, "enabled": true,
"data_source": "script", "data_source": "script",
@@ -11,7 +11,7 @@
"display_name": [ "display_name": [
{ {
"language_code": "en_us", "language_code": "en_us",
"string": "Mikrotik (Name discovery)" "string": "Mikrotik (Device discovery)"
} }
], ],
"icon": [ "icon": [
@@ -23,7 +23,7 @@
"description": [ "description": [
{ {
"language_code": "en_us", "language_code": "en_us",
"string": "A plugin to discover device names." "string": "A plugin to discover devices via Mikrotik."
} }
], ],
"params": [ "params": [

View File

@@ -1,6 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# test script by running:
# tbc
import os import os
import pathlib import pathlib
@@ -36,46 +34,39 @@ CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
LOG_FILE = os.path.join(CUR_PATH, 'script.log') LOG_FILE = os.path.join(CUR_PATH, 'script.log')
RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log') RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log')
pluginName = 'NSLOOKUP' pluginName = 'MTSCAN'
def main(): def main():
mylog('verbose', [f'[{pluginName}] In script']) mylog('verbose', [f'[{pluginName}] In script'])
mt_host = get_setting_value('MTSCAN_MT_HOST') # init global variables
mt_port = get_setting_value('MTSCAN_MT_PORT') global MT_HOST, MT_PORT, MT_USER, MT_PASS
mt_user = get_setting_value('MTSCAN_MT_USER')
mt_password = get_setting_value('MTSCAN_MT_PASS')
#mylog('verbose', [f'[{pluginName}] Router: {mt_host}:{mt_port} user: {mt_user}, pass: {mt_password}'])
# Create a database connection
db = DB() # instance of class DB
db.open()
# Initialize the Plugin obj output file # Initialize the Plugin obj output file
plugin_objects = Plugin_Objects(RESULT_FILE) plugin_objects = Plugin_Objects(RESULT_FILE)
# Create a Device_obj instance # Mikrotik settings
device_handler = Device_obj(db) MT_HOST = get_setting_value('MTSCAN_MT_HOST')
MT_PORT = get_setting_value('MTSCAN_MT_PORT')
MT_USER = get_setting_value('MTSCAN_MT_USER')
MT_PASS = get_setting_value('MTSCAN_MT_PASS')
# Retrieve devices plugin_objects = get_entries(plugin_objects)
#unknown_devices = device_handler.getUnknown()
#mylog('verbose', [f'[{pluginName}] Unknown devices count: {len(unknown_devices)}'])
all_devices = device_handler.getAll() plugin_objects.write_result_file()
mylog('verbose', [f'[{pluginName}] Scan finished, found {len(plugin_objects)} devices'])
mylog('verbose', [f'[{pluginName}] all devices count: {len(all_devices)}'])
device_map = {d['dev_MAC']:d['dev_LastIP'] for d in all_devices} def get_entries(plugin_objects: Plugin_Objects) -> Plugin_Objects:
try: try:
# connect router # connect router
api = connect(username=mt_user, password=mt_password, host=mt_host, port=mt_port) api = connect(username=MT_USER, password=MT_PASS, host=MT_HOST, port=MT_PORT)
# get dhcp leases # get dhcp leases
leases = api('/ip/dhcp-server/lease/print') leases = api('/ip/dhcp-server/lease/print')
for lease in leases: for lease in leases:
lease_id = lease.get('.id') lease_id = lease.get('.id')
@@ -84,56 +75,31 @@ def main():
host_name = lease.get('host-name') host_name = lease.get('host-name')
comment = lease.get('comment') comment = lease.get('comment')
last_seen = lease.get('last-seen') last_seen = lease.get('last-seen')
status = lease.get('status')
mylog('verbose', [f"ID: {lease_id}, Address: {address}, MAC Address: {mac_address}, Host Name: {host_name}, Comment: {comment}, Last Seen: {last_seen}"]) mylog('verbose', [f"ID: {lease_id}, Address: {address}, MAC Address: {mac_address}, Host Name: {host_name}, Comment: {comment}, Last Seen: {last_seen}, Status: {status}"])
if mac_address in device_map.keys():
device_name = host_name if (status == "bound"):
if comment != '':
device_name = comment
plugin_objects.add_object( plugin_objects.add_object(
# "Name-MAC", "LastIP", "IP", "Name","Host","LastSeen","Comment"
primaryId = mac_address, primaryId = mac_address,
secondaryId = device_map[mac_address], secondaryId = '',
watched1 = address, watched1 = address,
watched2 = device_name, watched2 = host_name,
watched3 = host_name, watched3 = last_seen,
watched4 = last_seen, watched4 = '',
extra = '', extra = '',
helpVal1 = comment, helpVal1 = comment,
foreignKey = mac_address) foreignKey = mac_address)
plugin_objects.write_result_file()
except TrapError as e: except TrapError as e:
mylog('error', [f"An error occurred: {e}"]) mylog('error', [f"An error occurred: {e}"])
except Exception as e: except Exception as e:
mylog('error', [f"Failed to connect to MikroTik API: {e}"]) mylog('error', [f"Failed to connect to MikroTik API: {e}"])
#for device in unknown_devices:
# domain_name, dns_server = execute_nslookup(device['dev_LastIP'], timeout)
# if domain_name != '':
# plugin_objects.add_object(
# # "MAC", "IP", "Server", "Name"
# primaryId = device['dev_MAC'],
# secondaryId = device['dev_LastIP'],
# watched1 = dns_server,
# watched2 = domain_name,
# watched3 = '',
# watched4 = '',
# extra = '',
# foreignKey = device['dev_MAC'])
#plugin_objects.write_result_file()
mylog('verbose', [f'[{pluginName}] Script finished']) mylog('verbose', [f'[{pluginName}] Script finished'])
return 0 return plugin_objects
#=============================================================================== #===============================================================================
# BEGIN # BEGIN

View File

@@ -3,7 +3,7 @@
NMAP-scan is a command-line tool to discover and fingerprint IP hosts on the local network. The NMAP-scan (and other Network-scan plugin times using the `SCAN_SUBNETS` setting) time depends on the number of IP addresses to check so set this up carefully with the appropriate network mask and interface. Check the [subnets documentation](https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md) for help with setting up VLANs, what VLANs are supported, or how to figure out the network mask and your interface. NMAP-scan is a command-line tool to discover and fingerprint IP hosts on the local network. The NMAP-scan (and other Network-scan plugin times using the `SCAN_SUBNETS` setting) time depends on the number of IP addresses to check so set this up carefully with the appropriate network mask and interface. Check the [subnets documentation](https://github.com/jokob-sk/NetAlertX/blob/main/docs/SUBNETS.md) for help with setting up VLANs, what VLANs are supported, or how to figure out the network mask and your interface.
> [!NOTE] > [!NOTE]
> The `NMAPDEV` plugin is great for detecting the availability of devices, however ARP scan might be better covering multiple VLANS. You can always combine different scan methods. You can find all available network scanning options (marked as `🔍 dev scanner`) in the [Plugins overview](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md) readme. > The `NMAPDEV` plugin is great for detecting the availability of devices, however ARP scan might be better covering multiple VLANS and subnets as NMAP can't pickup the MAC address from other subnets (this is an NMAP limitation) which are necessary to identify a device. You can always combine different scan methods. You can find all available network scanning options (marked as `🔍 dev scanner`) in the [Plugins overview](https://github.com/jokob-sk/NetAlertX/blob/main/front/plugins/README.md) readme.
### Usage ### Usage

View File

@@ -1,285 +0,0 @@
import re
""""
how to rebuild and re-run...
savefolder=~/naxdev/NetAlertX.v7
cd ~/naxdev
mv NetAlertX $savefolder
gh repo clone FlyingToto/NetAlertX
cd NetAlertX
ln -s ../docker-compose.yml.ffsb42 .
ln -s ../.env.omada.ffsb42 .
cd front/plugins/omada_sdn_imp/
cp -p $savefoder/front/plugins/omada_sdn_imp/omada_sdn.py* .
cp -p $savefoder/front/plugins/omada_sdn_imp/README.md .
cp -p $savefoder/front/plugins/omada_sdn_imp/omada_account_sample.png .
cp -p $savefoder/front/plugins/omada_sdn_imp/testre.py .
#cp -p $savefoder/front/plugins/omada_sdn_imp/config.json config.json.v6
cd ~/naxdev/NetAlertX
sudo docker-compose --env-file .env.omada.ffsb42 -f ./docker-compose.yml.ffsb42 up
to gather data for Boris:
today=$(date +%Y_%m_%d__%H_%M)
mkdir /drives/c/temp/4boris/$today
cd /drives/c/temp/4boris/$today
scp hal:~/naxdev/logs/app.log .
scp hal:~/naxdev/NetAlertX/front/plugins/omada_sdn_imp/* .
gzip -c app.log > app_$today.log.gz
scp hal:~/naxdev/NetAlertX/front/plugins/omada_sdn_imp/omada_sdn.py /drives/c/temp/4boris/
"""
def extract_mac_addresses(text):
mac_pattern = r"([0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2})"
#mac_pattern = r'([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})'
#r"(([0-9A-F]{2}-){5}[0-9A-F]{2})"
#r"([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})"
#r"([0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2})"
mac_addresses = re.findall(mac_pattern, text)
return ["".join(parts) for parts in mac_addresses]
# Example usage:
foo = """
Name: office
Address: 0C-80-63-69-C4-D1 (192.168.0.5)
Status: CONNECTED (CONNECTED)
Ports: 28
Supports PoE: False
Model: T1600G-28TS v3.0
LED Setting: SITE_SETTINGS
Uptime: 5day(s) 22h 39m 6s
Uplink switch: D8-07-B6-71-FF-7F office24
Downlink devices:
- 40-AE-30-A5-A7-50 ompapaoffice
- B0-95-75-46-0C-39 pantry12
"""
mac_list = extract_mac_addresses(foo)
print("mac list",mac_list)
# ['0C-80-63-69-C4-D1', 'D8-07-B6-71-FF-7F', '40-AE-30-A5-A7-50', 'B0-95-75-46-0C-39']
# ['C4-:D1', 'FF-:7F', 'A7-:50', '0C-:39']
linked_switches_and_ports_by_mac = {}
foo = """"
something
some BOB12
blah BOB23
--- BEGIN ---
something else BOB12
blah BOB23
--- END ---
"""
def extract_BOB_patterns(foo):
pattern = r"BOB\d{2}(?=.*BEGIN)"
matches = re.findall(pattern, foo, re.DOTALL)
return matches
BOBresult = extract_BOB_patterns(foo)
print("BOB:",BOBresult) # Output: ['BOB12', 'BOB23']
#0C-80-63-69-C4-D1
clientmac_by_switchmac_by_switchportSSID = {}
switch_mac_and_ports_by_clientmac = {}
def extract_uplinks_mac_and_ports(tplink_device_dump):
mac_switches = []
mac_pattern = r"([0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2}[:-][0-9A-Fa-f]{2})(?=.*BEGIN)"
mac_addresses = re.findall(mac_pattern, tplink_device_dump,re.DOTALL)
mac_switches = ["".join(parts) for parts in mac_addresses]
print(" mac_switches1=",mac_switches)
mymac = mac_switches[0]
mylinks = mac_switches[1:]
for mylink in mylinks:
port_pattern = r"(?=\{.*\"port\"\: )([0-9]+)(?=.*"+re.escape(mylink)+r")"
port_pattern = r"(?:{/s\"port\"\: )([0-9]+)(?:[!\}].*"+re.escape(mylink)+r")"
#port_pattern = rf"{{.*?{found_mac}.*?port\s*:\s*(\d+).*?}}"
#port_pattern = rf"{{.*?.*?port\s*:\s*(\d+)[!\\}]*{mylink}?}}"
port_pattern = r"(?:\{[!\}]port/s:/s)([0-9]+\,)(?:[!\}]*"+re.escape(mylink)+r"[!\{]*\})"
#port_pattern = r"(?:\{.*\"port\"\: )([0-9]+)(?=.*"+re.escape(mylink)+r")"
port_pattern = r"(?:{[^}]*\"port\"\: )([0-9]+)(?=[^}]*"+re.escape(mylink)+r")"
myport = re.findall(port_pattern, tplink_device_dump,re.DOTALL)
print("myswitch=",mymac, "- link_switch=", mylink, "myport=", myport)
return(0)
'''
with open('/tmp/switch.bigroom.dump.json', 'r') as file:
foo3 = file_content = file.read()
print("bigroom", end="")
extract_uplinks_mac_and_ports(foo3)
with open('/tmp/switch.office.dump.json', 'r') as file:
foo4 = file_content = file.read()
print("office", end="")
extract_uplinks_mac_and_ports(foo4)
'''
import netifaces
gw = netifaces.gateways()
print(gw['default'][netifaces.AF_INET][0])
d = {'a': ['0', 'Arthur'], 'b': ['foo', 'Belling']}
print(d.items())
print(d.keys())
print(d.values())
foo = 2
#while foo > 0:
# foo = 'toto'
print("foo is ",foo)
if foo in ( 'bar', '', 'null'):
print("foo is bar")
else:
print("foo is not bar")
foo='192-168-0-150.local'
bar = foo.split('.')[0]
print("bar=",bar,"-")
bar2 = 'toto'
print("bar2=",bar2,"-")
import concurrent.futures
import time
import random
def phello(arg):
print('running phell',arg)
delay = random.uniform(0, 6)
time.sleep(delay)
return f"parallel hello : {arg}", delay
def testparalel():
arguments = ["Alice", "Bob", "Charlie", "David"]
results = {}
results2 = {}
para = 10
# Using ThreadPoolExecutor for parallel execution
with concurrent.futures.ThreadPoolExecutor(max_workers=para) as executor:
# Submit tasks to the executor
future_to_arg = {executor.submit(phello, arg): arg for arg in arguments}
# Wait for all futures to complete
done, _ = concurrent.futures.wait(future_to_arg)
# Retrieve results
for future in done:
arg = future_to_arg[future]
try:
result, result2 = future.result()
results[arg] = result
results2[arg] = result2
except Exception as exc:
print(f"{arg} generated an exception: {exc}")
# Print results after all threads have completed
print("All threads completed. Results:")
for arg, result in results.items():
print(f"arg:{arg}, result={results[arg]}, result2={results2[arg]}")
#testparalel()
import netifaces
import ipaddress
def get_interfaces_and_subnets():
result = []
for interface in netifaces.interfaces():
addrs = netifaces.ifaddresses(interface)
if netifaces.AF_INET in addrs:
for addr in addrs[netifaces.AF_INET]:
ip = addr['addr']
mask = addr['netmask']
try:
network = ipaddress.IPv4Network(f"{ip}/{mask}", strict=False)
result.append((interface, str(network)))
except ValueError:
pass
return result
# Example usage:
interfaces_and_subnets = get_interfaces_and_subnets()
for interface, subnet in interfaces_and_subnets:
print(f"interface={interface}, subnet={subnet}")
'''
interface=lo, subnet=127.0.0.0/8
interface=enp6s0, subnet=192.168.0.0/24
interface=br-ba0070d71f2a, subnet=172.16.0.16/29
interface=br-bc4a4c4e0f93, subnet=172.16.0.40/29
interface=br-e043e0ae9c8c, subnet=172.16.0.72/29
interface=br-6acc3945cfba, subnet=172.16.0.48/29
interface=br-6f931807e709, subnet=172.16.0.80/29
interface=docker0, subnet=172.17.0.0/16
interface=br-9ce2cb7c38c3, subnet=172.16.0.24/29
interface=br-eec81501f666, subnet=172.16.0.32/29
interface=br-1064712a4791, subnet=172.16.0.56/29
interface=br-a93ebdba2a28, subnet=172.16.0.8/29
interface=br-d8fa7a3015e2, subnet=172.16.0.64/29
interface=br-e7cdd041d3d3, subnet=172.16.0.0/29
'''
import timeit
# Setup: Create a dictionary and a function with if-elif statements
data = {
"apple": 1,
"banana": 2,
"cherry": 3,
"date": 4,
"elderberry": 5
}
def get_value_dict(key):
return data.get(key, 0)
def get_value_if_elif(key):
if key == "apple":
return 1
elif key == "banana":
return 2
elif key == "cherry":
return 3
elif key == "date":
return 4
elif key == "elderberry":
return 5
else:
return 0
# Test dictionary lookup
dict_time = timeit.timeit(
'get_value_dict("elderberry")',
setup='from __main__ import get_value_dict',
number=1000000
)
# Test if-elif statements
if_elif_time = timeit.timeit(
'get_value_if_elif("elderberry")',
setup='from __main__ import get_value_if_elif',
number=1000000
)
print(f"Dictionary lookup time: {dict_time:.6f} seconds")
print(f"If-elif statements time: {if_elif_time:.6f} seconds")
print(f"Dictionary is {if_elif_time / dict_time:.2f}x faster")

View File

@@ -26,6 +26,368 @@
], ],
"params": [], "params": [],
"settings": [ "settings": [
{
"function": "NOT_RANDOM_MAC",
"type": {
"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": []
}
]
},
"maxLength": 50,
"default_value": [],
"options": [],
"localized": [],
"name": [
{
"string": "_GLOBAL_LANG_FILES_"
}
],
"description": [
{
"string": "_GLOBAL_LANG_FILES_"
}
]
},
{
"function": "ICONS",
"type": {
"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": []
}
]
},
"maxLength": 50,
"default_value": [
"PGkgY2xhc3M9J2ZhIGZhLXdpZmknPjwvaT4=",
"PGkgY2xhc3M9ImZhIGZhLWNvbXB1dGVyIj48L2k+",
"PGkgY2xhc3M9ImZhIGZhLWV0aGVybmV0Ij48L2k+",
"PGkgY2xhc3M9ImZhIGZhLWdhbWVwYWQiPjwvaT4",
"PGkgY2xhc3M9ImZhIGZhLWdsb2JlIj48L2k+",
"PGkgY2xhc3M9ImZhIGZhLWxhcHRvcCI+PC9pPg==",
"PGkgY2xhc3M9ImZhIGZhLWxpZ2h0YnVsYiI+PC9pPg==",
"PGkgY2xhc3M9ImZhIGZhLXNoaWVsZCI+PC9pPg==",
"PGkgY2xhc3M9ImZhIGZhLXdpZmkiPjwvaT4",
"PGkgY2xhc3M9J2ZhIGZhLWdhbWVwYWQnPjwvaT4"
],
"options": [],
"localized": [],
"name": [
{
"string": "_GLOBAL_LANG_FILES_"
}
],
"description": [
{
"string": "_GLOBAL_LANG_FILES_"
}
]
},
{
"function": "REFRESH",
"type": {
"dataType": "integer",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "number" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": 0,
"options": [],
"localized": [],
"name": [
{
"string": "_GLOBAL_LANG_FILES_"
}
],
"description": [
{
"string": "_GLOBAL_LANG_FILES_"
}
]
},
{
"function": "DEV_SECTIONS",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": [],
"options": ["Tile Cards", "Device Presence"],
"localized": [],
"name": [
{
"string": "_GLOBAL_LANG_FILES_"
}
],
"description": [
{
"string": "_GLOBAL_LANG_FILES_"
}
]
},
{
"function": "PRESENCE",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": ["online", "offline", "archived"],
"options": ["online", "offline", "archived"],
"localized": [],
"name": [
{
"string": "_GLOBAL_LANG_FILES_"
}
],
"description": [
{
"string": "_GLOBAL_LANG_FILES_"
}
]
},
{
"function": "MY_DEVICES",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true" }],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": ["online", "offline", "archived", "new", "down"],
"options": ["online", "offline", "archived", "new", "down"],
"localized": [],
"name": [
{
"string": "_GLOBAL_LANG_FILES_"
}
],
"description": [
{
"string": "_GLOBAL_LANG_FILES_"
}
]
},
{
"function": "device_columns",
"type": {
"dataType": "array",
"elements": [
{
"elementType": "select",
"elementOptions": [{ "multiple": "true", "ordeable": "true" }],
"transformers": ["getString"]
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-4" },
{ "onClick": "selectAll(this)" },
{ "getStringKey": "Gen_Add_All" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-4" },
{ "onClick": "unselectAll(this)" },
{ "getStringKey": "Gen_Remove_All" }
],
"transformers": []
},
{
"elementType": "button",
"elementOptions": [
{ "sourceSuffixes": [] },
{ "separator": "" },
{ "cssClasses": "col-xs-4" },
{ "onClick": "selectChange(this)" },
{ "getStringKey": "Gen_Change" }
],
"transformers": []
}
]
},
"maxLength": 50,
"default_value": [
"Device_TableHead_Icon",
"Device_TableHead_Name",
"Device_TableHead_Type",
"Device_TableHead_LastIP",
"Device_TableHead_Status",
"Device_TableHead_MAC_full"
],
"options": [
"Device_TableHead_Name",
"Device_TableHead_Owner",
"Device_TableHead_Type",
"Device_TableHead_Icon",
"Device_TableHead_Favorite",
"Device_TableHead_Group",
"Device_TableHead_FirstSession",
"Device_TableHead_LastSession",
"Device_TableHead_LastIP",
"Device_TableHead_MAC",
"Device_TableHead_Status",
"Device_TableHead_MAC_full",
"Device_TableHead_LastIPOrder",
"Device_TableHead_Rowid",
"Device_TableHead_Parent_MAC",
"Device_TableHead_Connected_Devices",
"Device_TableHead_Location",
"Device_TableHead_Vendor",
"Device_TableHead_Port",
"Device_TableHead_GUID",
"Device_TableHead_SyncHubNodeName",
"Device_TableHead_NetworkSite",
"Device_TableHead_SSID"
],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Device Columns"
}
],
"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."
}
]
},
{ {
"function": "shown_cards", "function": "shown_cards",
"type": { "type": {
@@ -67,7 +429,7 @@
"description": [ "description": [
{ {
"language_code": "en_us", "language_code": "en_us",
"string": "Which tiles to show on teh top of the Devices page." "string": "Which tiles to show on the top of the Devices page."
} }
] ]
}, },
@@ -98,6 +460,34 @@
"string": "Hide Device tiles with zero results." "string": "Hide Device tiles with zero results."
} }
] ]
},
{
"function": "dark_mode",
"type": {
"dataType": "boolean",
"elements": [
{
"elementType": "input",
"elementOptions": [{ "type": "checkbox" }],
"transformers": []
}
]
},
"default_value": false,
"options": [],
"localized": ["name", "description"],
"name": [
{
"language_code": "en_us",
"string": "Dark mode"
}
],
"description": [
{
"language_code": "en_us",
"string": "Enable dark mode."
}
]
} }
] ]
} }

View File

@@ -1,6 +1,6 @@
## Overview ## Overview
A plugin allowing for importing devices from a UniFi controller. A plugin allowing for importing devices from a UniFi controller. The plugin also tries to import the network map.
### Usage ### Usage
@@ -17,5 +17,4 @@ Specify the following settings in the Settings section of NetAlertX:
### Notes ### Notes
- Currently only used to import devices, not their status, type or network map.
- It is recommended to create a read-only user in your UniFi controller - It is recommended to create a read-only user in your UniFi controller

View File

@@ -460,7 +460,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
// INPUT // INPUT
console.log(codeName); // console.log(codeName);
// Parse the setType JSON string into an object // Parse the setType JSON string into an object
let inputHtml = ''; let inputHtml = '';
@@ -476,6 +476,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
inputType, inputType,
readOnly, readOnly,
isMultiSelect, isMultiSelect,
isOrdeable,
cssClasses, cssClasses,
placeholder, placeholder,
suffix, suffix,
@@ -494,8 +495,10 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
switch (elementType) { switch (elementType) {
case 'select': case 'select':
let multi = isMultiSelect ? "multiple" : ""; let multi = isMultiSelect ? "multiple" : "";
let addCss = isOrdeable ? "select2 select2-hidden-accessible" : "";
inputHtml += `<select onChange="settingsChanged()" my-data-type="${dataType}" my-editable="${editable}" class="form-control" name="${codeName}" id="${codeName}" ${multi}>
inputHtml += `<select onChange="settingsChanged()" my-data-type="${dataType}" my-editable="${editable}" class="form-control ${addCss}" name="${codeName}" id="${codeName}" ${multi}>
<option value="" id="${codeName + "_temp_"}"></option> <option value="" id="${codeName + "_temp_"}"></option>
</select>`; </select>`;
@@ -549,7 +552,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
}); });
// EVENTS // EVENTS
// process events (e.g. run ascan, or test a notification) if associated with the setting // process events (e.g. run a scan, or test a notification) if associated with the setting
let eventsHtml = ""; let eventsHtml = "";
const eventsList = createArray(set['Events']); const eventsList = createArray(set['Events']);
@@ -588,6 +591,8 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
}, 50); }, 50);
setupSmoothScrolling() setupSmoothScrolling()
// try to initialize select2
initSelect2()
hideSpinner() hideSpinner()
} }
@@ -645,6 +650,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
inputType, inputType,
readOnly, readOnly,
isMultiSelect, isMultiSelect,
isOrdeable,
cssClasses, cssClasses,
placeholder, placeholder,
suffix, suffix,
@@ -665,26 +671,34 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
value = applyTransformers(value, transformers); value = applyTransformers(value, transformers);
settingsArray.push([prefix, setCodeName, dataType, value]); settingsArray.push([prefix, setCodeName, dataType, value]);
} else if (inputType === 'checkbox') { } else if (dataType === 'boolean') {
value = $(`#${setCodeName}`).is(':checked') ? 1 : 0; value = $(`#${setCodeName}`).is(':checked') ? 1 : 0;
value = applyTransformers(value, transformers); value = applyTransformers(value, transformers);
settingsArray.push([prefix, setCodeName, dataType, value]); settingsArray.push([prefix, setCodeName, dataType, value]);
} else if (dataType === "array" ) { } else if (dataType === "array" ) {
// make sure to collect all if set as "editable" or selected only otherwise
$(`#${setCodeName}`).attr("my-editable") == "true" ? additionalSelector = "" : additionalSelector = ":selected"
const temps = []; let temps = [];
$(`#${setCodeName} option${additionalSelector}`).each(function() {
const vl = $(this).val(); if(isOrdeable)
if (vl !== '') { {
temps.push(applyTransformers(vl, transformers)); temps = $(`#${setCodeName}`).val()
} } else
}); {
// make sure to collect all if set as "editable" or selected only otherwise
$(`#${setCodeName}`).attr("my-editable") == "true" ? additionalSelector = "" : additionalSelector = ":selected";
$(`#${setCodeName} option${additionalSelector}`).each(function() {
const vl = $(this).val();
if (vl !== '') {
temps.push(applyTransformers(vl, transformers));
}
});
}
value = JSON.stringify(temps); value = JSON.stringify(temps);
settingsArray.push([prefix, setCodeName, dataType, value]); settingsArray.push([prefix, setCodeName, dataType, value]);
} else if (dataType === "json") { } else if (dataType === "json") {
@@ -780,34 +794,34 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
setTimeout("handleLoadingDialog()", 1000); setTimeout("handleLoadingDialog()", 1000);
} else } else
{ {
// check if the app is initialized and hide the spinner checkInitialization();
if(isAppInitialized())
{
// init page
getData()
// reload page if outdated information might be displayed
if(secondsSincePageLoad() > 5)
{
clearCache()
}
}
else
{
// reload the page if not initialized to give time the background tasks to finish
setTimeout(() => {
window.location.reload()
}, 3000);
}
} }
document.getElementById('lastImportedTime').innerHTML = humanReadable; document.getElementById('lastImportedTime').innerHTML = humanReadable;
}) })
} }
function checkInitialization() {
if (isAppInitialized()) {
// App is initialized, hide spinner and proceed with initialization
console.log("App initialized, proceeding...");
getData();
// Reload page if outdated information might be displayed
if (secondsSincePageLoad() > 10) {
clearCache();
}
} else {
console.log("App not initialized, checking again in 1s...");
// Check again after a delay
setTimeout(checkInitialization, 1000);
}
}
showSpinner() showSpinner()

View File

@@ -30,5 +30,5 @@ source myenv/bin/activate
update-alternatives --install /usr/bin/python python /usr/bin/python3 10 update-alternatives --install /usr/bin/python python /usr/bin/python3 10
# install packages thru pip3 # 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 cryptography 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 cryptography

View File

@@ -15,6 +15,7 @@ pluginsPath = applicationPath + '/front/plugins'
logPath = applicationPath + '/front/log' logPath = applicationPath + '/front/log'
apiPath = applicationPath + '/front/api/' apiPath = applicationPath + '/front/api/'
reportTemplatesPath = applicationPath + '/front/report_templates/' reportTemplatesPath = applicationPath + '/front/report_templates/'
fullConfFolder = applicationPath + '/config'
fullConfPath = applicationPath + confPath fullConfPath = applicationPath + confPath
fullDbPath = applicationPath + dbPath fullDbPath = applicationPath + dbPath
vendorsPath = '/usr/share/arp-scan/ieee-oui.txt' vendorsPath = '/usr/share/arp-scan/ieee-oui.txt'

View File

@@ -909,41 +909,44 @@ def collect_lang_strings(json, pref, stringSqlParams):
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
def checkNewVersion(): def checkNewVersion():
mylog('debug', [f"[Version check] Checking if new version available"]) mylog('debug', [f"[Version check] Checking if new version available"])
newVersion = False newVersion = False
f = open(applicationPath + '/front/buildtimestamp.txt', 'r') with open(applicationPath + '/front/buildtimestamp.txt', 'r') as f:
buildTimestamp = int(f.read().strip()) buildTimestamp = int(f.read().strip())
f.close()
data = ""
try: try:
url = requests.get("https://api.github.com/repos/jokob-sk/NetAlertX/releases") response = requests.get("https://api.github.com/repos/jokob-sk/NetAlertX/releases")
text = url.text response.raise_for_status() # Raise an exception for HTTP errors
data = json.loads(text) text = response.text
except requests.exceptions.ConnectionError as e: except requests.exceptions.RequestException as e:
mylog('minimal', ["[Version check] ⚠ ERROR: Couldn't check for new release."]) mylog('minimal', ["[Version check] ⚠ ERROR: Couldn't check for new release."])
data = "" return False
try:
data = json.loads(text)
except json.JSONDecodeError as e:
mylog('minimal', ["[Version check] ⚠ ERROR: Invalid JSON response from GitHub."])
return False
# make sure we received a valid response and not an API rate limit exceeded message # make sure we received a valid response and not an API rate limit exceeded message
if data != "" and len(data) > 0 and isinstance(data, list) and "published_at" in data[0]: if data and isinstance(data, list) and "published_at" in data[0]:
dateTimeStr = data[0]["published_at"] dateTimeStr = data[0]["published_at"]
releaseTimestamp = int(datetime.datetime.strptime(dateTimeStr, '%Y-%m-%dT%H:%M:%S%z').timestamp()) releaseTimestamp = int(datetime.datetime.strptime(dateTimeStr, '%Y-%m-%dT%H:%M:%S%z').timestamp())
if releaseTimestamp > buildTimestamp + 600: if releaseTimestamp > buildTimestamp + 600:
mylog('none', ["[Version check] New version of the container available!"]) mylog('none', ["[Version check] New version of the container available!"])
newVersion = True newVersion = True
else: else:
mylog('none', ["[Version check] Running the latest version."]) mylog('none', ["[Version check] Running the latest version."])
else:
mylog('minimal', ["[Version check] ⚠ ERROR: Received unexpected response from GitHub."])
return newVersion return newVersion
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
def initOrSetParam(db, parID, parValue): def initOrSetParam(db, parID, parValue):
sql = db.sql sql = db.sql

View File

@@ -11,13 +11,14 @@ import re
import conf import conf
from const import fullConfPath from const import fullConfPath, applicationPath, fullConfFolder
from helper import collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, updateState, setting_value_to_python_type from helper import collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, updateState, setting_value_to_python_type, timeNowTZ, get_setting_value
from logger import mylog from logger import mylog
from api import update_api from api import update_api
from scheduler import schedule_class from scheduler import schedule_class
from plugin import print_plugin_info, run_plugin_scripts from plugin import print_plugin_info, run_plugin_scripts
from plugin_utils import get_plugins_configs, get_plugin_setting_obj from plugin_utils import get_plugins_configs, get_plugin_setting_obj
from notification import write_notification
#=============================================================================== #===============================================================================
# Initialise user defined values # Initialise user defined values
@@ -28,7 +29,8 @@ from plugin_utils import get_plugins_configs, get_plugin_setting_obj
# Check config dictionary # Check config dictionary
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
def ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None): # managing application settings, ensuring SQL safety for user input, and updating internal configuration lists
def ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False):
if events is None: if events is None:
events = [] events = []
if setJsonMetadata is None: if setJsonMetadata is None:
@@ -40,7 +42,7 @@ def ccd(key, default, config_dir, name, inputtype, options, group, events=None,
result = default result = default
# Use existing value if already supplied, otherwise default value is used # Use existing value if already supplied, otherwise default value is used
if key in config_dir: if forceDefault == False and key in config_dir:
result = config_dir[key] result = config_dir[key]
# Single quotes might break SQL queries, replacing them # Single quotes might break SQL queries, replacing them
@@ -69,16 +71,20 @@ def update_or_append(settings_list, item_tuple, key):
if settings_list is None: if settings_list is None:
settings_list = [] settings_list = []
# mylog('debug', ['[Import Config] update_or_append debug '])
# mylog('debug', ['[Import Config] update_or_append ', settings_list])
# mylog('debug', ['[Import Config] update_or_append item_tuple ' , item_tuple])
for index, item in enumerate(settings_list): for index, item in enumerate(settings_list):
if item[0] == key: if item[0] == key:
settings_list[index] = item_tuple mylog('trace', ['[Import Config] OLD TUPLE : ', item])
mylog('debug', ['[Import Config] FOUND key : ', key]) # Keep values marked as "_KEEP_"
return settings_list updated_tuple = tuple(
new_val if new_val != "_KEEP_" else old_val
for old_val, new_val in zip(item, item_tuple)
)
mylog('trace', ['[Import Config] NEW TUPLE : ', updated_tuple])
settings_list[index] = updated_tuple
mylog('trace', ['[Import Config] FOUND key : ', key])
return settings_list
settings_list.append(item_tuple) settings_list.append(item_tuple)
return settings_list return settings_list
@@ -140,16 +146,11 @@ def importConfigs (db, all_plugins):
conf.DAYS_TO_KEEP_EVENTS = ccd('DAYS_TO_KEEP_EVENTS', 90 , c_d, 'Delete events days', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', '[]', 'General') conf.DAYS_TO_KEEP_EVENTS = ccd('DAYS_TO_KEEP_EVENTS', 90 , c_d, 'Delete events days', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', '[]', 'General')
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_NEWDEV = ccd('HRS_TO_KEEP_NEWDEV', 0 , c_d, 'Keep new devices for', '{"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 dev_PresentLastScan = 0' , c_d, 'Custom endpoint', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"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":"Entervalue"},{"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.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')
# UI # 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)' ]", '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_NOT_RANDOM_MAC = ccd('UI_NOT_RANDOM_MAC', [] , c_d, 'Exlude from Random Prefix', '{"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": "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": []}, {"elementType": "select","elementOptions": [{ "multiple": "true" },{ "readonly": "true" },{ "editable": "true" }],"transformers": [] }]}', "[]", 'UI')
conf.UI_ICONS = ccd('UI_ICONS', ['PGkgY2xhc3M9J2ZhIGZhLXdpZmknPjwvaT4=', 'PGkgY2xhc3M9ImZhIGZhLWNvbXB1dGVyIj48L2k+', 'PGkgY2xhc3M9ImZhIGZhLWV0aGVybmV0Ij48L2k+', 'PGkgY2xhc3M9ImZhIGZhLWdhbWVwYWQiPjwvaT4', 'PGkgY2xhc3M9ImZhIGZhLWdsb2JlIj48L2k+', 'PGkgY2xhc3M9ImZhIGZhLWxhcHRvcCI+PC9pPg==', 'PGkgY2xhc3M9ImZhIGZhLWxpZ2h0YnVsYiI+PC9pPg==', 'PGkgY2xhc3M9ImZhIGZhLXNoaWVsZCI+PC9pPg==', 'PGkgY2xhc3M9ImZhIGZhLXdpZmkiPjwvaT4', 'PGkgY2xhc3M9J2ZhIGZhLWdhbWVwYWQnPjwvaT4'] , c_d, 'Icons', '{"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": "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": []}, {"elementType": "select","elementOptions": [{ "multiple": "true" },{ "readonly": "true" },{ "editable": "true" }],"transformers": [] }]}', "[]", 'UI')
conf.UI_REFRESH = ccd('UI_REFRESH', 0 , c_d, 'Refresh interval', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', "[]", 'UI')
conf.UI_DEV_SECTIONS = ccd('UI_DEV_SECTIONS', [] , c_d, 'Show sections', '{"dataType":"array", "elements": [{"elementType" : "select", "elementOptions" : [{"multiple":"true"}] ,"transformers": []}]}', "['Tile Cards', 'Device Presence']", 'UI')
conf.UI_PRESENCE = ccd('UI_PRESENCE', ['online', 'offline', 'archived'] , c_d, 'Include in presence', '{"dataType":"array", "elements": [{"elementType" : "select", "elementOptions" : [{"multiple":"true"}] ,"transformers": []}]}', "['online', 'offline', 'archived']", 'UI')
conf.UI_MY_DEVICES = ccd('UI_MY_DEVICES', ['online', 'offline', 'archived', 'new', 'down'] , c_d, 'Include in My Devices', '{"dataType":"array", "elements": [{"elementType" : "select", "elementOptions" : [{"multiple":"true"}] ,"transformers": []}]}', "['online', 'offline', 'archived', 'new', 'down']", 'UI')
# Init timezone in case it changed # Init timezone in case it changed
conf.tz = timezone(conf.TIMEZONE) conf.tz = timezone(conf.TIMEZONE)
@@ -285,8 +286,7 @@ def importConfigs (db, all_plugins):
for plugin in all_plugins: for plugin in all_plugins:
pref = plugin["unique_prefix"] pref = plugin["unique_prefix"]
loaded_plugins_prefixes.append(pref) loaded_plugins_prefixes.append(pref)
# save the newly discovered plugins as options and default values # save the newly discovered plugins as options and default values
conf.LOADED_PLUGINS = ccd('LOADED_PLUGINS', loaded_plugins_prefixes , c_d, 'Loaded plugins', '{"dataType":"array", "elements": [{"elementType" : "select", "elementOptions" : [{"multiple":"true"}] ,"transformers": []}]}', str(sorted(all_plugins_prefixes)), 'General') conf.LOADED_PLUGINS = ccd('LOADED_PLUGINS', loaded_plugins_prefixes , c_d, 'Loaded plugins', '{"dataType":"array", "elements": [{"elementType" : "select", "elementOptions" : [{"multiple":"true"}] ,"transformers": []}]}', str(sorted(all_plugins_prefixes)), 'General')
@@ -296,7 +296,54 @@ def importConfigs (db, all_plugins):
conf.plugins_once_run = False conf.plugins_once_run = False
# ----------------- # -----------------
# Plugins END # Plugins END
# TODO check app_conf_override.json
# Assuming fullConfFolder is defined elsewhere
app_conf_override_path = fullConfFolder + '/app_conf_override.json'
if os.path.exists(app_conf_override_path):
with open(app_conf_override_path, 'r') as f:
try:
# Load settings_override from the JSON file
settings_override = json.load(f)
# Loop through settings_override dictionary
for setting_name, value in settings_override.items():
# Ensure the value is treated as a string and passed directly
if isinstance(value, str):
# 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}"])
ccd(setting_name, value, c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True)
else:
# Convert to string and log
# 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: {str(value)}"])
ccd(setting_name, str(value), c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True)
except json.JSONDecodeError:
mylog('none', [f"[Config] [ERROR] Setting override decoding JSON from {app_conf_override_path}"])
else:
mylog('debug', [f"[Config] File {app_conf_override_path} does not exist."])
# Check if app was upgraded
with open(applicationPath + '/front/buildtimestamp.txt', 'r') as f:
buildTimestamp = int(f.read().strip())
cur_version = conf.VERSION
mylog('debug', [f"[Config] buildTimestamp: '{buildTimestamp}'"])
mylog('debug', [f"[Config] conf.VERSION : '{cur_version}'"])
if str(cur_version) != str(buildTimestamp):
mylog('none', ['[Config] App upgraded 🚀'])
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
ccd('VERSION', buildTimestamp , c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True)
write_notification(f'[Upgrade] : App upgraded 🚀 Please clear the cache: <ol> <li>Clear the browser cache (shift + browser refresh button)</li> <li> Clear app cache with the 🔄 (reload) button in the header</li></ol> Check out new features and what has changed in the <a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.', 'interrupt', timeNowTZ())
# Insert settings into the DB # Insert settings into the DB
sql.execute ("DELETE FROM Settings") sql.execute ("DELETE FROM Settings")