mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
Compare commits
87 Commits
v24.7.18
...
39d7642484
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39d7642484 | ||
|
|
287facb798 | ||
|
|
c3f91cae9e | ||
|
|
ef9aeea2d2 | ||
|
|
597cd48318 | ||
|
|
c78db01269 | ||
|
|
bee84cf8b2 | ||
|
|
7c080302e8 | ||
|
|
cec177a912 | ||
|
|
fff1f36b61 | ||
|
|
17d16b1bda | ||
|
|
8199e5e714 | ||
|
|
5c0e9a8af8 | ||
|
|
6438165b14 | ||
|
|
b3d1a43261 | ||
|
|
4ef7f507ed | ||
|
|
0e830e92ed | ||
|
|
552e861887 | ||
|
|
c88afde5f8 | ||
|
|
b4f1e6a5da | ||
|
|
edd66e4888 | ||
|
|
cfa0b3c387 | ||
|
|
e848112452 | ||
|
|
8199bef55d | ||
|
|
8a385a90d4 | ||
|
|
2d0b5d3bdd | ||
|
|
49450e4d1f | ||
|
|
d921d5760f | ||
|
|
2c05f3f663 | ||
|
|
3cde177e01 | ||
|
|
4f1dc1e0d7 | ||
|
|
c21497c61e | ||
|
|
75740670df | ||
|
|
6a161c910b | ||
|
|
857f3e64b7 | ||
|
|
239ebd40b9 | ||
|
|
7203c335e4 | ||
|
|
45489eadaf | ||
|
|
dd99a5de1a | ||
|
|
cae4c0b8c1 | ||
|
|
7dc0a38677 | ||
|
|
1f7a38593d | ||
|
|
e066a65f1b | ||
|
|
4b2b8d6dd1 | ||
|
|
e22b12e5d7 | ||
|
|
9cc994e157 | ||
|
|
2e45cf36f2 | ||
|
|
4d329d47f3 | ||
|
|
dd5e0726aa | ||
|
|
d18cfb07ff | ||
|
|
efea2c970e | ||
|
|
7378517929 | ||
|
|
aeee584939 | ||
|
|
31e686ed4b | ||
|
|
01986a712b | ||
|
|
8193f7f9e5 | ||
|
|
67e467d45a | ||
|
|
1243cf896f | ||
|
|
b6107f6cb9 | ||
|
|
4ef1bb257d | ||
|
|
78db3c7089 | ||
|
|
68b691df09 | ||
|
|
ea6e8862f8 | ||
|
|
a31469373f | ||
|
|
8b1b86eeb7 | ||
|
|
d14944c2bd | ||
|
|
b4c9c4d803 | ||
|
|
cfae2ea8ee | ||
|
|
ab08e2ce85 | ||
|
|
f86b374ed3 | ||
|
|
a69f72fd3d | ||
|
|
df40b5caf9 | ||
|
|
54b6b1d408 | ||
|
|
d79acc7bad | ||
|
|
57d8db771a | ||
|
|
43759b6b7d | ||
|
|
3305828947 | ||
|
|
3e35f08d6c | ||
|
|
1a9b9e3bf7 | ||
|
|
3cb68c4dee | ||
|
|
c51d1ec00e | ||
|
|
7f83fe82b3 | ||
|
|
1fe56a80bd | ||
|
|
b4a4b78700 | ||
|
|
9b0d956fdb | ||
|
|
37700de434 | ||
|
|
d6eb994bf1 |
11
.gitignore
vendored
11
.gitignore
vendored
@@ -19,4 +19,13 @@ __pycache__/
|
||||
**/last_result.log
|
||||
**/script.log
|
||||
**/pialert.conf_bak
|
||||
**/pialert.db_bak
|
||||
**/pialert.db_bak
|
||||
.*.swp
|
||||
|
||||
front/img/account/*
|
||||
**/account.php
|
||||
**/account.js
|
||||
front/css/account.css
|
||||
|
||||
docker-compose.yml.ffsb42
|
||||
.env.omada.ffsb42
|
||||
|
||||
@@ -15,7 +15,7 @@ ENV PATH="/opt/venv/bin:$PATH"
|
||||
COPY . ${INSTALL_DIR}/
|
||||
|
||||
|
||||
RUN pip install netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython \
|
||||
RUN pip install netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros \
|
||||
&& bash -c "find ${INSTALL_DIR} -type d -exec chmod 750 {} \;" \
|
||||
&& bash -c "find ${INSTALL_DIR} -type f -exec chmod 640 {} \;" \
|
||||
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
|
||||
|
||||
@@ -43,7 +43,7 @@ RUN phpenmod -v 8.2 sqlite3
|
||||
RUN apt-get install -y python3-venv
|
||||
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
|
||||
RUN date +%s > ${INSTALL_DIR}/front/buildtimestamp.txt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# 💻🔍 Network scanner & notification framework
|
||||
# 🖧🔍 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).
|
||||
|
||||
@@ -64,7 +64,7 @@ Head to [https://netalertx.com/](https://netalertx.com/) for more gifs and scree
|
||||
| Docs | Link |
|
||||
|-------------|-------------|
|
||||
| 📥🐳 | [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) |
|
||||
| 📚 | [All Documentation](https://github.com/jokob-sk/NetAlertX/blob/main/docs/README.md) (App Usage and Configuration) |
|
||||
|
||||
@@ -92,7 +92,6 @@ Thank you to all the wonderful people who are sponsoring this project.
|
||||
<!-- SPONSORS-LIST DO NOT MODIFY BELOW -->
|
||||
| All Sponsors |
|
||||
|---|
|
||||
| [iptvcld](https://github.com/iptvcld) |
|
||||
|
||||
<!-- SPONSORS-LIST DO NOT MODIFY ABOVE -->
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# Scan multiple interfaces (eth1 and eth0):
|
||||
# SCAN_SUBNETS = [ '192.168.1.0/24 --interface=eth1', '192.168.1.0/24 --interface=eth0' ]
|
||||
|
||||
SCAN_SUBNETS=['192.168.1.0/24 --interface=eth1']
|
||||
SCAN_SUBNETS=['192.168.1.0/24 --interface=eth0']
|
||||
TIMEZONE='Europe/Berlin'
|
||||
LOADED_PLUGINS = ['ARPSCAN','CSVBCKP','DBCLNP', 'INTRNT','MAINT','NEWDEV','NSLOOKUP','NTFPRCS', 'PHOLUS','SETPWD','SMTP', 'SYNC', 'VNDRPDT', 'WORKFLOWS']
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ services:
|
||||
- ${DEV_LOCATION}/front/presence.php:/app/front/presence.php
|
||||
- ${DEV_LOCATION}/front/settings.php:/app/front/settings.php
|
||||
- ${DEV_LOCATION}/front/systeminfo.php:/app/front/systeminfo.php
|
||||
- ${DEV_LOCATION}/front/account.php:/app/front/account.php
|
||||
- ${DEV_LOCATION}/front/report.php:/app/front/report.php
|
||||
- ${DEV_LOCATION}/front/workflows.php:/app/front/workflows.php
|
||||
- ${DEV_LOCATION}/front/appEventsCore.php:/app/front/appEventsCore.php
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||

|
||||
[](https://github.com/sponsors/jokob-sk)
|
||||
|
||||
# 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) |
|
||||
|----------------------|----------------------| ----------------------| ----------------------|
|
||||
|
||||
@@ -33,24 +33,9 @@ Example use cases for plugins could be:
|
||||
|
||||
If you wish to develop a plugin, please check the existing plugin structure. Once the settings are saved by the user they need to be removed from the `app.conf` file manually if you want to re-initialize them from the `config.json` of the plugin.
|
||||
|
||||
Again, please read the below carefully if you'd like to contribute with a plugin yourself. This documentation file might be outdated, so double-check the sample plugins as well.
|
||||
|
||||
## ⚠ Disclaimer
|
||||
|
||||
Follow the below very carefully and check example plugin(s) if you'd like to write one yourself. Plugin UI is not my priority right now, happy to approve PRs if you are interested in extending/improving the UI experience (See [Frontend guidelines](/docs/FRONTEND_DEVELOPMENT.md)). Example improvements for the taking:
|
||||
|
||||
* Making the tables sortable/filterable
|
||||
* Using the same approach to display table data as in the Devices section (solves above)
|
||||
* Adding form controls supported to display the data (Currently supported ones are listed in the section "UI settings in database_column_definitions" below)
|
||||
* ...
|
||||
|
||||
## ❗ Known limitations:
|
||||
|
||||
These issues will be hopefully fixed with time, so please don't report them. Instead, if you know how, feel free to investigate and submit a PR to fix the below. Keep the PRs small as it's easier to approve them:
|
||||
|
||||
* Existing plugin objects are sometimes not interpreted correctly and a new object is created instead, resulting in duplicate entries. (race condition?)
|
||||
* Occasional (experienced twice) hanging of processing plugin script file.
|
||||
* UI displays outdated values until the API endpoints get refreshed.
|
||||
Please read the below carefully if you'd like to contribute with a plugin yourself. This documentation file might be outdated, so double-check the sample plugins as well.
|
||||
|
||||
## Plugin file structure overview
|
||||
|
||||
@@ -67,10 +52,10 @@ These issues will be hopefully fixed with time, so please don't report them. Ins
|
||||
|
||||
More on specifics below.
|
||||
|
||||
### Column order and values
|
||||
### Column order and values (plugins interface contract)
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Spend some time reading and trying to understand the below table. This is the interface between the Plugins and the core application.
|
||||
> Spend some time reading and trying to understand the below table. This is the interface between the Plugins and the core application. The application expets 9 or 13 values The first 9 values are mandatory. The next 4 values (`HelpVal1` to `HelpVal4`) are optional. However, if you use any of these optional values (e.g., `HelpVal1`), you need to supply all optional values (e.g., `HelpVal2`, `HelpVal3`, and `HelpVal4`). If a value is not used, it should be padded with `null`.
|
||||
|
||||
| Order | Represented Column | Value Required | Description |
|
||||
|----------------------|----------------------|----------------------|----------------------|
|
||||
@@ -83,6 +68,11 @@ More on specifics below.
|
||||
| 6 | `Watched_Value4` | no | As above |
|
||||
| 7 | `Extra` | no | Any other data you want to pass and display in NetAlertX and the notifications |
|
||||
| 8 | `ForeignKey` | no | A foreign key that can be used to link to the parent object (usually a MAC address) |
|
||||
| 9 | `HelpVal1` | no | (optional) A helper value |
|
||||
| 10 | `HelpVal2` | no | (optional) A helper value |
|
||||
| 11 | `HelpVal3` | no | (optional) A helper value |
|
||||
| 12 | `HelpVal4` | no | (optional) A helper value |
|
||||
|
||||
|
||||
> [!NOTE]
|
||||
> De-duplication is run once an hour on the `Plugins_Objects` database table and duplicate entries with the same value in columns `Object_PrimaryID`, `Object_SecondaryID`, `Plugin` (auto-filled based on `unique_prefix` of the plugin), `UserData` (can be populated with the `"type": "textbox_save"` column type) are removed.
|
||||
|
||||
@@ -1149,7 +1149,7 @@ function initializeCalendar () {
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
updateIconPreview('#txtIcon')
|
||||
}, 100);
|
||||
}, 500);
|
||||
|
||||
hideSpinner()
|
||||
}
|
||||
|
||||
@@ -143,9 +143,23 @@
|
||||
var tableOrder = [[3,'desc'], [0,'asc']];
|
||||
|
||||
var tableColumnHide = [];
|
||||
var tableColumnOrder = [];
|
||||
var tableColumnVisible = [];
|
||||
|
||||
//initialize the table headers in the correct order
|
||||
var headersDefaultOrder = [
|
||||
|
||||
|
||||
|
||||
// Read parameters & Initialize components
|
||||
callAfterAppInitialized(main)
|
||||
showSpinner();
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function main () {
|
||||
|
||||
//initialize the table headers in the correct order
|
||||
var headersDefaultOrder = [
|
||||
getString('Device_TableHead_Name'),
|
||||
getString('Device_TableHead_Owner'),
|
||||
getString('Device_TableHead_Type'),
|
||||
@@ -173,16 +187,8 @@
|
||||
|
||||
// generate default order lists of given length
|
||||
var columnsStr = JSON.stringify(Array.from({ length: headersDefaultOrder.length }, (_, i) => i));
|
||||
var tableColumnOrder = Array.from({ length: headersDefaultOrder.length }, (_, i) => i);
|
||||
var tableColumnVisible = tableColumnOrder;
|
||||
|
||||
// Read parameters & Initialize components
|
||||
showSpinner();
|
||||
main();
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
function main () {
|
||||
tableColumnOrder = Array.from({ length: headersDefaultOrder.length }, (_, i) => i);
|
||||
tableColumnVisible = tableColumnOrder;
|
||||
|
||||
handleLoadingDialog()
|
||||
|
||||
|
||||
@@ -10,9 +10,10 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
var timerRefreshData = ''
|
||||
|
||||
var emptyArr = ['undefined', "", undefined, null, 'null'];
|
||||
var UI_LANG = "English";
|
||||
var settingsJSON = {}
|
||||
var emptyArr = ['undefined', "", undefined, null, 'null'];
|
||||
var UI_LANG = "English";
|
||||
const allLanguages = ["en_us", "es_es", "de_de", "fr_fr", "it_it", "ru_ru", "nb_no", "pl_pl", "zh_cn"]; // needs to be same as in lang.php
|
||||
var settingsJSON = {}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -207,98 +208,123 @@ function getSetting (key) {
|
||||
// -----------------------------------------------------------------------------
|
||||
// Get language string
|
||||
// -----------------------------------------------------------------------------
|
||||
function cacheStrings()
|
||||
{
|
||||
function cacheStrings() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(!getCache('completedCalls').includes('cacheStrings'))
|
||||
{
|
||||
// handle core strings and translations
|
||||
var 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
|
||||
|
||||
allLanguages.forEach(function (language_code) {
|
||||
$.get(`php/templates/language/${language_code}.json?nocache=${Date.now()}`, function (res) {
|
||||
// Iterate over each language
|
||||
Object.entries(res).forEach(([key, value]) => {
|
||||
// Store translations for each key-value pair
|
||||
setCache(`pia_lang_${key}_${language_code}`, value)
|
||||
});
|
||||
|
||||
// handle strings and translations from plugins
|
||||
$.get(`api/table_plugins_language_strings.json?nocache=${Date.now()}`, function(res) {
|
||||
|
||||
data = res["data"];
|
||||
|
||||
data.forEach((langString) => {
|
||||
setCache(`pia_lang_${langString.String_Key}_${langString.Language_Code}`, langString.String_Value)
|
||||
});
|
||||
}).then(() => handleSuccess('cacheStrings', resolve())).catch(() => handleFailure('cacheStrings', reject("cacheStrings already completed"))); // handle AJAX synchronization
|
||||
|
||||
// Create a promise for each language
|
||||
const languagePromises = allLanguages.map((language_code) => {
|
||||
return new Promise((resolveLang, rejectLang) => {
|
||||
// Fetch core strings and translations
|
||||
|
||||
$.get(`php/templates/language/${language_code}.json?nocache=${Date.now()}`)
|
||||
.done((res) => {
|
||||
// Iterate over each key-value pair and store the translations
|
||||
Object.entries(res).forEach(([key, value]) => {
|
||||
setCache(`pia_lang_${key}_${language_code}`, value);
|
||||
});
|
||||
|
||||
// Fetch strings and translations from plugins
|
||||
$.get(`api/table_plugins_language_strings.json?nocache=${Date.now()}`)
|
||||
.done((pluginRes) => {
|
||||
const data = pluginRes["data"];
|
||||
|
||||
// Store plugin translations
|
||||
data.forEach((langString) => {
|
||||
setCache(`pia_lang_${langString.String_Key}_${langString.Language_Code}`, langString.String_Value);
|
||||
});
|
||||
|
||||
// Handle successful completion of language processing
|
||||
handleSuccess(`cacheStrings[${language_code}]`, resolveLang);
|
||||
})
|
||||
.fail((pluginError) => {
|
||||
// Handle failure in plugin strings fetching
|
||||
rejectLang(pluginError);
|
||||
});
|
||||
})
|
||||
.fail((error) => {
|
||||
// Handle failure in core strings fetching
|
||||
rejectLang(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Wait for all language promises to complete
|
||||
Promise.all(languagePromises)
|
||||
.then(() => {
|
||||
// All languages processed successfully
|
||||
resolve();
|
||||
})
|
||||
.catch((error) => {
|
||||
// Handle failure in any of the language processing
|
||||
handleFailure('cacheStrings', reject);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Get translated language string
|
||||
function getString (key) {
|
||||
function getString(key) {
|
||||
|
||||
// handle initial load to make sure everything is set-up and cached
|
||||
handleFirstLoad(getString)
|
||||
|
||||
UI_LANG = getSetting("UI_LANG");
|
||||
function fetchString(key) {
|
||||
UI_LANG = getSetting("UI_LANG");
|
||||
|
||||
lang_code = 'en_us';
|
||||
let lang_code = 'en_us';
|
||||
|
||||
switch(UI_LANG)
|
||||
{
|
||||
case 'English':
|
||||
lang_code = 'en_us';
|
||||
break;
|
||||
case 'Spanish':
|
||||
lang_code = 'es_es';
|
||||
break;
|
||||
case 'German':
|
||||
lang_code = 'de_de';
|
||||
break;
|
||||
case 'French':
|
||||
lang_code = 'fr_fr';
|
||||
break;
|
||||
case 'Norwegian':
|
||||
lang_code = 'nb_no';
|
||||
break;
|
||||
case 'Polish (pl_pl)':
|
||||
lang_code = 'pl_pl';
|
||||
break;
|
||||
case 'Portuguese (pt_br)':
|
||||
lang_code = 'pt_br';
|
||||
break;
|
||||
case 'Turkish (tr_tr)':
|
||||
lang_code = 'tr_tr';
|
||||
break;
|
||||
case 'Italian (it_it)':
|
||||
lang_code = 'it_it';
|
||||
break;
|
||||
case 'Russian':
|
||||
lang_code = 'ru_ru';
|
||||
break;
|
||||
case 'Chinese (zh_cn)':
|
||||
lang_code = 'zh_cn';
|
||||
break;
|
||||
}
|
||||
result = getCache(`pia_lang_${key}_${lang_code}`, true);
|
||||
switch (UI_LANG) {
|
||||
case 'English':
|
||||
lang_code = 'en_us';
|
||||
break;
|
||||
case 'Spanish':
|
||||
lang_code = 'es_es';
|
||||
break;
|
||||
case 'German':
|
||||
lang_code = 'de_de';
|
||||
break;
|
||||
case 'French':
|
||||
lang_code = 'fr_fr';
|
||||
break;
|
||||
case 'Norwegian':
|
||||
lang_code = 'nb_no';
|
||||
break;
|
||||
case 'Polish (pl_pl)':
|
||||
lang_code = 'pl_pl';
|
||||
break;
|
||||
case 'Portuguese (pt_br)':
|
||||
lang_code = 'pt_br';
|
||||
break;
|
||||
case 'Turkish (tr_tr)':
|
||||
lang_code = 'tr_tr';
|
||||
break;
|
||||
case 'Italian (it_it)':
|
||||
lang_code = 'it_it';
|
||||
break;
|
||||
case 'Russian':
|
||||
lang_code = 'ru_ru';
|
||||
break;
|
||||
case 'Chinese (zh_cn)':
|
||||
lang_code = 'zh_cn';
|
||||
break;
|
||||
}
|
||||
|
||||
let result = getCache(`pia_lang_${key}_${lang_code}`, true);
|
||||
|
||||
if(isEmpty(result))
|
||||
{
|
||||
result = getCache(`pia_lang_${key}_en_us`, true);
|
||||
if (isEmpty(result)) {
|
||||
result = getCache(`pia_lang_${key}_en_us`, true);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
if (isAppInitialized()) {
|
||||
return fetchString(key);
|
||||
} else {
|
||||
callAfterAppInitialized(() => fetchString(key));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// String utilities
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -334,6 +360,15 @@ function isValidBase64(str) {
|
||||
}
|
||||
|
||||
|
||||
function isValidJSON(jsonString) {
|
||||
try {
|
||||
JSON.parse(jsonString);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// General utilities
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -631,7 +666,7 @@ function openUrl(urls) {
|
||||
// -----------------------------------------------------------------------------
|
||||
function navigateToDeviceWithIp (ip) {
|
||||
|
||||
$.get('api/table_devices.json', function(res) {
|
||||
$.get('api/table_devices.json?nocache=' + Date.now(), function(res) {
|
||||
|
||||
devices = res["data"];
|
||||
|
||||
@@ -835,15 +870,15 @@ function getDeviceDataByMac(macAddress, dbColumn) {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Cache teh devices as one JSON
|
||||
// Cache the devices as one JSON
|
||||
function cacheDevices()
|
||||
{
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
if(!getCache('completedCalls').includes('cacheDevices'))
|
||||
{
|
||||
$.get('api/table_devices.json', function(data) {
|
||||
// if(!getCache('completedCalls').includes('cacheDevices'))
|
||||
// {
|
||||
$.get('api/table_devices.json?nocache=' + Date.now(), function(data) {
|
||||
|
||||
// console.log(data)
|
||||
|
||||
@@ -866,7 +901,8 @@ function cacheDevices()
|
||||
// console.log(getCache('devicesListAll_JSON'))
|
||||
}).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
|
||||
@@ -918,6 +954,8 @@ function showSpinner(stringKey='Loading')
|
||||
text = getString(stringKey)
|
||||
}
|
||||
|
||||
text = isEmpty(text) ? "Loading" : text;
|
||||
|
||||
if($("#loadingSpinner").length)
|
||||
{
|
||||
$("#loadingSpinner").show();
|
||||
@@ -1102,6 +1140,8 @@ function arraysContainSameValues(arr1, arr2) {
|
||||
const sessionStorageKey = "myScriptExecuted_common_js";
|
||||
var completedCalls = []
|
||||
var completedCalls_final = ['cacheSettings', 'cacheStrings', 'cacheDevices'];
|
||||
var completedCallsCount = 0;
|
||||
var completedCallsCount_final = allLanguages.length + 2; // number of language files + cacheDevices + cacheSettings
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Clearing all the caches
|
||||
@@ -1139,10 +1179,24 @@ async function handleFirstLoad(callback) {
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Execute callback once app initialized
|
||||
function callAfterAppInitialized(callback) {
|
||||
if (!isAppInitialized()) {
|
||||
setTimeout(() => {
|
||||
callAfterAppInitialized(callback)
|
||||
}, 500);
|
||||
} else
|
||||
{
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Check if the code has been executed before by checking sessionStorage
|
||||
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);
|
||||
}
|
||||
|
||||
// Define a function that will execute the code only once
|
||||
@@ -1151,9 +1205,10 @@ async function executeOnce() {
|
||||
|
||||
if (!isAppInitialized()) {
|
||||
try {
|
||||
await cacheStrings();
|
||||
await cacheSettings();
|
||||
await cacheDevices();
|
||||
await cacheSettings();
|
||||
await cacheStrings();
|
||||
|
||||
console.log("✅ All AJAX callbacks have completed");
|
||||
onAllCallsComplete();
|
||||
} catch (error) {
|
||||
@@ -1166,8 +1221,20 @@ async function executeOnce() {
|
||||
// Function to handle successful completion of an AJAX call
|
||||
const handleSuccess = (callName) => {
|
||||
console.log(`AJAX call successful: ${callName}`);
|
||||
completedCalls.push(callName);
|
||||
setCache('completedCalls', mergeUniqueArrays(getCache('completedCalls').split(','), [callName]));
|
||||
// completedCalls.push(callName);
|
||||
// setCache('completedCalls', mergeUniqueArrays(getCache('completedCalls').split(','), [callName]));
|
||||
|
||||
val = getCache('completedCallsCount');
|
||||
|
||||
if(val == "")
|
||||
{
|
||||
val = 0;
|
||||
} else
|
||||
{
|
||||
val = parseInt(val)
|
||||
}
|
||||
|
||||
setCache('completedCallsCount', val + 1)
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -1190,6 +1257,10 @@ const onAllCallsComplete = () => {
|
||||
sessionStorage.setItem(sessionStorageKey + '_time', millisecondsNow);
|
||||
|
||||
console.log('✔ Cache initialized');
|
||||
// setTimeout(() => {
|
||||
// location.reload()
|
||||
// }, 10);
|
||||
|
||||
} else {
|
||||
// If not all strings are initialized, retry initialization
|
||||
console.log('❌ Not all strings are initialized. Retrying...');
|
||||
@@ -1199,20 +1270,19 @@ const onAllCallsComplete = () => {
|
||||
|
||||
// Call any other initialization functions here if needed
|
||||
|
||||
// No need for location.reload() here
|
||||
};
|
||||
|
||||
// Function to check if all necessary strings are initialized
|
||||
const areAllStringsInitialized = () => {
|
||||
// Implement logic to check if all necessary strings are initialized
|
||||
// Return true if all strings are initialized, false otherwise
|
||||
return getString('UI_LANG') != ""
|
||||
return getString('UI_LANG_name') != ""
|
||||
};
|
||||
|
||||
// Call the function to execute the code
|
||||
executeOnce();
|
||||
|
||||
// Set timer for regular checks
|
||||
// Set timer for regular UI refresh if enabled
|
||||
setTimeout(() => {
|
||||
|
||||
// page refresh if configured
|
||||
|
||||
@@ -89,7 +89,7 @@ function checkDbLock() {
|
||||
type: "GET",
|
||||
|
||||
success: function (response) {
|
||||
console.log(response);
|
||||
// console.log(response);
|
||||
if (response == 0) {
|
||||
// console.log('Database is not locked');
|
||||
$(".header-status-locked-db").hide();
|
||||
|
||||
@@ -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
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -266,7 +278,9 @@ function checkNotification() {
|
||||
if (oldestInterruptNotification) {
|
||||
// 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() {
|
||||
// Mark the notification as read
|
||||
|
||||
@@ -259,7 +259,8 @@ function addList(element, clearInput = true) {
|
||||
.attr("value", input)
|
||||
.text(input);
|
||||
|
||||
const el = $(`#${toId}`).append(newOption);
|
||||
// add new option
|
||||
$(`#${toId}`).append(newOption);
|
||||
|
||||
// clear input
|
||||
if (clearInput) {
|
||||
@@ -269,6 +270,7 @@ function addList(element, clearInput = true) {
|
||||
// Initialize interaction options only for the newly added option
|
||||
initListInteractionOptions(newOption);
|
||||
|
||||
// flag something changes to prevent navigating from page
|
||||
settingsChanged();
|
||||
}
|
||||
|
||||
@@ -279,31 +281,6 @@ function removeFromList(element) {
|
||||
.find("option:last")
|
||||
.remove();
|
||||
}
|
||||
// ---------------------------------------------------------
|
||||
function addInterface() {
|
||||
ipMask = $("#ipMask").val();
|
||||
ipInterface = $("#ipInterface").val();
|
||||
|
||||
full = ipMask + " --interface=" + ipInterface;
|
||||
|
||||
console.log(full);
|
||||
|
||||
if (ipMask == "" || ipInterface == "") {
|
||||
showModalOk(
|
||||
"Validation error",
|
||||
"Specify both, the network mask and the interface"
|
||||
);
|
||||
} else {
|
||||
$("#SCAN_SUBNETS").append(
|
||||
$("<option disabled></option>").attr("value", full).text(full)
|
||||
);
|
||||
|
||||
$("#ipMask").val("");
|
||||
$("#ipInterface").val("");
|
||||
|
||||
settingsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Function to remove an item from the select element
|
||||
@@ -555,7 +532,7 @@ function generateOptionsOrSetOptions(
|
||||
transformers = [] // Transformers to be applied to the values
|
||||
) {
|
||||
|
||||
console.log(codeName);
|
||||
// console.log(codeName);
|
||||
|
||||
// NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
|
||||
options = arrayToObject(createArray(getSettingOptions(codeName)))
|
||||
|
||||
@@ -11,16 +11,7 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// Initialize device selectors / pickers fields
|
||||
// -----------------------------------------------------------------------------
|
||||
function initDeviceSelectors() {
|
||||
|
||||
// console.log(devicesList)
|
||||
// Retrieve device list from session variable
|
||||
var devicesListAll_JSON = getCache('devicesListAll_JSON');
|
||||
|
||||
var devicesList = JSON.parse(devicesListAll_JSON);
|
||||
|
||||
// console.log(devicesList);
|
||||
|
||||
function initDeviceSelectors(devicesListAll_JSON) {
|
||||
|
||||
// Check if both device list exists
|
||||
if (devicesListAll_JSON) {
|
||||
@@ -78,52 +69,6 @@ function initDeviceSelectors() {
|
||||
|
||||
|
||||
|
||||
// // -----------------------------------------------------------------------------
|
||||
// // (ASYNC) Initiate dropdown
|
||||
// function generateSetOptions(settingKey, // Identifier for the setting
|
||||
// valuesArray, // Array of values to be pre-selected in the dropdown
|
||||
// targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
|
||||
// callbackToGenerateEntries, // Callback function to generate entries based on options
|
||||
// targetField, // Target field or element where selected value should be applied or updated
|
||||
// nameTransformer) // callback to transform the name (e.g. base64)
|
||||
// {
|
||||
|
||||
// var optionsHtml = ""
|
||||
|
||||
// // NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
|
||||
// optionsArray = createArray(getSettingOptions(settingKey))
|
||||
|
||||
|
||||
// // check if the result is a SQL query
|
||||
// if(optionsArray.length > 0 && isSQLQuery(optionsArray[0]))
|
||||
// {
|
||||
|
||||
// if (settingKey == "NEWDEV_dev_Network_Node_MAC_ADDR") {
|
||||
// console.log("isSQLQuery in generateSetOptions");
|
||||
|
||||
// }
|
||||
// readData(optionsArray[0], callbackToGenerateEntries, valuesArray, targetLocation, targetField, nameTransformer);
|
||||
|
||||
// } else // this should be already an array, e.g. from a setting or pre-defined
|
||||
// {
|
||||
// optionsArray.forEach(option => {
|
||||
// let selected = valuesArray.includes(option) ? 'selected' : '';
|
||||
// optionsHtml += `<option value="${option}" ${selected}>${option}</option>`;
|
||||
// });
|
||||
|
||||
// // Replace the specified placeholder div with the resulting HTML
|
||||
// setTimeout(() => {
|
||||
|
||||
// $("#" + targetLocation).replaceWith(optionsHtml);
|
||||
|
||||
// }, 50);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Hide elements on the page based on the supplied setting
|
||||
function hideUIelements(settingKey) {
|
||||
@@ -290,42 +235,57 @@ function getCellValue(row, index) {
|
||||
// initialize
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function initSelect2() {
|
||||
|
||||
setTimeout(() => {
|
||||
// Retrieve device list from session variable
|
||||
var devicesListAll_JSON = getCache('devicesListAll_JSON');
|
||||
|
||||
initDeviceSelectors();
|
||||
// check if cache ready
|
||||
if(isValidJSON(devicesListAll_JSON))
|
||||
{
|
||||
// prepare HTML DOM before initializing the frotend
|
||||
initDeviceSelectors(devicesListAll_JSON)
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
//Initialize Select2 Elements and make them sortable
|
||||
|
||||
$(function () {
|
||||
// Iterate over each Select2 dropdown
|
||||
$('.select2').each(function() {
|
||||
var selectEl = $(this).select2();
|
||||
|
||||
// Apply sortable functionality to the dropdown's dropdown-container
|
||||
selectEl.next().children().children().children().sortable({
|
||||
containment: 'parent',
|
||||
update: function () {
|
||||
var sortedValues = $(this).children().map(function() {
|
||||
return $(this).attr('title');
|
||||
}).get();
|
||||
|
||||
var sortedOptions = selectEl.find('option').sort(function(a, b) {
|
||||
return sortedValues.indexOf($(a).text()) - sortedValues.indexOf($(b).text());
|
||||
});
|
||||
|
||||
// Replace all options in selectEl
|
||||
selectEl.empty().append(sortedOptions);
|
||||
|
||||
// Trigger change event on Select2
|
||||
selectEl.trigger('change');
|
||||
}
|
||||
});
|
||||
|
||||
// --------------------------------------------------------
|
||||
//Initialize Select2 Elements and make them sortable
|
||||
$(function () {
|
||||
// Iterate over each Select2 dropdown
|
||||
$('.select2').each(function() {
|
||||
var selectEl = $(this).select2();
|
||||
|
||||
// Apply sortable functionality to the dropdown's dropdown-container
|
||||
selectEl.next().children().children().children().sortable({
|
||||
containment: 'parent',
|
||||
update: function () {
|
||||
var sortedValues = $(this).children().map(function() {
|
||||
return $(this).attr('title');
|
||||
}).get();
|
||||
|
||||
var sortedOptions = selectEl.find('option').sort(function(a, b) {
|
||||
return sortedValues.indexOf($(a).text()) - sortedValues.indexOf($(b).text());
|
||||
});
|
||||
|
||||
// Replace all options in selectEl
|
||||
selectEl.empty().append(sortedOptions);
|
||||
|
||||
// Trigger change event on Select2
|
||||
selectEl.trigger('change');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
} else // cache not ready try later
|
||||
{
|
||||
setTimeout(() => {
|
||||
initSelect2()
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// try to initialize select2
|
||||
setTimeout(() => {
|
||||
initSelect2()
|
||||
}, 500);
|
||||
|
||||
|
||||
|
||||
0
front/log/.gitignore
vendored
Executable file → Normal file
0
front/log/.gitignore
vendored
Executable file → Normal file
@@ -101,10 +101,19 @@
|
||||
for (let j = i * elementsPerColumn; j < Math.min((i + 1) * elementsPerColumn, columns.length); j++) {
|
||||
|
||||
const setTypeObject = JSON.parse(columns[j].Type.replace(/'/g, '"'));
|
||||
// console.log(setTypeObject);
|
||||
const lastElementObj = setTypeObject.elements[setTypeObject.elements.length - 1]
|
||||
// console.log(setTypeObject); 🔽
|
||||
// const lastElementObj = setTypeObject.elements[setTypeObject.elements.length - 1]
|
||||
|
||||
const { elementType, elementOptions = [], transformers = [] } = lastElementObj;
|
||||
// get the element with the input value(s)
|
||||
let elementsWithInputValue = setTypeObject.elements.filter(element => element.elementHasInputValue === 1);
|
||||
|
||||
// if none found, take last
|
||||
if(elementsWithInputValue.length == 0)
|
||||
{
|
||||
elementsWithInputValue = setTypeObject.elements[setTypeObject.elements.length - 1]
|
||||
}
|
||||
|
||||
const { elementType, elementOptions = [], transformers = [] } = elementsWithInputValue;
|
||||
const {
|
||||
inputType,
|
||||
readOnly,
|
||||
@@ -123,8 +132,8 @@
|
||||
// console.log(setTypeObject);
|
||||
// console.log(inputType);
|
||||
|
||||
// render based on element type
|
||||
if (lastElementObj.elementType === 'select') {
|
||||
// render based on element type
|
||||
if (elementsWithInputValue.elementType === 'select') {
|
||||
|
||||
targetLocation = columns[j].Code_Name + "_generateSetOptions"
|
||||
|
||||
@@ -154,7 +163,7 @@
|
||||
}
|
||||
|
||||
|
||||
} else if (lastElementObj.elementType === 'input'){
|
||||
} else if (elementsWithInputValue.elementType === 'input'){
|
||||
|
||||
// Add classes specifically for checkboxes
|
||||
inputType === 'checkbox' ? inputClass = 'checkbox' : inputClass = 'form-control';
|
||||
|
||||
@@ -359,12 +359,17 @@
|
||||
<?php
|
||||
|
||||
// Get all Unassigned / unconnected nodes
|
||||
$func_sql = 'SELECT dev_MAC as mac,
|
||||
dev_PresentLastScan as online,
|
||||
dev_Name as name,
|
||||
dev_LastIP as last_ip,
|
||||
dev_Network_Node_MAC_ADDR
|
||||
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';
|
||||
$func_sql = 'SELECT
|
||||
dev_MAC AS mac,
|
||||
dev_PresentLastScan AS online,
|
||||
dev_Name AS name,
|
||||
dev_LastIP AS last_ip,
|
||||
dev_Network_Node_MAC_ADDR
|
||||
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;
|
||||
$func_result = $db->query($func_sql);
|
||||
@@ -673,7 +678,9 @@
|
||||
|
||||
(!emptyArr.includes(nodeData.data.port )) ? port = nodeData.data.port : port = "";
|
||||
|
||||
(port == "" || port == 0 ) ? portBckgIcon = `<i class="fa fa-wifi"></i>` : portBckgIcon = `<i class="fa fa-ethernet"></i>`;
|
||||
(port == "" || port == 0 || port == 'None' ) ? portBckgIcon = `<i class="fa fa-wifi"></i>` : portBckgIcon = `<i class="fa fa-ethernet"></i>`;
|
||||
|
||||
portHtml = (port == "" || port == 0 || port == 'None' ) ? "" : port
|
||||
|
||||
// Build HTML for individual nodes in the network diagram
|
||||
deviceIcon = (!emptyArr.includes(nodeData.data.icon )) ?
|
||||
@@ -682,7 +689,7 @@
|
||||
</div>` : "";
|
||||
devicePort = `<div class="netPort"
|
||||
style="width:${emSize*sizeCoefficient}em;height:${emSize*sizeCoefficient}em">
|
||||
${port}</div>
|
||||
${portHtml}</div>
|
||||
<div class="portBckgIcon"
|
||||
style="margin-left:-${emSize*sizeCoefficient}em;">
|
||||
${portBckgIcon}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"AppEvents_ObjectPrimaryID": "Primär ID",
|
||||
"AppEvents_ObjectSecondaryID": "Sekundär ID",
|
||||
"AppEvents_ObjectStatus": "",
|
||||
"AppEvents_ObjectStatusColumn": "",
|
||||
"AppEvents_ObjectStatusColumn": "Statusspalte",
|
||||
"AppEvents_ObjectType": "Objekttyp",
|
||||
"AppEvents_Plugin": "Plugin",
|
||||
"AppEvents_Type": "Typ",
|
||||
@@ -98,7 +98,7 @@
|
||||
"DevDetail_MainInfo_Network_Site": "",
|
||||
"DevDetail_MainInfo_Network_Title": "<i class=\"fa fa-network-wired\"></i> Network",
|
||||
"DevDetail_MainInfo_Owner": "Eigen­tümer",
|
||||
"DevDetail_MainInfo_SSID": "",
|
||||
"DevDetail_MainInfo_SSID": "SSID",
|
||||
"DevDetail_MainInfo_Title": "<i class=\"fa fa-pencil\"></i> Hauptinformation",
|
||||
"DevDetail_MainInfo_Type": "Typ",
|
||||
"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_SessionInfo_FirstSession": "Erste Sitzung",
|
||||
"DevDetail_SessionInfo_LastIP": "Letzte IP",
|
||||
"DevDetail_SessionInfo_LastSession": "Letzte Sitzung",
|
||||
"DevDetail_SessionInfo_LastSession": "Zuletzt offline",
|
||||
"DevDetail_SessionInfo_StaticIP": "Statische IP",
|
||||
"DevDetail_SessionInfo_Status": "Status",
|
||||
"DevDetail_SessionInfo_Title": "<i class=\"fa fa-calendar\"></i> Sitzungsinformation",
|
||||
@@ -202,7 +202,7 @@
|
||||
"Device_Shortcut_Archived": "Archiviert",
|
||||
"Device_Shortcut_Connected": "Verbunden",
|
||||
"Device_Shortcut_Devices": "Geräte",
|
||||
"Device_Shortcut_DownAlerts": "Offline & Nicht erreichbar",
|
||||
"Device_Shortcut_DownAlerts": "Nicht erreichbar & offline",
|
||||
"Device_Shortcut_DownOnly": "Offline",
|
||||
"Device_Shortcut_Favorites": "Favoriten",
|
||||
"Device_Shortcut_NewDevices": "Neue Geräte",
|
||||
@@ -210,12 +210,12 @@
|
||||
"Device_TableHead_Connected_Devices": "Verbundene Geräte",
|
||||
"Device_TableHead_Favorite": "Favorit",
|
||||
"Device_TableHead_FirstSession": "Erste Sitzung",
|
||||
"Device_TableHead_GUID": "",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
"Device_TableHead_Group": "Gruppe",
|
||||
"Device_TableHead_Icon": "Icon",
|
||||
"Device_TableHead_LastIP": "Letzte IP",
|
||||
"Device_TableHead_LastIPOrder": "Last IP Order",
|
||||
"Device_TableHead_LastSession": "Letzte Sitzung",
|
||||
"Device_TableHead_LastSession": "Zuletzt offline",
|
||||
"Device_TableHead_Location": "Standort",
|
||||
"Device_TableHead_MAC": "MAC",
|
||||
"Device_TableHead_MAC_full": "Gesamte MAC",
|
||||
@@ -226,9 +226,9 @@
|
||||
"Device_TableHead_Port": "Port",
|
||||
"Device_TableHead_RowID": "Zeilen ID",
|
||||
"Device_TableHead_Rowid": "Zeilennummer",
|
||||
"Device_TableHead_SSID": "",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_Status": "Status",
|
||||
"Device_TableHead_SyncHubNodeName": "",
|
||||
"Device_TableHead_SyncHubNodeName": "Synchronisationsknoten",
|
||||
"Device_TableHead_Type": "Typ",
|
||||
"Device_TableHead_Vendor": "Hersteller",
|
||||
"Device_Table_Not_Network_Device": "Nicht konfiguriert als Netzwerkgerät",
|
||||
@@ -272,7 +272,7 @@
|
||||
"Events_TableHead_IPOrder": "IP Order",
|
||||
"Events_TableHead_Order": "Order",
|
||||
"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_nav_next": "Nächste",
|
||||
"Events_Table_nav_prev": "Zurück",
|
||||
@@ -280,9 +280,9 @@
|
||||
"Events_Tablelenght_all": "Alle",
|
||||
"Events_Title": "Ereignisse",
|
||||
"Gen_Action": "Action",
|
||||
"Gen_Add": "",
|
||||
"Gen_Add_All": "",
|
||||
"Gen_All_Devices": "",
|
||||
"Gen_Add": "Hinzufügen",
|
||||
"Gen_Add_All": "Alle hinzufügen",
|
||||
"Gen_All_Devices": "Alle Geräte",
|
||||
"Gen_AreYouSure": "Sind Sie sich sicher?",
|
||||
"Gen_Backup": "Sichern",
|
||||
"Gen_Cancel": "Abbrechen",
|
||||
@@ -291,25 +291,25 @@
|
||||
"Gen_Delete": "Löschen",
|
||||
"Gen_DeleteAll": "Delete all",
|
||||
"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_Offline": "",
|
||||
"Gen_Offline": "Offline",
|
||||
"Gen_Okay": "Ok",
|
||||
"Gen_Purge": "Aufräumen",
|
||||
"Gen_ReadDocs": "Mehr in der Dokumentation",
|
||||
"Gen_Remove_All": "",
|
||||
"Gen_Remove_Last": "",
|
||||
"Gen_Remove_All": "Alle entfernen",
|
||||
"Gen_Remove_Last": "Letzte entfernen",
|
||||
"Gen_Restore": "Wiederherstellen",
|
||||
"Gen_Run": "Run",
|
||||
"Gen_Save": "Speichern",
|
||||
"Gen_Saved": "Gespeichert",
|
||||
"Gen_Search": "",
|
||||
"Gen_Search": "Suchen",
|
||||
"Gen_Selected_Devices": "Ausgewählte Geräte:",
|
||||
"Gen_Switch": "Umschalten",
|
||||
"Gen_Upd": "Aktualisierung erfolgreich",
|
||||
"Gen_Upd_Fail": "Aktualisierung fehlgeschlagen",
|
||||
"Gen_Update": "",
|
||||
"Gen_Update_Value": "",
|
||||
"Gen_Update": "Aktualisieren",
|
||||
"Gen_Update_Value": "Wert aktualisieren",
|
||||
"Gen_Warning": "Warnung",
|
||||
"Gen_Work_In_Progress": "Keine Finalversion, feedback bitte unter: https://github.com/jokob-sk/NetAlertX/issues",
|
||||
"General_display_name": "Allgemein",
|
||||
@@ -353,7 +353,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_Title": "Hilfe / FAQ",
|
||||
"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_name": "Erweiterte Protokollierung",
|
||||
"Loading": "Laden...",
|
||||
@@ -384,8 +384,8 @@
|
||||
"MQTT_USER_name": "MQTT user",
|
||||
"MQTT_display_name": "MQTT",
|
||||
"MQTT_icon": "<i class=\"fa fa-square-rss\"></i>",
|
||||
"Maint_PurgeLog": "",
|
||||
"Maint_RestartServer": "",
|
||||
"Maint_PurgeLog": "Protokoll bereinigen",
|
||||
"Maint_RestartServer": "Server neu starten",
|
||||
"Maint_Restart_Server_noti_text": "",
|
||||
"Maintenance_Running_Version": "Installierte Version",
|
||||
"Maintenance_Status": "Status",
|
||||
@@ -398,7 +398,7 @@
|
||||
"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_text": "Machen Sie ein Backup, bevor Sie diese Funktion 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_text": "",
|
||||
"Maintenance_Tool_arpscansw": "arp-Scan stoppen/starten",
|
||||
@@ -493,7 +493,7 @@
|
||||
"NTFY_USER_name": "NTFY user",
|
||||
"NTFY_display_name": "NTFY",
|
||||
"NTFY_icon": "<i class=\"fa fa-terminal\"></i>",
|
||||
"Navigation_About": "",
|
||||
"Navigation_About": "Über",
|
||||
"Navigation_Devices": "Geräte",
|
||||
"Navigation_Donations": "Donations",
|
||||
"Navigation_Events": "Ereignisse",
|
||||
@@ -503,10 +503,10 @@
|
||||
"Navigation_Maintenance": "Wartung",
|
||||
"Navigation_Monitoring": "Überwachung",
|
||||
"Navigation_Network": "Netzwerk",
|
||||
"Navigation_Notifications": "",
|
||||
"Navigation_Notifications": "Benachrichtigungen",
|
||||
"Navigation_Plugins": "Plugins",
|
||||
"Navigation_Presence": "Anwesenheit",
|
||||
"Navigation_Report": "Bericht",
|
||||
"Navigation_Report": "Gesendete Berichte",
|
||||
"Navigation_Settings": "Einstellungen",
|
||||
"Navigation_SystemInfo": "Systeminfo",
|
||||
"Navigation_Workflows": "Arbeitsabläufe",
|
||||
@@ -545,7 +545,7 @@
|
||||
"Network_Node": "Netzwerkknoten",
|
||||
"Network_Node_Name": "Knotenname",
|
||||
"Network_Parent": "Übergeordnetes Netzwerkgerät",
|
||||
"Network_Root": "",
|
||||
"Network_Root": "Wurzelknoten",
|
||||
"Network_Root_Not_Configured": "",
|
||||
"Network_Root_Unconfigurable": "Nicht konfigurierbare Wurzel",
|
||||
"Network_Table_Hostname": "Gerätename",
|
||||
@@ -553,8 +553,8 @@
|
||||
"Network_Table_State": "Status",
|
||||
"Network_Title": "Netzwerkübersicht",
|
||||
"Network_UnassignedDevices": "Nicht zugewiesene Geräte",
|
||||
"Notifications_All": "",
|
||||
"Notifications_Mark_All_Read": "",
|
||||
"Notifications_All": "Alle Benachrichtigungen",
|
||||
"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_name": "Login-Passwort",
|
||||
"PIALERT_WEB_PROTECTION_description": "Ein Loginfenster wird angezeigt wenn aktiviert. Untere Beschreibung genau durchlesen falls Sie sich aus Ihrer Instanz aussperren.",
|
||||
@@ -609,8 +609,8 @@
|
||||
"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",
|
||||
"RandomMAC_hover": "Autodetected - indicates if the device randomizes it's MAC address.",
|
||||
"Reports_Sent_Log": "",
|
||||
"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.",
|
||||
"Reports_Sent_Log": "Protokoll gesendeter Berichte",
|
||||
"SCAN_SUBNETS_description": "",
|
||||
"SMTP_FORCE_SSL_description": "Force SSL when connecting to your SMTP server.",
|
||||
"SMTP_FORCE_SSL_name": "Force SSL",
|
||||
"SMTP_PASS_description": "The SMTP server password. ",
|
||||
@@ -629,7 +629,7 @@
|
||||
"Setting_Override": "Override value",
|
||||
"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_device_Scanners_desync": "",
|
||||
"Settings_device_Scanners_desync": "⚠ Die Zeitpläne des Gerätescanners sind nicht synchronisiert.",
|
||||
"Settings_device_Scanners_desync_popup": "",
|
||||
"Speedtest_Results": "Ergebnisse des Geschwindigkeitstests",
|
||||
"Systeminfo_CPU": "CPU",
|
||||
@@ -744,29 +744,29 @@
|
||||
"report_time": "Benachrichtigungszeit:",
|
||||
"run_event_icon": "fa-play",
|
||||
"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_label": "",
|
||||
"settings_core_icon": "",
|
||||
"settings_core_label": "Kern",
|
||||
"settings_device_scanners": "",
|
||||
"settings_device_scanners_icon": "fa-solid fa-magnifying-glass-plus",
|
||||
"settings_device_scanners_icon": "",
|
||||
"settings_device_scanners_info": "",
|
||||
"settings_device_scanners_label": "Gerätescanner",
|
||||
"settings_enabled": "Aktive Einstellungen",
|
||||
"settings_enabled_icon": "fa-solid fa-toggle-on",
|
||||
"settings_enabled_icon": "",
|
||||
"settings_expand_all": "Expand all",
|
||||
"settings_imported": "Last time settings were imported from the app.conf file:",
|
||||
"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_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": "",
|
||||
"settings_missing_block": "",
|
||||
"settings_old": "Importing settings and re-initializing...",
|
||||
"settings_other_scanners": "",
|
||||
"settings_other_scanners_icon": "fa-solid fa-recycle",
|
||||
"settings_other_scanners_icon": "",
|
||||
"settings_other_scanners_label": "Andere Scanner",
|
||||
"settings_publishers": "",
|
||||
"settings_publishers_icon": "fa-solid fa-paper-plane",
|
||||
"settings_publishers_info": "",
|
||||
"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_system_icon": "fa-solid fa-gear",
|
||||
"settings_saved": "",
|
||||
"settings_system_icon": "",
|
||||
"settings_system_label": "System",
|
||||
"settings_update_item_warning": "",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
|
||||
0
front/php/templates/language/en_us.json
Normal file → Executable file
0
front/php/templates/language/en_us.json
Normal file → Executable file
10
front/php/templates/language/es_es.json
Normal file → Executable file
10
front/php/templates/language/es_es.json
Normal file → Executable file
@@ -394,11 +394,11 @@
|
||||
"Maintenance_Tool_ExportCSV_text": "Genere un archivo CSV (valor separado por comas) que contenga la lista de Dispositivos incluyendo las relaciones de red entre los Nodos de red y los dispositivos conectados. También puedes activarlo accediendo a esta URL <code>your NetAlertX url/php/server/devices.php?action=ExportCSV</code> o activando el plugin <a href=\"settings.php#CSVBCKP_header\">Copia de seguridad CSV</a>.",
|
||||
"Maintenance_Tool_ImportCSV": "Importación CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Importación CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "¿Está seguro de que quiere importar el archivo CSV? Esto sobrescribirá completamente los dispositivos de su base de datos.",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "¿Estás seguro de que quieres importar el archivo CSV? Esto <b>sobrescribirá</b> completamente los dispositivos en su base de datos.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Antes de usar esta función, haga una copia de seguridad. Importe un archivo CSV (valor separado por comas) que contiene la lista de dispositivos, incluidas las relaciones de red entre nodos de red y dispositivos conectados. Para hacer eso, coloque el archivo CSV llamado <b> devices.csv </b> en su carpeta <b>/config </b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Importar CSV (Pegar)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "¿Seguro que desea importar el CSV pegado? Esto <b>sobrescribirá</b> completamente los dispositivos en su base de datos.",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "Antes de usar esta función, por favor haga una copia de seguridad. Importar un archivo CSV (valor separado por comas) que contiene la lista de Dispositivos incluyendo las relaciones de red entre los Nodos de red y los dispositivos conectados.",
|
||||
"Maintenance_Tool_arpscansw": "Activar arp-scan (on/off)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Activar arp-scan on or off",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Cuando el escaneo se ha apagado, permanece apagado hasta que se active nuevamente.",
|
||||
@@ -735,7 +735,7 @@
|
||||
"Webhooks_icon": "<i class=\"fa fa-circle-nodes\"></i>",
|
||||
"Webhooks_settings_group": "<i class=\"fa fa-circle-nodes\"></i> Webhooks",
|
||||
"devices_old": "Volviendo a actualizar....",
|
||||
"general_event_description": "El evento que has activado puede tardar un poco hasta que finalicen los procesos en segundo plano. La ejecución finalizó una vez que se vació la cola de ejecución de abajo (Compruebe el <a href='/mantenimiento.php#tab_Logging'>registro de errores</a> si encuentra problemas). <br/> <br/> Cola de ejecución:",
|
||||
"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 vació 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_title": "Ejecutar un evento ad-hoc",
|
||||
"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:",
|
||||
|
||||
12
front/php/templates/language/fr_fr.json
Executable file → Normal file
12
front/php/templates/language/fr_fr.json
Executable file → Normal file
@@ -8,7 +8,7 @@
|
||||
"About_Title": "Analyse de la sécurité du réseau et cadre de notification",
|
||||
"AppEvents_DateTimeCreated": "Journalisé",
|
||||
"AppEvents_Extra": "Extra",
|
||||
"AppEvents_GUID": "",
|
||||
"AppEvents_GUID": "GUID d’événement d’application",
|
||||
"AppEvents_Helper1": "Helper 1",
|
||||
"AppEvents_Helper2": "Helper 2",
|
||||
"AppEvents_Helper3": "Helper 3",
|
||||
@@ -35,7 +35,7 @@
|
||||
"BackDevices_Arpscan_enabled": "Apr-Scan Activé",
|
||||
"BackDevices_Backup_CopError": "La base de donnée initiale n'a pas pu être sauvegardée.",
|
||||
"BackDevices_Backup_Failed": "La sauvegarde a été partiellement complétée. L'archive n'a pas pu être crée ou est vide.",
|
||||
"BackDevices_Backup_okay": "",
|
||||
"BackDevices_Backup_okay": "La sauvegarde s'est déroulée avec succès avec la nouvelle archive",
|
||||
"BackDevices_DBTools_DelDevError_a": "Erreur lors de la suppression de l'appareil",
|
||||
"BackDevices_DBTools_DelDevError_b": "Erreur lors de la suppression des appareils",
|
||||
"BackDevices_DBTools_DelDev_a": "Appareil supprimé",
|
||||
@@ -56,15 +56,15 @@
|
||||
"BackDevices_Restore_okay": "Restauration exécutée avec succès.",
|
||||
"BackDevices_darkmode_disabled": "Mode sombre désactivé",
|
||||
"BackDevices_darkmode_enabled": "Mode sombre activé",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Il s'agit d'un paramètre de maintenance. Il indique le nombre de jours pendant lesquels les entrées d'événements seront conservées. Tous les événements plus anciens seront supprimés périodiquement. S'applique également à l'historique des événements du plugin.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Supprimer les événements plus anciens que",
|
||||
"DevDetail_Copy_Device_Title": "",
|
||||
"DevDetail_Copy_Device_Tooltip": "",
|
||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copier les détails de l'appareil",
|
||||
"DevDetail_Copy_Device_Tooltip": "Copier les détails de l'appareil dans la liste déroulante. Tout ce qui se trouve sur cette page sera écrasé",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Alerter tous les événements",
|
||||
"DevDetail_EveandAl_AlertDown": "Alerte de panne",
|
||||
"DevDetail_EveandAl_Archived": "Archivés",
|
||||
"DevDetail_EveandAl_NewDevice": "Nouvel appareil",
|
||||
"DevDetail_EveandAl_NewDevice_Tooltip": "",
|
||||
"DevDetail_EveandAl_NewDevice_Tooltip": "Affiche le statut Nouveau pour l'appareil et l'inclut dans les listes lorsque le filtre Nouveaux Appareils est actif. N'affecte pas les notifications.",
|
||||
"DevDetail_EveandAl_RandomMAC": "MAC aléatoire",
|
||||
"DevDetail_EveandAl_ScanCycle": "",
|
||||
"DevDetail_EveandAl_ScanCycle_a": "",
|
||||
|
||||
10
front/php/templates/language/it_it.json
Normal file → Executable file
10
front/php/templates/language/it_it.json
Normal file → Executable file
@@ -370,11 +370,11 @@
|
||||
"Maintenance_Tool_ExportCSV_text": "Genera un file CSV (comma separated value) contenente la lista dei dispositivi incluse le relazioni di rete tra i nodi di rete e i dispositivi connessi. Puoi anche eseguire questa azione accedendo all'URL <code>il_tuo_NetAlertX/php/server/devices.php?action=ExportCSV</code> o abilitando il plugin <a href=\"settings.php#CSVBCKP_header\">Backup CSV</a>.",
|
||||
"Maintenance_Tool_ImportCSV": "Importa CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti": "Importa CSV",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Sei sicuro di voler importare il file CSV? Questa operazione sovrascriverà tutti i dispositivi presenti nel database.",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Sei sicuro di voler importare il file CSV? Questa operazione <b>sovrascriverà</b> tutti i dispositivi presenti nel database.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Prima di utilizzare questa funzione, esegui un backup. Importa un file CSV (comma separated value) contenente la lista dei dispositivi incluse le relazioni di rete tra i nodi di rete e i dispositivi connessi. Per far ciò posiziona il file CSV denominato <b>devices.csv</b> nella cartella <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Importazione CSV (incolla)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "Sei sicuro di voler importare il CSV incollato? Questo <b>sovrascriverà</b> completamente i dispositivi nel tuo database.",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "Prima di utilizzare questa funzione, esegui un backup. Importa un file CSV (valori separati da virgole) contenente l'elenco dei dispositivi, comprese le relazioni di rete tra i nodi di rete e i dispositivi collegati.",
|
||||
"Maintenance_Tool_arpscansw": "Attiva/disattiva arp-Scan",
|
||||
"Maintenance_Tool_arpscansw_noti": "Attiva o disattiva arp-Scan",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Una volta disattivata la scansione rimane disattivata finché non viene nuovamente attivata.",
|
||||
@@ -655,7 +655,7 @@
|
||||
"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",
|
||||
"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",
|
||||
"report_guid": "GUID notifica:",
|
||||
"report_guid_missing": "Notifica collegata non trovata. C'è un piccolo ritardo tra la disponibilità delle notifiche inviate di recente e la loro disponibilità. Aggiorna la pagina e la cache dopo alcuni secondi. È anche possibile che la notifica selezionata sia stata eliminata durante la manutenzione come specificato nell'impostazione <code>DBCLNP_NOTIFI_HIST</code>. <br/> <br/>Viene invece visualizzata l'ultima notifica. La notifica mancante ha il seguente GUID:",
|
||||
|
||||
0
front/php/templates/language/nb_no.json
Normal file → Executable file
0
front/php/templates/language/nb_no.json
Normal file → Executable file
0
front/php/templates/language/pl_pl.json
Normal file → Executable file
0
front/php/templates/language/pl_pl.json
Normal file → Executable file
508
front/php/templates/language/pt_br.json
Executable file → Normal file
508
front/php/templates/language/pt_br.json
Executable file → Normal file
@@ -3,7 +3,7 @@
|
||||
"API_CUSTOM_SQL_name": "Endpoint customizado",
|
||||
"API_display_name": "API",
|
||||
"API_icon": "<i class=\"fa fa-arrow-down-up-across-line\"></i>",
|
||||
"About_Design": "Desenhado por:",
|
||||
"About_Design": "Desenvolvido por:",
|
||||
"About_Exit": "Sair",
|
||||
"About_Title": "Analisador de segurança de rede & framework de notificação",
|
||||
"AppEvents_DateTimeCreated": "Registrado em",
|
||||
@@ -56,15 +56,15 @@
|
||||
"BackDevices_Restore_okay": "Restauração executada com sucesso.",
|
||||
"BackDevices_darkmode_disabled": "Modo Noturno Desabilitado",
|
||||
"BackDevices_darkmode_enabled": "Modo Noturno Habilitado",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "",
|
||||
"DAYS_TO_KEEP_EVENTS_description": "Esta é uma definição de manutenção. Especifica o número de dias de entradas de eventos que serão mantidas. Todos os eventos mais antigos serão eliminados periodicamente. Também se aplica ao Histórico de eventos do plug-in.",
|
||||
"DAYS_TO_KEEP_EVENTS_name": "Excluir eventos mais antigos que",
|
||||
"DevDetail_Copy_Device_Title": "<i class=\"fa fa-copy\"></i> Copiar detalhes do dispositivo",
|
||||
"DevDetail_Copy_Device_Tooltip": "",
|
||||
"DevDetail_Copy_Device_Tooltip": "Copiar detalhes do dispositivo a partir da lista pendente. Tudo o que se encontra nesta página será substituído",
|
||||
"DevDetail_EveandAl_AlertAllEvents": "Alerte Todos os Eventos",
|
||||
"DevDetail_EveandAl_AlertDown": "Alerta Desligado",
|
||||
"DevDetail_EveandAl_Archived": "Arquivado",
|
||||
"DevDetail_EveandAl_NewDevice": "Novo Dispositivo",
|
||||
"DevDetail_EveandAl_NewDevice_Tooltip": "",
|
||||
"DevDetail_EveandAl_NewDevice_Tooltip": "Mostra o estado Novo do dispositivo e inclui-o nas listas quando o filtro Novos dispositivos está ativo. Não afecta as notificações.",
|
||||
"DevDetail_EveandAl_RandomMAC": "MAC Aleatório",
|
||||
"DevDetail_EveandAl_ScanCycle": "Rastrear dispositivo",
|
||||
"DevDetail_EveandAl_ScanCycle_a": "Rastrear Dispositivo",
|
||||
@@ -72,258 +72,258 @@
|
||||
"DevDetail_EveandAl_Skip": "Pular notificações repetidas para",
|
||||
"DevDetail_EveandAl_Title": "<i class=\"fa fa-bolt\"></i> Configuração de Eventos & Alertas",
|
||||
"DevDetail_Events_CheckBox": "Esconder Eventos de Conexão",
|
||||
"DevDetail_GoToNetworkNode": "",
|
||||
"DevDetail_GoToNetworkNode": "Navega para a página Rede do nó indicado.",
|
||||
"DevDetail_Icon": "Icone",
|
||||
"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_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": "",
|
||||
"DevDetail_Icon_Descr": "Introduza o nome de um ícone fantástico do tipo de letra sem o prefixo fa- ou com a classe completa, por exemplo: fa fa-brands fa-apple.",
|
||||
"DevDetail_Loading": "A carregar...",
|
||||
"DevDetail_MainInfo_Comments": "Comentários",
|
||||
"DevDetail_MainInfo_Favorite": "Favorito",
|
||||
"DevDetail_MainInfo_Group": "Grupo",
|
||||
"DevDetail_MainInfo_Location": "Localização",
|
||||
"DevDetail_MainInfo_Name": "Nome",
|
||||
"DevDetail_MainInfo_Network": "<i class=\"fa fa-server\"> </i> Node (MAC)",
|
||||
"DevDetail_MainInfo_Network_Port": "<i class=\"fa fa-ethernet\"></i>Porta",
|
||||
"DevDetail_MainInfo_Network_Site": "Site",
|
||||
"DevDetail_MainInfo_Network_Title": "<i class=\"fa fa-network-wired\"></i> Rede",
|
||||
"DevDetail_MainInfo_Owner": "Proprietário",
|
||||
"DevDetail_MainInfo_SSID": "SSID",
|
||||
"DevDetail_MainInfo_Title": "<i class=\"fa fa-pencil\"></i> Informações principais",
|
||||
"DevDetail_MainInfo_Type": "Tipo",
|
||||
"DevDetail_MainInfo_Vendor": "Vendedor",
|
||||
"DevDetail_MainInfo_mac": "MAC",
|
||||
"DevDetail_Network_Node_hover": "Selecione o dispositivo de rede principal ao qual o dispositivo atual está conectado, para preencher a árvore Rede.",
|
||||
"DevDetail_Network_Port_hover": "A porta a que este dispositivo está ligado no dispositivo de rede principal. Se for deixado vazio, é apresentado um ícone wifi na árvore Rede.",
|
||||
"DevDetail_Nmap_Scans": "Varreduras manuais do Nmap",
|
||||
"DevDetail_Nmap_Scans_desc": "Aqui você pode executar varreduras manuais NMAP. Você também pode agendar varreduras automáticas regulares de NMAP através do plugin Serviços & Ports (NMAP). Cabeça para <a href='/settings.php' target='_blank'>Configurações</a> para descobrir mais",
|
||||
"DevDetail_Nmap_buttonDefault": "Verificação predefinida",
|
||||
"DevDetail_Nmap_buttonDefault_text": "Scan padrão: Nmap verifica as 1.000 portas superiores para cada protocolo de digitalização solicitado. Isto atinge cerca de 93% das portas TCP e 49% das portas UDP. (cerca de 5 segundos)",
|
||||
"DevDetail_Nmap_buttonDetail": "Verificação Detalhada",
|
||||
"DevDetail_Nmap_buttonDetail_text": "Verificação detalhada: Verificação predefinida com deteção de SO activada, deteção de versão, verificação de scripts e traceroute (até 30 segundos ou mais)",
|
||||
"DevDetail_Nmap_buttonFast": "Verificação rápida",
|
||||
"DevDetail_Nmap_buttonFast_text": "Verificação rápida: Verifica menos portas (100) do que a verificação predefinida (alguns segundos)",
|
||||
"DevDetail_Nmap_buttonSkipDiscovery": "Saltar descoberta do host",
|
||||
"DevDetail_Nmap_buttonSkipDiscovery_text": "Ignorar a descoberta do host (-Pn opção): Verificação padrão sem descoberta do host",
|
||||
"DevDetail_Nmap_resultsLink": "Você pode deixar esta página depois de iniciar uma varredura. Os resultados também estarão disponíveis no arquivo <code>app_front.log</code>.",
|
||||
"DevDetail_Owner_hover": "Quem é o dono deste dispositivo. Campo de texto gratuito.",
|
||||
"DevDetail_Periodselect_All": "Todas as informações",
|
||||
"DevDetail_Periodselect_LastMonth": "Último mês",
|
||||
"DevDetail_Periodselect_LastWeek": "Semana passada",
|
||||
"DevDetail_Periodselect_LastYear": "Ano passado",
|
||||
"DevDetail_Periodselect_today": "Hoje",
|
||||
"DevDetail_Run_Actions_Title": "<i class=\"fa fa-play\"></i> Executar ação no dispositivo",
|
||||
"DevDetail_Run_Actions_Tooltip": "Execute uma ação no dispositivo atual da lista suspensa.",
|
||||
"DevDetail_SessionInfo_FirstSession": "Primeira sessão",
|
||||
"DevDetail_SessionInfo_LastIP": "Último IP",
|
||||
"DevDetail_SessionInfo_LastSession": "Último offline",
|
||||
"DevDetail_SessionInfo_StaticIP": "IP estático",
|
||||
"DevDetail_SessionInfo_Status": "Estado",
|
||||
"DevDetail_SessionInfo_Title": "<i class=\"fa fa-calendar\"></i> Informações de Sessão",
|
||||
"DevDetail_SessionTable_Additionalinfo": "Informações adicionais",
|
||||
"DevDetail_SessionTable_Connection": "Conexão",
|
||||
"DevDetail_SessionTable_Disconnection": "Desconexão",
|
||||
"DevDetail_SessionTable_Duration": "Duração",
|
||||
"DevDetail_SessionTable_IP": "IP",
|
||||
"DevDetail_SessionTable_Order": "Ordem",
|
||||
"DevDetail_Shortcut_CurrentStatus": "Estado atual",
|
||||
"DevDetail_Shortcut_DownAlerts": "Alertas para baixo",
|
||||
"DevDetail_Shortcut_Presence": "Presença",
|
||||
"DevDetail_Shortcut_Sessions": "Sessões",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detalhes",
|
||||
"DevDetail_Tab_Events": "<i class=\"fa fa-bolt\"></i> Eventos",
|
||||
"DevDetail_Tab_EventsTableDate": "Data",
|
||||
"DevDetail_Tab_EventsTableEvent": "Tipo de evento",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
"DevDetail_Tab_EventsTableInfo": "Informações adicionais",
|
||||
"DevDetail_Tab_Nmap": "<i class=\"fa fa-ethernet\"> </i>",
|
||||
"DevDetail_Tab_NmapEmpty": "Nenhuma porta detectada com Nmap neste dispositivo.",
|
||||
"DevDetail_Tab_NmapTableExtra": "Adicional",
|
||||
"DevDetail_Tab_NmapTableHeader": "Resultados da verificação programada",
|
||||
"DevDetail_Tab_NmapTableIndex": "Índice",
|
||||
"DevDetail_Tab_NmapTablePort": "Porta",
|
||||
"DevDetail_Tab_NmapTableService": "Serviço",
|
||||
"DevDetail_Tab_NmapTableState": "Estado",
|
||||
"DevDetail_Tab_NmapTableText": "Configure uma programação em <a href=\"/settings.php#NMAP_ACTIVE\">Configurações</a>",
|
||||
"DevDetail_Tab_NmapTableTime": "Tempo",
|
||||
"DevDetail_Tab_Plugins": "<i class=\"fa fa-plug\"> </i> Plugins",
|
||||
"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_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_Error": "Um erro ocorreu",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Start": "Iniciar informações da Internet",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Title": "Info Internet",
|
||||
"DevDetail_Tab_Tools_Nslookup_Description": "Nslookup é uma ferramenta de linha de comando usada para consultar o Sistema de Nomes de Domínio (DNS). DNS é um sistema que traduz nomes de domínio, como www.google.com, em endereços IP, como 172.217.0.142.",
|
||||
"DevDetail_Tab_Tools_Nslookup_Error": "Erro: O endereço IP não é válido",
|
||||
"DevDetail_Tab_Tools_Nslookup_Start": "Iniciar Nslookup",
|
||||
"DevDetail_Tab_Tools_Nslookup_Title": "Nslookup",
|
||||
"DevDetail_Tab_Tools_Speedtest_Description": "A ferramenta Speedtest mede a velocidade de download, velocidade de upload e latência da conexão de internet.",
|
||||
"DevDetail_Tab_Tools_Speedtest_Start": "Iniciar Speedtest",
|
||||
"DevDetail_Tab_Tools_Speedtest_Title": "Speedtest Online",
|
||||
"DevDetail_Tab_Tools_Traceroute_Description": "Traceroute é um comando de diagnóstico de rede usado para rastrear o caminho que os pacotes de dados levam de um host para outro.<br><br> O comando usa o Protocolo de Mensagem de Controle da Internet (ICMP) para enviar pacotes para nós intermediários na rota, cada nó intermediário responde com um pacote ICMP time-out (TTL timed out) .<br><br> A saída do comando traceroute exibe o endereço IP de cada nó intermediário na rota.<br><br> O comando traceroute pode ser usado para diagnosticar problemas de rede, como atrasos, perda de pacotes e rotas bloqueadas.<br><br> Também pode ser usado para identificar a localização de um nó intermediário em uma rede.",
|
||||
"DevDetail_Tab_Tools_Traceroute_Error": "Erro: O endereço IP não é válido",
|
||||
"DevDetail_Tab_Tools_Traceroute_Start": "Iniciar Traceroute",
|
||||
"DevDetail_Tab_Tools_Traceroute_Title": "Rastreamento",
|
||||
"DevDetail_Tools_WOL": "Enviar comando WoL ",
|
||||
"DevDetail_Tools_WOL_noti": "Wake-on-LAN",
|
||||
"DevDetail_Tools_WOL_noti_text": "O comando Wake-on-LAN é enviado para o endereço de transmissão. Se o alvo não estiver na sub-rede/VLAN do NetAlertX, o dispositivo de destino não responderá.",
|
||||
"DevDetail_Type_hover": "O tipo do dispositivo. Se você selecionar qualquer um dos dispositivos de rede pré-definidos (por exemplo: AP, Firewall, Router, Switch...) eles aparecerão na configuração da árvore de rede como possíveis nós de rede pai.",
|
||||
"DevDetail_Vendor_hover": "O fornecedor deve ser auto-detectado. Você pode substituir ou adicionar seu valor personalizado.",
|
||||
"DevDetail_WOL_Title": "<i class=\"fa fa-power-off\"></i>",
|
||||
"DevDetail_button_AddIcon": "Adicionar novo ícone",
|
||||
"DevDetail_button_AddIcon_Help": "Cole uma tag HTML SVG ou um ícone de tag HTML Font Awesome. Leia a <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md\" target=\"_blank\">documentação sobre ícones</a> para obter detalhes.",
|
||||
"DevDetail_button_AddIcon_Tooltip": "Adicione um novo ícone a este dispositivo que ainda não esteja disponível no menu suspenso.",
|
||||
"DevDetail_button_Delete": "Excluir dispositivo",
|
||||
"DevDetail_button_DeleteEvents": "Excluir eventos",
|
||||
"DevDetail_button_DeleteEvents_Warning": "Tem certeza de que deseja excluir todos os eventos deste dispositivo?<br><br>(isso limpará o <b>Histórico de eventos</b> e as <b>sessões</b> e poderá ajudar com constantes (persistentes) notificações)",
|
||||
"DevDetail_button_OverwriteIcons": "Substituir ícones",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "Substituir ícones de todos os dispositivos pelo mesmo tipo de dispositivo",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "Tem certeza de que deseja substituir todos os ícones de todos os dispositivos pelo mesmo tipo de dispositivo do tipo de dispositivo atual?",
|
||||
"DevDetail_button_Reset": "Redefinir alterações",
|
||||
"DevDetail_button_Save": "Salvar",
|
||||
"Device_MultiEdit": "Edição múltipla",
|
||||
"Device_MultiEdit_Backup": "Cuidado, inserir valores errados abaixo interromperá sua configuração. Faça backup do seu banco de dados ou da configuração dos dispositivos primeiro (<a href=\"php/server/devices.php?action=ExportCSV\">clique para baixar <i class=\"fa-solid fa-download fa-bounce\"></i> </a>). Leia como recuperar dispositivos deste arquivo no <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/BACKUPS.md#scenario-2-corrupted-database\" target=\" _blank\">Documentação de backups</a>.",
|
||||
"Device_MultiEdit_Fields": "Editar campos:",
|
||||
"Device_MultiEdit_MassActions": "Ações em massa:",
|
||||
"Device_MultiEdit_Tooltip": "Cuidadoso. Clicar aqui aplicará o valor à esquerda a todos os dispositivos selecionados acima.",
|
||||
"Device_Searchbox": "Procurar",
|
||||
"Device_Shortcut_AllDevices": "Meus dispositivos",
|
||||
"Device_Shortcut_Archived": "Arquivado",
|
||||
"Device_Shortcut_Connected": "Conectado",
|
||||
"Device_Shortcut_Devices": "Dispositivos",
|
||||
"Device_Shortcut_DownAlerts": "Inativo e off-line",
|
||||
"Device_Shortcut_DownOnly": "Inativo",
|
||||
"Device_Shortcut_Favorites": "Favoritos",
|
||||
"Device_Shortcut_NewDevices": "Novos dispositivos",
|
||||
"Device_Shortcut_OnlineChart": "Presença do dispositivo",
|
||||
"Device_TableHead_Connected_Devices": "Conexões",
|
||||
"Device_TableHead_Favorite": "Favorito",
|
||||
"Device_TableHead_FirstSession": "Primeira sessão",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
"Device_TableHead_Group": "Grupo",
|
||||
"Device_TableHead_Icon": "Ícone",
|
||||
"Device_TableHead_LastIP": "Último IP",
|
||||
"Device_TableHead_LastIPOrder": "Último pedido de IP",
|
||||
"Device_TableHead_LastSession": "Último off-line",
|
||||
"Device_TableHead_Location": "Localização",
|
||||
"Device_TableHead_MAC": "MAC aleatório",
|
||||
"Device_TableHead_MAC_full": "MAC completo",
|
||||
"Device_TableHead_Name": "Nome",
|
||||
"Device_TableHead_NetworkSite": "Site da rede",
|
||||
"Device_TableHead_Owner": "Proprietário",
|
||||
"Device_TableHead_Parent_MAC": "Nó pai MAC",
|
||||
"Device_TableHead_Port": "Porta",
|
||||
"Device_TableHead_RowID": "ID da linha",
|
||||
"Device_TableHead_Rowid": "ID da linha",
|
||||
"Device_TableHead_SSID": "SSID",
|
||||
"Device_TableHead_Status": "Status",
|
||||
"Device_TableHead_SyncHubNodeName": "Nó de sincronização",
|
||||
"Device_TableHead_Type": "Tipo",
|
||||
"Device_TableHead_Vendor": "Fornecedor",
|
||||
"Device_Table_Not_Network_Device": "Não configurado como um dispositivo de rede",
|
||||
"Device_Table_info": "Mostrando _START_ de _END_ do _TOTAL_ entradas",
|
||||
"Device_Table_nav_next": "Próximo",
|
||||
"Device_Table_nav_prev": "Anterior",
|
||||
"Device_Tablelenght": "Mostrar entradas do _MENU_",
|
||||
"Device_Tablelenght_all": "Todos",
|
||||
"Device_Title": "Dispositivos",
|
||||
"Donations_Others": "Outros",
|
||||
"Donations_Platforms": "Plataformas de patrocinadores",
|
||||
"Donations_Text": "Ei 👋! </br> Obrigado por clicar neste item de menu 😅 </br> </br> Estou tentando coletar algumas doações para melhorar o software. Além disso, isso me ajudaria a não ficar exausto, para que eu pudesse oferecer suporte a este aplicativo por mais tempo. Qualquer pequeno patrocínio (recorrente ou não) me faz querer colocar mais esforço neste aplicativo. </br> Eu adoraria encurtar minha semana de trabalho e no tempo restante focar totalmente no NetAlertX. Você obteria mais funcionalidades, um aplicativo mais sofisticado e menos bugs. </br> </br> Obrigado pela leitura - sou grato por qualquer apoio ❤🙏 </br> </br> TL;DR: Ao me apoiar, você obtém: </br> </br> <ul> <li>Atualizações regulares para manter seus dados e sua família seguros 🔄</li><li>Menos bugs 🐛🔫</li><li>Melhor e mais funcionalidade➕</li><li>Eu não fico exausto 🔥🤯</li><li>Lançamentos menos apressados 💨</li><li>Documentos melhores📚</li><li>Suporte melhor e mais rápido com problemas 🆘</li></ul> </br> 📧 Envie-me um e-mail para <a href='mailto:jokob@duck.com?subject=NetAlertX'>jokob@duck.com</a> se quiser entrar em contato ou se devo adicionar outras plataformas de patrocínio. </br>",
|
||||
"Donations_Title": "Doações",
|
||||
"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",
|
||||
"Email_display_name": "Email",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Carregando...",
|
||||
"Events_Periodselect_All": "Todas as informações",
|
||||
"Events_Periodselect_LastMonth": "Mês passado",
|
||||
"Events_Periodselect_LastWeek": "Semana passada",
|
||||
"Events_Periodselect_LastYear": "Ano passado",
|
||||
"Events_Periodselect_today": "Hoje",
|
||||
"Events_Searchbox": "Procurar",
|
||||
"Events_Shortcut_AllEvents": "Todos os eventos",
|
||||
"Events_Shortcut_DownAlerts": "Alertas de queda",
|
||||
"Events_Shortcut_Events": "Eventos",
|
||||
"Events_Shortcut_MissSessions": "Sessões ausentes",
|
||||
"Events_Shortcut_NewDevices": "Novos dispositivos",
|
||||
"Events_Shortcut_Sessions": "Sessões",
|
||||
"Events_Shortcut_VoidSessions": "Sessões anuladas",
|
||||
"Events_TableHead_AdditionalInfo": "Informação adicional",
|
||||
"Events_TableHead_Connection": "Conexão",
|
||||
"Events_TableHead_Date": "Data",
|
||||
"Events_TableHead_Device": "Dispositivo",
|
||||
"Events_TableHead_Disconnection": "Desconexão",
|
||||
"Events_TableHead_Duration": "Duração",
|
||||
"Events_TableHead_DurationOrder": "Duração do pedido",
|
||||
"Events_TableHead_EventType": "Tipo de evento",
|
||||
"Events_TableHead_IP": "IP",
|
||||
"Events_TableHead_IPOrder": "Pedido de IP",
|
||||
"Events_TableHead_Order": "Ordem",
|
||||
"Events_TableHead_Owner": "Proprietário",
|
||||
"Events_TableHead_PendingAlert": "Alerta Pendente",
|
||||
"Events_Table_info": "Mostrando_START_ to _END_ of _TOTAL_ entradas",
|
||||
"Events_Table_nav_next": "Próxima",
|
||||
"Events_Table_nav_prev": "Anterior",
|
||||
"Events_Tablelenght": "Mostrar entradas do _MENU_",
|
||||
"Events_Tablelenght_all": "Todos",
|
||||
"Events_Title": "Eventos",
|
||||
"Gen_Action": "Ação",
|
||||
"Gen_Add": "Adicionar",
|
||||
"Gen_Add_All": "Adicionar todos",
|
||||
"Gen_All_Devices": "Todos os Dispositivos",
|
||||
"Gen_AreYouSure": "Tem certeza?",
|
||||
"Gen_Backup": "Executar backup",
|
||||
"Gen_Cancel": "Cancelar",
|
||||
"Gen_Copy": "Executar",
|
||||
"Gen_DataUpdatedUITakesTime": "OK - Pode levar um tempo para a interface do usuário ser atualizada se uma verificação estiver em execução.",
|
||||
"Gen_Delete": "Excluir",
|
||||
"Gen_DeleteAll": "Excluir todos",
|
||||
"Gen_Error": "Erro",
|
||||
"Gen_Filter": "Filtro",
|
||||
"Gen_LockedDB": "ERRO - O banco de dados pode estar bloqueado - Verifique F12 Ferramentas de desenvolvimento -> Console ou tente mais tarde.",
|
||||
"Gen_Offline": "Offline",
|
||||
"Gen_Okay": "Ok",
|
||||
"Gen_Purge": "Purge",
|
||||
"Gen_ReadDocs": "Leia mais em documentos.",
|
||||
"Gen_Remove_All": "Remover tudo",
|
||||
"Gen_Remove_Last": "Remover o último",
|
||||
"Gen_Restore": "Executar restauração",
|
||||
"Gen_Run": "Executar",
|
||||
"Gen_Save": "Salvar",
|
||||
"Gen_Saved": "Salvo",
|
||||
"Gen_Search": "Procurar",
|
||||
"Gen_Selected_Devices": "Dispositivos selecionados:",
|
||||
"Gen_Switch": "Trocar",
|
||||
"Gen_Upd": "Atualizado com sucesso",
|
||||
"Gen_Upd_Fail": "A atualização falhou",
|
||||
"Gen_Update": "Atualizar",
|
||||
"Gen_Update_Value": "Atualizar valor",
|
||||
"Gen_Warning": "Aviso",
|
||||
"Gen_Work_In_Progress": "Trabalho em andamento, um bom momento para enviar feedback em https://github.com/jokob-sk/NetAlertX/issues",
|
||||
"General_display_name": "Geral",
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"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.",
|
||||
"HRS_TO_KEEP_NEWDEV_name": "Manter novos dispositivos por",
|
||||
"HelpFAQ_Cat_Detail": "Detalhes",
|
||||
"HelpFAQ_Cat_Detail_300_head": "O que significa ",
|
||||
"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_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_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_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_Detail_302_head_b": "E por que não posso selecionar isso?",
|
||||
"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": "O que é o Nmap e para que serve?",
|
||||
"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": "Eu tenho dispositivos na minha lista dos quais não sei nada. Após excluí-los, eles sempre reaparecem.",
|
||||
"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": "Geral",
|
||||
"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": "No seu PC, o seguinte fuso horário está configurado para o ambiente PHP:",
|
||||
"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": "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": "Minha rede parece estar lenta, o streaming fica \"congelado\".",
|
||||
"HelpFAQ_Cat_General_101_text": "",
|
||||
"HelpFAQ_Cat_General_102_head": "",
|
||||
"HelpFAQ_Cat_General_102_text": "",
|
||||
@@ -690,4 +690,4 @@
|
||||
"settings_update_item_warning": "",
|
||||
"test_event_icon": "",
|
||||
"test_event_tooltip": ""
|
||||
}
|
||||
}
|
||||
|
||||
8
front/php/templates/language/ru_ru.json
Normal file → Executable file
8
front/php/templates/language/ru_ru.json
Normal file → Executable file
@@ -370,11 +370,11 @@
|
||||
"Maintenance_Tool_ExportCSV_text": "Создайте файл CSV (значения, разделенные запятыми), содержащий список устройств, включая сетевые отношения между сетевыми узлами и подключенными устройствами. Вы также можете открыть этот URL-адрес <code> URL Вашего NetAlertX/php/server/devices.php?action=ExportCSV</code> или включить плагин <a href=\"settings.php#CSVBCKP_header\">Резервное копирование в CSV</a>.",
|
||||
"Maintenance_Tool_ImportCSV": "CSV Импорт",
|
||||
"Maintenance_Tool_ImportCSV_noti": "CSV Импорт",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Вы уверены, что хотите импортировать файл CSV? Это полностью перезапишет устройства в вашей базе данных.",
|
||||
"Maintenance_Tool_ImportCSV_noti_text": "Вы уверены, что хотите импортировать файл CSV? Это полностью <b>перезапишет</b> устройства в вашей базе данных.",
|
||||
"Maintenance_Tool_ImportCSV_text": "Прежде чем использовать эту функцию, сделайте резервную копию. Импортируйте файл CSV (значения, разделенные запятыми), содержащий список устройств, включая сетевые отношения между сетевыми узлами и подключенными устройствами. Для этого поместите файл CSV с именем <b>devices.csv</b> в папку <b>/config</b>.",
|
||||
"Maintenance_Tool_ImportPastedCSV": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "",
|
||||
"Maintenance_Tool_ImportPastedCSV": "Импорт CSV (вставка)",
|
||||
"Maintenance_Tool_ImportPastedCSV_noti_text": "Вы уверены, что хотите импортировать вставленный CSV? Это полностью <b>перезапишет</b> устройства в вашей базе данных.",
|
||||
"Maintenance_Tool_ImportPastedCSV_text": "Перед использованием этой функции, пожалуйста, создайте резервную копию. Импортируйте файл формата CSV (значения, разделенные запятыми), содержащий список устройств, включая сетевые связи между узлами сети и подключенными устройствами.",
|
||||
"Maintenance_Tool_arpscansw": "Переключить arp-скан (ВКЛ./ВЫКЛ.)",
|
||||
"Maintenance_Tool_arpscansw_noti": "Включить или выключить arp-скан",
|
||||
"Maintenance_Tool_arpscansw_noti_text": "Когда сканирование было выключено, оно остается выключенным до тех пор, пока не будет активировано снова.",
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
"API_display_name": "",
|
||||
"API_icon": "",
|
||||
"About_Design": "",
|
||||
"About_Exit": "",
|
||||
"About_Exit": "Oturum kapat",
|
||||
"About_Title": "",
|
||||
"AppEvents_DateTimeCreated": "",
|
||||
"AppEvents_Extra": "",
|
||||
"AppEvents_Extra": "Ekstra",
|
||||
"AppEvents_GUID": "",
|
||||
"AppEvents_Helper1": "",
|
||||
"AppEvents_Helper2": "",
|
||||
"AppEvents_Helper3": "",
|
||||
"AppEvents_Helper1": "Yardımcı 1",
|
||||
"AppEvents_Helper2": "Yardımcı 2",
|
||||
"AppEvents_Helper3": "Yardımcı 3",
|
||||
"AppEvents_ObjectForeignKey": "",
|
||||
"AppEvents_ObjectIndex": "",
|
||||
"AppEvents_ObjectIsArchived": "",
|
||||
@@ -24,33 +24,33 @@
|
||||
"AppEvents_ObjectType": "",
|
||||
"AppEvents_Plugin": "",
|
||||
"AppEvents_Type": "",
|
||||
"BackDevDetail_Actions_Ask_Run": "",
|
||||
"BackDevDetail_Actions_Ask_Run": "Komutları çalıştırmak istiyor musunuz?",
|
||||
"BackDevDetail_Actions_Not_Registered": "",
|
||||
"BackDevDetail_Actions_Title_Run": "",
|
||||
"BackDevDetail_Actions_Title_Run": "Komutu çalıştır",
|
||||
"BackDevDetail_Copy_Ask": "",
|
||||
"BackDevDetail_Copy_Title": "",
|
||||
"BackDevDetail_Tools_WOL_error": "",
|
||||
"BackDevDetail_Tools_WOL_okay": "",
|
||||
"BackDevDetail_Copy_Title": "Ayrıntıları kopyala",
|
||||
"BackDevDetail_Tools_WOL_error": "Komut çalıştırılmadı.",
|
||||
"BackDevDetail_Tools_WOL_okay": "Komut çalıştırıldı.",
|
||||
"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_DelDevError_a": "Cihaz silinirken hata oluştu",
|
||||
"BackDevices_DBTools_DelDevError_b": "Cihazlar silinirken hata oluştu",
|
||||
"BackDevices_DBTools_DelDev_a": "Cihaz silindi",
|
||||
"BackDevices_DBTools_DelDev_b": "Cihazlar silindi",
|
||||
"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_DBTools_UpdDev": "Cihaz başarılı bir şekilde güncellendi",
|
||||
"BackDevices_DBTools_UpdDevError": "Cihaz güncellenirken hata oluştu",
|
||||
"BackDevices_DBTools_Upgrade": "Veritabanı başarılı bir şekilde güncellendi",
|
||||
"BackDevices_DBTools_UpgradeError": "Veritabanı güncellenemedi",
|
||||
"BackDevices_Device_UpdDevError": "Cihazlar güncellenirken hata oluştu, daha sonra tekrar deneyiz. Veritabanı, devam eden bir komut nedeniyle kilitli olabilir.",
|
||||
"BackDevices_Restore_CopError": "",
|
||||
"BackDevices_Restore_Failed": "",
|
||||
"BackDevices_Restore_okay": "",
|
||||
@@ -63,7 +63,7 @@
|
||||
"DevDetail_EveandAl_AlertAllEvents": "",
|
||||
"DevDetail_EveandAl_AlertDown": "",
|
||||
"DevDetail_EveandAl_Archived": "",
|
||||
"DevDetail_EveandAl_NewDevice": "",
|
||||
"DevDetail_EveandAl_NewDevice": "Yeni Cihaz",
|
||||
"DevDetail_EveandAl_NewDevice_Tooltip": "",
|
||||
"DevDetail_EveandAl_RandomMAC": "",
|
||||
"DevDetail_EveandAl_ScanCycle": "",
|
||||
@@ -75,17 +75,17 @@
|
||||
"DevDetail_GoToNetworkNode": "",
|
||||
"DevDetail_Icon": "",
|
||||
"DevDetail_Icon_Descr": "",
|
||||
"DevDetail_Loading": "",
|
||||
"DevDetail_MainInfo_Comments": "",
|
||||
"DevDetail_Loading": "YÜkleniyor...",
|
||||
"DevDetail_MainInfo_Comments": "Yorumlar",
|
||||
"DevDetail_MainInfo_Favorite": "",
|
||||
"DevDetail_MainInfo_Group": "",
|
||||
"DevDetail_MainInfo_Location": "",
|
||||
"DevDetail_MainInfo_Name": "",
|
||||
"DevDetail_MainInfo_Group": "Grup",
|
||||
"DevDetail_MainInfo_Location": "Konum",
|
||||
"DevDetail_MainInfo_Name": "İsim",
|
||||
"DevDetail_MainInfo_Network": "",
|
||||
"DevDetail_MainInfo_Network_Port": "",
|
||||
"DevDetail_MainInfo_Network_Site": "",
|
||||
"DevDetail_MainInfo_Network_Title": "",
|
||||
"DevDetail_MainInfo_Owner": "",
|
||||
"DevDetail_MainInfo_Owner": "Sahip",
|
||||
"DevDetail_MainInfo_SSID": "",
|
||||
"DevDetail_MainInfo_Title": "",
|
||||
"DevDetail_MainInfo_Type": "",
|
||||
@@ -97,70 +97,70 @@
|
||||
"DevDetail_Nmap_Scans_desc": "",
|
||||
"DevDetail_Nmap_buttonDefault": "",
|
||||
"DevDetail_Nmap_buttonDefault_text": "",
|
||||
"DevDetail_Nmap_buttonDetail": "",
|
||||
"DevDetail_Nmap_buttonDetail": "Detaylı Tarama",
|
||||
"DevDetail_Nmap_buttonDetail_text": "",
|
||||
"DevDetail_Nmap_buttonFast": "",
|
||||
"DevDetail_Nmap_buttonFast": "Hızlı Tarama",
|
||||
"DevDetail_Nmap_buttonFast_text": "",
|
||||
"DevDetail_Nmap_buttonSkipDiscovery": "",
|
||||
"DevDetail_Nmap_buttonSkipDiscovery_text": "",
|
||||
"DevDetail_Nmap_resultsLink": "",
|
||||
"DevDetail_Nmap_resultsLink": "Tarama başlattıktan sonra bu sayfadan çıkabilirsiniz. Sonuçlara <code>app_front.log</code> dosyasından da ulaşılabilir.",
|
||||
"DevDetail_Owner_hover": "",
|
||||
"DevDetail_Periodselect_All": "",
|
||||
"DevDetail_Periodselect_LastMonth": "",
|
||||
"DevDetail_Periodselect_LastWeek": "",
|
||||
"DevDetail_Periodselect_LastYear": "",
|
||||
"DevDetail_Periodselect_today": "",
|
||||
"DevDetail_Run_Actions_Title": "",
|
||||
"DevDetail_Periodselect_All": "Tüm Bilgi",
|
||||
"DevDetail_Periodselect_LastMonth": "Geçen Ay",
|
||||
"DevDetail_Periodselect_LastWeek": "Geçen Hafta",
|
||||
"DevDetail_Periodselect_LastYear": "Geçen Yıl",
|
||||
"DevDetail_Periodselect_today": "Bugün",
|
||||
"DevDetail_Run_Actions_Title": "<i class=\"fa fa-play\"></i>Komutu cihazda çalıştır",
|
||||
"DevDetail_Run_Actions_Tooltip": "",
|
||||
"DevDetail_SessionInfo_FirstSession": "",
|
||||
"DevDetail_SessionInfo_LastIP": "",
|
||||
"DevDetail_SessionInfo_FirstSession": "İlk Oturum",
|
||||
"DevDetail_SessionInfo_LastIP": "Son IP",
|
||||
"DevDetail_SessionInfo_LastSession": "",
|
||||
"DevDetail_SessionInfo_StaticIP": "",
|
||||
"DevDetail_SessionInfo_Status": "",
|
||||
"DevDetail_SessionInfo_Title": "",
|
||||
"DevDetail_SessionTable_Additionalinfo": "",
|
||||
"DevDetail_SessionTable_Connection": "",
|
||||
"DevDetail_SessionInfo_Status": "Durum",
|
||||
"DevDetail_SessionInfo_Title": "<i class=\"fa fa-calendar\"></i> Oturum Bİlgisi",
|
||||
"DevDetail_SessionTable_Additionalinfo": "Ek bilgi",
|
||||
"DevDetail_SessionTable_Connection": "Bağlantı",
|
||||
"DevDetail_SessionTable_Disconnection": "",
|
||||
"DevDetail_SessionTable_Duration": "",
|
||||
"DevDetail_SessionTable_IP": "",
|
||||
"DevDetail_SessionTable_Order": "",
|
||||
"DevDetail_Shortcut_CurrentStatus": "",
|
||||
"DevDetail_SessionTable_Duration": "Süre",
|
||||
"DevDetail_SessionTable_IP": "IP",
|
||||
"DevDetail_SessionTable_Order": "Sıra",
|
||||
"DevDetail_Shortcut_CurrentStatus": "Mevcut Durum",
|
||||
"DevDetail_Shortcut_DownAlerts": "",
|
||||
"DevDetail_Shortcut_Presence": "",
|
||||
"DevDetail_Shortcut_Sessions": "",
|
||||
"DevDetail_Tab_Details": "",
|
||||
"DevDetail_Shortcut_Sessions": "Oturumlar",
|
||||
"DevDetail_Tab_Details": "<i class=\"fa fa-info-circle\"></i> Detaylar",
|
||||
"DevDetail_Tab_Events": "",
|
||||
"DevDetail_Tab_EventsTableDate": "",
|
||||
"DevDetail_Tab_EventsTableDate": "Tarih",
|
||||
"DevDetail_Tab_EventsTableEvent": "",
|
||||
"DevDetail_Tab_EventsTableIP": "",
|
||||
"DevDetail_Tab_EventsTableInfo": "",
|
||||
"DevDetail_Tab_EventsTableIP": "IP",
|
||||
"DevDetail_Tab_EventsTableInfo": "Ek bilgi",
|
||||
"DevDetail_Tab_Nmap": "",
|
||||
"DevDetail_Tab_NmapEmpty": "",
|
||||
"DevDetail_Tab_NmapTableExtra": "",
|
||||
"DevDetail_Tab_NmapTableHeader": "",
|
||||
"DevDetail_Tab_NmapTableExtra": "Ekstra",
|
||||
"DevDetail_Tab_NmapTableHeader": "Planlanmış tarama sonuçları",
|
||||
"DevDetail_Tab_NmapTableIndex": "",
|
||||
"DevDetail_Tab_NmapTablePort": "",
|
||||
"DevDetail_Tab_NmapTableService": "",
|
||||
"DevDetail_Tab_NmapTableState": "",
|
||||
"DevDetail_Tab_NmapTableText": "",
|
||||
"DevDetail_Tab_NmapTableTime": "",
|
||||
"DevDetail_Tab_NmapTableTime": "Zaman",
|
||||
"DevDetail_Tab_Plugins": "",
|
||||
"DevDetail_Tab_Presence": "",
|
||||
"DevDetail_Tab_Sessions": "",
|
||||
"DevDetail_Tab_Sessions": "<i class=\"fa fa-list-ol\"></i> Oturumlar",
|
||||
"DevDetail_Tab_Tools": "",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Description": "",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Error": "",
|
||||
"DevDetail_Tab_Tools_Internet_Info_Error": "Bir hata oluştu",
|
||||
"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_Error": "Hata: Geçersiz IP adresi.",
|
||||
"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_Error": "Hata: Geçersiz IP adresi",
|
||||
"DevDetail_Tab_Tools_Traceroute_Start": "",
|
||||
"DevDetail_Tab_Tools_Traceroute_Title": "",
|
||||
"DevDetail_Tools_WOL": "",
|
||||
@@ -169,45 +169,45 @@
|
||||
"DevDetail_Type_hover": "",
|
||||
"DevDetail_Vendor_hover": "",
|
||||
"DevDetail_WOL_Title": "",
|
||||
"DevDetail_button_AddIcon": "",
|
||||
"DevDetail_button_AddIcon": "Yeni İkon Ekle",
|
||||
"DevDetail_button_AddIcon_Help": "",
|
||||
"DevDetail_button_AddIcon_Tooltip": "",
|
||||
"DevDetail_button_Delete": "",
|
||||
"DevDetail_button_Delete": "Cihazı Sil",
|
||||
"DevDetail_button_DeleteEvents": "",
|
||||
"DevDetail_button_DeleteEvents_Warning": "",
|
||||
"DevDetail_button_OverwriteIcons": "",
|
||||
"DevDetail_button_OverwriteIcons_Tooltip": "",
|
||||
"DevDetail_button_OverwriteIcons_Warning": "",
|
||||
"DevDetail_button_Reset": "",
|
||||
"DevDetail_button_Save": "",
|
||||
"DevDetail_button_Reset": "Değişiklikleri Sıfırla",
|
||||
"DevDetail_button_Save": "Kaydet",
|
||||
"Device_MultiEdit": "",
|
||||
"Device_MultiEdit_Backup": "",
|
||||
"Device_MultiEdit_Fields": "",
|
||||
"Device_MultiEdit_MassActions": "",
|
||||
"Device_MultiEdit_MassActions": "Toplu komutlar:",
|
||||
"Device_MultiEdit_Tooltip": "",
|
||||
"Device_Searchbox": "",
|
||||
"Device_Shortcut_AllDevices": "",
|
||||
"Device_Shortcut_AllDevices": "Cihazlarım",
|
||||
"Device_Shortcut_Archived": "",
|
||||
"Device_Shortcut_Connected": "",
|
||||
"Device_Shortcut_Devices": "",
|
||||
"Device_Shortcut_Connected": "Bağlandı",
|
||||
"Device_Shortcut_Devices": "Cihazlar",
|
||||
"Device_Shortcut_DownAlerts": "",
|
||||
"Device_Shortcut_DownOnly": "",
|
||||
"Device_Shortcut_Favorites": "",
|
||||
"Device_Shortcut_NewDevices": "",
|
||||
"Device_Shortcut_Favorites": "Favoriler",
|
||||
"Device_Shortcut_NewDevices": "Yeni Cİhazlar",
|
||||
"Device_Shortcut_OnlineChart": "",
|
||||
"Device_TableHead_Connected_Devices": "",
|
||||
"Device_TableHead_Connected_Devices": "Bağlantılar",
|
||||
"Device_TableHead_Favorite": "",
|
||||
"Device_TableHead_FirstSession": "",
|
||||
"Device_TableHead_FirstSession": "İlk Oturum",
|
||||
"Device_TableHead_GUID": "",
|
||||
"Device_TableHead_Group": "",
|
||||
"Device_TableHead_Group": "Grup",
|
||||
"Device_TableHead_Icon": "",
|
||||
"Device_TableHead_LastIP": "",
|
||||
"Device_TableHead_LastIPOrder": "",
|
||||
"Device_TableHead_LastSession": "",
|
||||
"Device_TableHead_Location": "",
|
||||
"Device_TableHead_Location": "Konum",
|
||||
"Device_TableHead_MAC": "",
|
||||
"Device_TableHead_MAC_full": "",
|
||||
"Device_TableHead_Name": "",
|
||||
"Device_TableHead_Name": "İsim",
|
||||
"Device_TableHead_NetworkSite": "",
|
||||
"Device_TableHead_Owner": "",
|
||||
"Device_TableHead_Parent_MAC": "",
|
||||
@@ -215,96 +215,96 @@
|
||||
"Device_TableHead_RowID": "",
|
||||
"Device_TableHead_Rowid": "",
|
||||
"Device_TableHead_SSID": "",
|
||||
"Device_TableHead_Status": "",
|
||||
"Device_TableHead_Status": "Durum",
|
||||
"Device_TableHead_SyncHubNodeName": "",
|
||||
"Device_TableHead_Type": "",
|
||||
"Device_TableHead_Vendor": "",
|
||||
"Device_Table_Not_Network_Device": "",
|
||||
"Device_Table_Not_Network_Device": "Ağ cihazı olarak ayarlanmadı",
|
||||
"Device_Table_info": "",
|
||||
"Device_Table_nav_next": "",
|
||||
"Device_Table_nav_prev": "",
|
||||
"Device_Table_nav_next": "Sonraki",
|
||||
"Device_Table_nav_prev": "Önceki",
|
||||
"Device_Tablelenght": "",
|
||||
"Device_Tablelenght_all": "",
|
||||
"Device_Title": "",
|
||||
"Donations_Others": "",
|
||||
"Device_Title": "Cihazlar",
|
||||
"Donations_Others": "Diğerleri",
|
||||
"Donations_Platforms": "",
|
||||
"Donations_Text": "",
|
||||
"Donations_Title": "",
|
||||
"ENABLE_PLUGINS_description": "",
|
||||
"ENABLE_PLUGINS_name": "",
|
||||
"Email_display_name": "",
|
||||
"Email_icon": "",
|
||||
"Events_Loading": "",
|
||||
"Email_display_name": "Eposta",
|
||||
"Email_icon": "<i class=\"fa fa-at\"></i>",
|
||||
"Events_Loading": "Yükleniyor...",
|
||||
"Events_Periodselect_All": "",
|
||||
"Events_Periodselect_LastMonth": "",
|
||||
"Events_Periodselect_LastWeek": "",
|
||||
"Events_Periodselect_LastYear": "",
|
||||
"Events_Periodselect_today": "",
|
||||
"Events_Periodselect_LastMonth": "Geçen Ay",
|
||||
"Events_Periodselect_LastWeek": "Geçen Hafta",
|
||||
"Events_Periodselect_LastYear": "Geçen Yıl",
|
||||
"Events_Periodselect_today": "Bugün",
|
||||
"Events_Searchbox": "",
|
||||
"Events_Shortcut_AllEvents": "",
|
||||
"Events_Shortcut_DownAlerts": "",
|
||||
"Events_Shortcut_Events": "",
|
||||
"Events_Shortcut_MissSessions": "",
|
||||
"Events_Shortcut_NewDevices": "",
|
||||
"Events_Shortcut_Sessions": "",
|
||||
"Events_Shortcut_NewDevices": "Yeni Cİhazlar",
|
||||
"Events_Shortcut_Sessions": "Oturumlar",
|
||||
"Events_Shortcut_VoidSessions": "",
|
||||
"Events_TableHead_AdditionalInfo": "",
|
||||
"Events_TableHead_Connection": "",
|
||||
"Events_TableHead_Date": "",
|
||||
"Events_TableHead_Device": "",
|
||||
"Events_TableHead_AdditionalInfo": "Ek Bilgi",
|
||||
"Events_TableHead_Connection": "Bağlantı",
|
||||
"Events_TableHead_Date": "Tarih",
|
||||
"Events_TableHead_Device": "Cihaz",
|
||||
"Events_TableHead_Disconnection": "",
|
||||
"Events_TableHead_Duration": "",
|
||||
"Events_TableHead_Duration": "Süre",
|
||||
"Events_TableHead_DurationOrder": "",
|
||||
"Events_TableHead_EventType": "",
|
||||
"Events_TableHead_IP": "",
|
||||
"Events_TableHead_IPOrder": "",
|
||||
"Events_TableHead_Order": "",
|
||||
"Events_TableHead_Order": "Sıra",
|
||||
"Events_TableHead_Owner": "",
|
||||
"Events_TableHead_PendingAlert": "",
|
||||
"Events_Table_info": "",
|
||||
"Events_Table_nav_next": "",
|
||||
"Events_Table_nav_prev": "",
|
||||
"Events_Table_nav_prev": "Önceki",
|
||||
"Events_Tablelenght": "",
|
||||
"Events_Tablelenght_all": "",
|
||||
"Events_Title": "",
|
||||
"Gen_Action": "",
|
||||
"Gen_Add": "",
|
||||
"Gen_Add_All": "",
|
||||
"Gen_All_Devices": "",
|
||||
"Gen_AreYouSure": "",
|
||||
"Gen_Action": "Komut",
|
||||
"Gen_Add": "Ekle",
|
||||
"Gen_Add_All": "Tümünü ekle",
|
||||
"Gen_All_Devices": "Tüm Cihazlar",
|
||||
"Gen_AreYouSure": "Emin misiniz?",
|
||||
"Gen_Backup": "",
|
||||
"Gen_Cancel": "",
|
||||
"Gen_Copy": "",
|
||||
"Gen_DataUpdatedUITakesTime": "",
|
||||
"Gen_Delete": "",
|
||||
"Gen_DeleteAll": "",
|
||||
"Gen_Error": "",
|
||||
"Gen_Filter": "",
|
||||
"Gen_Cancel": "İptal",
|
||||
"Gen_Copy": "Çalıştır",
|
||||
"Gen_DataUpdatedUITakesTime": "TAMAM - Eğer bir tarama çalışıyorsa arayüzün güncellenmesi biraz zaman alabilir",
|
||||
"Gen_Delete": "Sil",
|
||||
"Gen_DeleteAll": "Tümünü sil",
|
||||
"Gen_Error": "Hata",
|
||||
"Gen_Filter": "Filtre",
|
||||
"Gen_LockedDB": "",
|
||||
"Gen_Offline": "",
|
||||
"Gen_Okay": "",
|
||||
"Gen_Purge": "",
|
||||
"Gen_Offline": "Çevrimdışı",
|
||||
"Gen_Okay": "Tamam",
|
||||
"Gen_Purge": "Çıkar",
|
||||
"Gen_ReadDocs": "",
|
||||
"Gen_Remove_All": "",
|
||||
"Gen_Remove_All": "Tümünü kaldır",
|
||||
"Gen_Remove_Last": "",
|
||||
"Gen_Restore": "",
|
||||
"Gen_Run": "",
|
||||
"Gen_Save": "",
|
||||
"Gen_Saved": "",
|
||||
"Gen_Run": "Çalıştır",
|
||||
"Gen_Save": "Kaydet",
|
||||
"Gen_Saved": "Kaydedildi",
|
||||
"Gen_Search": "",
|
||||
"Gen_Selected_Devices": "",
|
||||
"Gen_Selected_Devices": "Seçilmiş Cihazlar:",
|
||||
"Gen_Switch": "",
|
||||
"Gen_Upd": "",
|
||||
"Gen_Upd": "Başarılı bir şekilde güncellendi",
|
||||
"Gen_Upd_Fail": "",
|
||||
"Gen_Update": "",
|
||||
"Gen_Update_Value": "",
|
||||
"Gen_Warning": "",
|
||||
"Gen_Warning": "Uyarı",
|
||||
"Gen_Work_In_Progress": "",
|
||||
"General_display_name": "",
|
||||
"General_icon": "",
|
||||
"General_display_name": "Genel",
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "",
|
||||
"HRS_TO_KEEP_NEWDEV_name": "",
|
||||
"HelpFAQ_Cat_Detail": "",
|
||||
"HelpFAQ_Cat_Detail": "Detaylar",
|
||||
"HelpFAQ_Cat_Detail_300_head": "",
|
||||
"HelpFAQ_Cat_Detail_300_text_a": "",
|
||||
"HelpFAQ_Cat_Detail_300_text_b": "",
|
||||
@@ -314,24 +314,24 @@
|
||||
"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_Detail_303_head": "Nmap nedir ve ne içindir?",
|
||||
"HelpFAQ_Cat_Detail_303_text": "Nmap birden fazla fonksiyona sahip bir ağ tarayıcısıdır..<br>Listenizde yeni bir cihaz belirdiği zaman, Nmap taraması sayesinde o cihaz hakkında daha çok bilgi alabilme olanağınız var.",
|
||||
"HelpFAQ_Cat_Device_200_head": "Listemde bilmediğim cihazlar var. Sildiğim zaman yeniden ortaya çıkıyorlar.",
|
||||
"HelpFAQ_Cat_Device_200_text": "",
|
||||
"HelpFAQ_Cat_General": "",
|
||||
"HelpFAQ_Cat_General": "Genel",
|
||||
"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_head": "Veritabanının salt okunur olduğu mesajını alıyorum.",
|
||||
"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_head": "Bu sayfa ne işe yarar?",
|
||||
"HelpFAQ_Cat_Network_600_text": "",
|
||||
"HelpFAQ_Cat_Network_601_head": "",
|
||||
"HelpFAQ_Cat_Network_601_text": "",
|
||||
@@ -339,34 +339,34 @@
|
||||
"HelpFAQ_Cat_Presence_400_text": "",
|
||||
"HelpFAQ_Cat_Presence_401_head": "",
|
||||
"HelpFAQ_Cat_Presence_401_text": "",
|
||||
"HelpFAQ_Title": "",
|
||||
"HelpFAQ_Title": "Yardım / SSS",
|
||||
"LOADED_PLUGINS_description": "",
|
||||
"LOADED_PLUGINS_name": "",
|
||||
"LOG_LEVEL_description": "",
|
||||
"LOG_LEVEL_name": "",
|
||||
"Loading": "",
|
||||
"Login_Box": "",
|
||||
"Login_Default_PWD": "",
|
||||
"Login_Psw-box": "",
|
||||
"Loading": "Yükleniyor...",
|
||||
"Login_Box": "Şifrenizi giriniz",
|
||||
"Login_Default_PWD": "Varsayılan şifre \"123456\" hâlâ aktif.",
|
||||
"Login_Psw-box": "Şİfre",
|
||||
"Login_Psw_alert": "",
|
||||
"Login_Psw_folder": "",
|
||||
"Login_Psw_new": "",
|
||||
"Login_Psw_new": "yeni_sifre",
|
||||
"Login_Psw_run": "",
|
||||
"Login_Remember": "",
|
||||
"Login_Remember_small": "",
|
||||
"Login_Submit": "",
|
||||
"Login_Remember": "Hatırla",
|
||||
"Login_Remember_small": "(7 gün geçerli)",
|
||||
"Login_Submit": "Oturum aç",
|
||||
"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_Running_Version": "Yüklenmiş sürüm",
|
||||
"Maintenance_Status": "Durum",
|
||||
"Maintenance_Title": "",
|
||||
"Maintenance_Tool_ExportCSV": "",
|
||||
"Maintenance_Tool_ExportCSV_noti": "",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "",
|
||||
"Maintenance_Tool_ExportCSV_noti_text": "Bir CSV dosyası oluşturmak istediğinize emin misiniz?",
|
||||
"Maintenance_Tool_ExportCSV_text": "",
|
||||
"Maintenance_Tool_ImportCSV": "",
|
||||
"Maintenance_Tool_ImportCSV_noti": "",
|
||||
@@ -392,9 +392,9 @@
|
||||
"Maintenance_Tool_del_ActHistory_noti": "",
|
||||
"Maintenance_Tool_del_ActHistory_noti_text": "",
|
||||
"Maintenance_Tool_del_ActHistory_text": "",
|
||||
"Maintenance_Tool_del_alldev": "",
|
||||
"Maintenance_Tool_del_alldev": "Tüm Cihazları Sil",
|
||||
"Maintenance_Tool_del_alldev_noti": "",
|
||||
"Maintenance_Tool_del_alldev_noti_text": "",
|
||||
"Maintenance_Tool_del_alldev_noti_text": "Tüm cihazları silmek istediğinize emin misiniz?",
|
||||
"Maintenance_Tool_del_alldev_text": "",
|
||||
"Maintenance_Tool_del_allevents": "",
|
||||
"Maintenance_Tool_del_allevents30": "",
|
||||
@@ -405,12 +405,12 @@
|
||||
"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": "Cihazları Sil",
|
||||
"Maintenance_Tool_del_empty_macs_noti_text": "",
|
||||
"Maintenance_Tool_del_empty_macs_text": "",
|
||||
"Maintenance_Tool_del_selecteddev": "",
|
||||
"Maintenance_Tool_del_selecteddev": "Seçilmiş cihazları sil",
|
||||
"Maintenance_Tool_del_selecteddev_text": "",
|
||||
"Maintenance_Tool_del_unknowndev": "",
|
||||
"Maintenance_Tool_del_unknowndev": "(bilinmeyen) Cihazları Sil",
|
||||
"Maintenance_Tool_del_unknowndev_noti": "",
|
||||
"Maintenance_Tool_del_unknowndev_noti_text": "",
|
||||
"Maintenance_Tool_del_unknowndev_text": "",
|
||||
@@ -430,59 +430,59 @@
|
||||
"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_Tools_Tab_Settings": "Ayarlar",
|
||||
"Maintenance_Tools_Tab_Tools": "Araçlar",
|
||||
"Maintenance_Tools_Tab_UISettings": "Arayüz Ayarları",
|
||||
"Maintenance_arp_status": "Tarama Durumu",
|
||||
"Maintenance_arp_status_off": "şu anda devre dışı",
|
||||
"Maintenance_arp_status_on": "tarama(lar) şu anda çalışıyor",
|
||||
"Maintenance_built_on": "",
|
||||
"Maintenance_current_version": "",
|
||||
"Maintenance_database_backup": "",
|
||||
"Maintenance_database_backup_found": "",
|
||||
"Maintenance_database_backup_found": "yedekler bulundu",
|
||||
"Maintenance_database_backup_total": "",
|
||||
"Maintenance_database_lastmod": "",
|
||||
"Maintenance_database_path": "",
|
||||
"Maintenance_database_rows": "",
|
||||
"Maintenance_database_size": "",
|
||||
"Maintenance_lang_selector_apply": "",
|
||||
"Maintenance_lang_selector_apply": "Uygula",
|
||||
"Maintenance_lang_selector_empty": "",
|
||||
"Maintenance_lang_selector_lable": "",
|
||||
"Maintenance_lang_selector_text": "",
|
||||
"Maintenance_new_version": "",
|
||||
"Maintenance_themeselector_apply": "",
|
||||
"Maintenance_themeselector_apply": "Uygula",
|
||||
"Maintenance_themeselector_empty": "",
|
||||
"Maintenance_themeselector_lable": "",
|
||||
"Maintenance_themeselector_text": "",
|
||||
"Maintenance_version": "",
|
||||
"NETWORK_DEVICE_TYPES_description": "",
|
||||
"NETWORK_DEVICE_TYPES_name": "",
|
||||
"Navigation_About": "",
|
||||
"Navigation_Devices": "",
|
||||
"Navigation_About": "Hakkında",
|
||||
"Navigation_Devices": "Cihazlar",
|
||||
"Navigation_Donations": "",
|
||||
"Navigation_Events": "",
|
||||
"Navigation_HelpFAQ": "",
|
||||
"Navigation_HelpFAQ": "Yardım / SSS",
|
||||
"Navigation_Integrations": "",
|
||||
"Navigation_Maintenance": "",
|
||||
"Navigation_Monitoring": "",
|
||||
"Navigation_Network": "",
|
||||
"Navigation_Notifications": "",
|
||||
"Navigation_Notifications": "Bildirimler",
|
||||
"Navigation_Plugins": "",
|
||||
"Navigation_Presence": "",
|
||||
"Navigation_Report": "",
|
||||
"Navigation_Settings": "",
|
||||
"Navigation_Settings": "Ayarlar",
|
||||
"Navigation_SystemInfo": "",
|
||||
"Navigation_Workflows": "",
|
||||
"Network_Assign": "",
|
||||
"Network_Cant_Assign": "",
|
||||
"Network_Configuration_Error": "",
|
||||
"Network_Connected": "",
|
||||
"Network_ManageAdd": "",
|
||||
"Network_ManageAdd_Name": "",
|
||||
"Network_ManageAdd_Name_text": "",
|
||||
"Network_Configuration_Error": "Kurulum Hatası",
|
||||
"Network_Connected": "Bağlanmış cihazlar",
|
||||
"Network_ManageAdd": "Cihaz Ekle",
|
||||
"Network_ManageAdd_Name": "Cihaz İsmi",
|
||||
"Network_ManageAdd_Name_text": "Özel karakterler olmadan isim veriniz",
|
||||
"Network_ManageAdd_Port": "",
|
||||
"Network_ManageAdd_Port_text": "",
|
||||
"Network_ManageAdd_Submit": "",
|
||||
"Network_ManageAdd_Submit": "Cihaz Ekle",
|
||||
"Network_ManageAdd_Type": "",
|
||||
"Network_ManageAdd_Type_text": "",
|
||||
"Network_ManageAssign": "",
|
||||
@@ -490,15 +490,15 @@
|
||||
"Network_ManageDel_Name": "",
|
||||
"Network_ManageDel_Name_text": "",
|
||||
"Network_ManageDel_Submit": "",
|
||||
"Network_ManageDevices": "",
|
||||
"Network_ManageDevices": "Cihazları Yönet",
|
||||
"Network_ManageEdit": "",
|
||||
"Network_ManageEdit_ID": "",
|
||||
"Network_ManageEdit_ID_text": "",
|
||||
"Network_ManageEdit_Name": "",
|
||||
"Network_ManageEdit_Name": "Yeni Cihaz İsmi",
|
||||
"Network_ManageEdit_Name_text": "",
|
||||
"Network_ManageEdit_Port": "",
|
||||
"Network_ManageEdit_Port_text": "",
|
||||
"Network_ManageEdit_Submit": "",
|
||||
"Network_ManageEdit_Submit": "Ayarları Kaydet",
|
||||
"Network_ManageEdit_Type": "",
|
||||
"Network_ManageEdit_Type_text": "",
|
||||
"Network_ManageLeaf": "",
|
||||
@@ -516,7 +516,7 @@
|
||||
"Network_Table_State": "",
|
||||
"Network_Title": "",
|
||||
"Network_UnassignedDevices": "",
|
||||
"Notifications_All": "",
|
||||
"Notifications_All": "Tüm Bildirimler",
|
||||
"Notifications_Mark_All_Read": "",
|
||||
"PIALERT_WEB_PASSWORD_description": "",
|
||||
"PIALERT_WEB_PASSWORD_name": "",
|
||||
@@ -531,21 +531,21 @@
|
||||
"Plugins_Out_of": "",
|
||||
"Plugins_Unprocessed_Events": "",
|
||||
"Plugins_no_control": "",
|
||||
"Presence_CalHead_day": "",
|
||||
"Presence_CalHead_day": "gün",
|
||||
"Presence_CalHead_lang": "",
|
||||
"Presence_CalHead_month": "",
|
||||
"Presence_CalHead_quarter": "",
|
||||
"Presence_CalHead_week": "",
|
||||
"Presence_CalHead_year": "",
|
||||
"Presence_CallHead_Devices": "",
|
||||
"Presence_Loading": "",
|
||||
"Presence_Shortcut_AllDevices": "",
|
||||
"Presence_CalHead_quarter": "çeyrek",
|
||||
"Presence_CalHead_week": "hafta",
|
||||
"Presence_CalHead_year": "yıl",
|
||||
"Presence_CallHead_Devices": "Cihazlar",
|
||||
"Presence_Loading": "Yükleniyor...",
|
||||
"Presence_Shortcut_AllDevices": "Cihazlarım",
|
||||
"Presence_Shortcut_Archived": "",
|
||||
"Presence_Shortcut_Connected": "",
|
||||
"Presence_Shortcut_Devices": "",
|
||||
"Presence_Shortcut_Devices": "Cihazlar",
|
||||
"Presence_Shortcut_DownAlerts": "",
|
||||
"Presence_Shortcut_Favorites": "",
|
||||
"Presence_Shortcut_NewDevices": "",
|
||||
"Presence_Shortcut_Favorites": "Favoriler",
|
||||
"Presence_Shortcut_NewDevices": "Yeni Cihazlar",
|
||||
"Presence_Title": "",
|
||||
"REPORT_DASHBOARD_URL_description": "",
|
||||
"REPORT_DASHBOARD_URL_name": "",
|
||||
@@ -571,21 +571,21 @@
|
||||
"Systeminfo_CPU_Vendor": "",
|
||||
"Systeminfo_Client_Resolution": "",
|
||||
"Systeminfo_Client_User_Agent": "",
|
||||
"Systeminfo_General": "",
|
||||
"Systeminfo_General_Date": "",
|
||||
"Systeminfo_General": "Genel",
|
||||
"Systeminfo_General_Date": "Tarih:",
|
||||
"Systeminfo_General_Date2": "",
|
||||
"Systeminfo_General_Full_Date": "",
|
||||
"Systeminfo_General_TimeZone": "",
|
||||
"Systeminfo_General_TimeZone": "Zaman dilimi:",
|
||||
"Systeminfo_Memory": "",
|
||||
"Systeminfo_Memory_Total_Memory": "",
|
||||
"Systeminfo_Memory_Usage": "",
|
||||
"Systeminfo_Memory_Usage_Percent": "",
|
||||
"Systeminfo_Motherboard": "",
|
||||
"Systeminfo_Motherboard": "Anakart",
|
||||
"Systeminfo_Motherboard_BIOS": "",
|
||||
"Systeminfo_Motherboard_BIOS_Date": "",
|
||||
"Systeminfo_Motherboard_BIOS_Vendor": "",
|
||||
"Systeminfo_Motherboard_Manufactured": "",
|
||||
"Systeminfo_Motherboard_Name": "",
|
||||
"Systeminfo_Motherboard_Name": "İsim:",
|
||||
"Systeminfo_Motherboard_Revision": "",
|
||||
"Systeminfo_Network": "",
|
||||
"Systeminfo_Network_Accept_Encoding": "",
|
||||
@@ -596,7 +596,7 @@
|
||||
"Systeminfo_Network_HTTP_Referer_String": "",
|
||||
"Systeminfo_Network_Hardware": "",
|
||||
"Systeminfo_Network_Hardware_Interface_Mask": "",
|
||||
"Systeminfo_Network_Hardware_Interface_Name": "",
|
||||
"Systeminfo_Network_Hardware_Interface_Name": "Arayüz İsmi",
|
||||
"Systeminfo_Network_Hardware_Interface_RX": "",
|
||||
"Systeminfo_Network_Hardware_Interface_TX": "",
|
||||
"Systeminfo_Network_IP": "",
|
||||
@@ -617,35 +617,35 @@
|
||||
"Systeminfo_Services_Description": "",
|
||||
"Systeminfo_Services_Name": "",
|
||||
"Systeminfo_Storage": "",
|
||||
"Systeminfo_Storage_Device": "",
|
||||
"Systeminfo_Storage_Device": "Cihaz:",
|
||||
"Systeminfo_Storage_Mount": "",
|
||||
"Systeminfo_Storage_Size": "",
|
||||
"Systeminfo_Storage_Size": "Boyut:",
|
||||
"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": "Sistem",
|
||||
"Systeminfo_System_AVG": "",
|
||||
"Systeminfo_System_Architecture": "",
|
||||
"Systeminfo_System_Kernel": "",
|
||||
"Systeminfo_System_OSVersion": "",
|
||||
"Systeminfo_System_Running_Processes": "",
|
||||
"Systeminfo_System_System": "",
|
||||
"Systeminfo_System_System": "Sistem:",
|
||||
"Systeminfo_System_Uname": "",
|
||||
"Systeminfo_System_Uptime": "",
|
||||
"Systeminfo_This_Client": "",
|
||||
"Systeminfo_USB_Devices": "",
|
||||
"Systeminfo_USB_Devices": "USB Aygıtları",
|
||||
"TICKER_MIGRATE_TO_NETALERTX": "",
|
||||
"TIMEZONE_description": "",
|
||||
"TIMEZONE_name": "",
|
||||
"TIMEZONE_name": "Zaman dilimi",
|
||||
"UI_DEV_SECTIONS_description": "",
|
||||
"UI_DEV_SECTIONS_name": "",
|
||||
"UI_ICONS_description": "",
|
||||
"UI_ICONS_name": "",
|
||||
"UI_LANG_description": "",
|
||||
"UI_LANG_name": "",
|
||||
"UI_LANG_name": "Arayüz Dili",
|
||||
"UI_MY_DEVICES_description": "",
|
||||
"UI_MY_DEVICES_name": "",
|
||||
"UI_NOT_RANDOM_MAC_description": "",
|
||||
@@ -654,13 +654,13 @@
|
||||
"UI_PRESENCE_name": "",
|
||||
"UI_REFRESH_description": "",
|
||||
"UI_REFRESH_name": "",
|
||||
"devices_old": "",
|
||||
"devices_old": "Yenileniyor...",
|
||||
"general_event_description": "",
|
||||
"general_event_title": "",
|
||||
"report_guid": "",
|
||||
"report_guid_missing": "",
|
||||
"report_select_format": "",
|
||||
"report_time": "",
|
||||
"report_time": "Bildirim zamanı:",
|
||||
"run_event_icon": "",
|
||||
"run_event_tooltip": "",
|
||||
"settings_core_icon": "",
|
||||
@@ -679,15 +679,15 @@
|
||||
"settings_old": "",
|
||||
"settings_other_scanners": "",
|
||||
"settings_other_scanners_icon": "",
|
||||
"settings_other_scanners_label": "",
|
||||
"settings_other_scanners_label": "Diğer tarayıcılar",
|
||||
"settings_publishers": "",
|
||||
"settings_publishers_icon": "",
|
||||
"settings_publishers_info": "",
|
||||
"settings_publishers_label": "",
|
||||
"settings_saved": "",
|
||||
"settings_system_icon": "",
|
||||
"settings_system_label": "",
|
||||
"settings_system_label": "Sistem",
|
||||
"settings_update_item_warning": "",
|
||||
"test_event_icon": "",
|
||||
"test_event_tooltip": ""
|
||||
}
|
||||
}
|
||||
|
||||
1252
front/php/templates/language/zh_cn.json
Executable file → Normal file
1252
front/php/templates/language/zh_cn.json
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@ NetAlertX supports additional plugins to extend its functionality, each with its
|
||||
|
||||
|
||||
## 📑 Available Plugins
|
||||
|
||||
|
||||
Device-detecting plugins insert values into the `CurrentScan` database table. The plugins that are not required are safe to ignore, however, it makes sense to have at least some device-detecting plugins enabled, such as `ARPSCAN` or `NMAPDEV`.
|
||||
|
||||
|
||||
@@ -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/) |
|
||||
| `NTFPRCS` | ⚙ | Notification processing | | Yes | Template | [notification_processing](/front/plugins/notification_processing/)|
|
||||
| `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/) |
|
||||
| `PIHOLE` | 🔍/📥 | Pi-hole device import & sync | | | SQLite DB | [pihole_scan](/front/plugins/pihole_scan/) |
|
||||
| `PUSHSAFER` | ▶️ | Pushsafer notifications | | | Script | [_publisher_pushsafer](/front/plugins/_publisher_pushsafer/) |
|
||||
@@ -52,9 +52,9 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
|
||||
| `SETPWD` | ⚙ | Set password | | Yes | Template | [set_password](/front/plugins/set_password/) |
|
||||
| `SMTP` | ▶️ | Email notifications | | | Script | [_publisher_email](/front/plugins/_publisher_email/) |
|
||||
| `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/) |
|
||||
| `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/) |
|
||||
| `WEBHOOK` | ▶️ | Webhook notifications | | | Script | [_publisher_webhook](/front/plugins/_publisher_webhook/) |
|
||||
| `WEBMON` | ♻ | Website down monitoring | | | Script | [website_monitor](/front/plugins/website_monitor/) |
|
||||
@@ -81,7 +81,7 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
|
||||
|
||||
| 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 |
|
||||
|
||||
|
||||
|
||||
@@ -173,6 +173,16 @@
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
@@ -194,15 +204,6 @@
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@ import pathlib
|
||||
import sys
|
||||
import json
|
||||
import sqlite3
|
||||
from pytz import timezone
|
||||
|
||||
# Define the installation path and extend the system path for plugin imports
|
||||
INSTALL_PATH = "/app"
|
||||
@@ -16,6 +17,10 @@ from logger import mylog
|
||||
from const import pluginsPath, fullDbPath
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from notification import write_notification
|
||||
import conf
|
||||
|
||||
# Make sure the TIMEZONE for logging is correct
|
||||
conf.tz = timezone(get_setting_value('TIMEZONE'))
|
||||
|
||||
# Define the current path and log file paths
|
||||
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||
@@ -57,7 +62,12 @@ def main():
|
||||
watched3 = device['device_type'],
|
||||
watched4 = device['last_seen'],
|
||||
extra = '',
|
||||
foreignKey = device['mac_address'])
|
||||
foreignKey = device['mac_address']
|
||||
# helpVal1 = "Something1", # Optional Helper values to be passed for mapping into the app
|
||||
# helpVal2 = "Something1", # If you need to use even only 1, add the remaining ones too
|
||||
# helpVal3 = "Something1", # and set them to 'null'. Check the the docs for details:
|
||||
# helpVal4 = "Something1", # https://github.com/jokob-sk/NetAlertX/blob/main/docs/PLUGINS_DEV.md
|
||||
)
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] New entries: "{len(device_data)}"'])
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ 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')
|
||||
|
||||
@@ -27,7 +27,10 @@ from logger import mylog, append_line_to_file, print_log
|
||||
from helper import timeNowTZ, get_setting_value, hide_email
|
||||
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')
|
||||
|
||||
@@ -499,6 +499,38 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "TLS",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "checkbox" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": false,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "MQTT TLS"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Enable TLS support."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Habilitar soporte TLS."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "USER",
|
||||
"type": {
|
||||
|
||||
@@ -29,7 +29,10 @@ from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ, get_setting_value, bytes_to_string, sanitize_string
|
||||
from notification import Notification_obj
|
||||
from database import DB, get_device_stats
|
||||
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')
|
||||
@@ -193,7 +196,10 @@ class sensor_config:
|
||||
def publish_mqtt(mqtt_client, topic, message):
|
||||
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')
|
||||
|
||||
mylog('verbose', [f"[{pluginName}] Sending MQTT topic: {topic}"])
|
||||
@@ -292,9 +298,11 @@ def mqtt_create_client():
|
||||
if get_setting_value('MQTT_VERSION') == 1:
|
||||
mqtt_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1)
|
||||
else:
|
||||
mqtt_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
|
||||
mqtt_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
|
||||
|
||||
if get_setting_value('MQTT_TLS'):
|
||||
mqtt_client.tls_set()
|
||||
|
||||
|
||||
mqtt_client.username_pw_set(get_setting_value('MQTT_USER'), get_setting_value('MQTT_PASSWORD'))
|
||||
mqtt_client.on_connect = on_connect
|
||||
mqtt_client.on_disconnect = on_disconnect
|
||||
@@ -359,7 +367,7 @@ def mqtt_start(db):
|
||||
|
||||
# Create devices in Home Assistant - send config messages
|
||||
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', 'mac_address', 'folder-key-network', device["dev_MAC"])
|
||||
|
||||
@@ -22,7 +22,10 @@ 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')
|
||||
|
||||
@@ -16,6 +16,10 @@ from notification import Notification_obj # noqa: E402
|
||||
from database import DB # noqa: E402
|
||||
import conf
|
||||
from const import confFileName
|
||||
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")
|
||||
|
||||
@@ -22,6 +22,10 @@ from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ, get_setting_value, hide_string
|
||||
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')
|
||||
|
||||
@@ -25,6 +25,10 @@ from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ, get_setting_value, hide_string, write_file
|
||||
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')
|
||||
|
||||
@@ -18,6 +18,11 @@ from plugin_helper import Plugin_Object, Plugin_Objects, handleEmpty
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath
|
||||
import conf
|
||||
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())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
|
||||
@@ -16,9 +16,13 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath, fullDbPath
|
||||
import conf
|
||||
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())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
|
||||
@@ -18,7 +18,11 @@ from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath, fullDbPath
|
||||
import conf
|
||||
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())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
|
||||
@@ -19,9 +19,13 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ, check_IP_format
|
||||
from helper import timeNowTZ, get_setting_value, check_IP_format
|
||||
from const import logPath, applicationPath, fullDbPath
|
||||
import conf
|
||||
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())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
|
||||
@@ -525,6 +525,16 @@
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
@@ -546,15 +556,6 @@
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -15,6 +15,12 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, handleEmpty, is_mac
|
||||
from logger import mylog
|
||||
from dhcp_leases import DhcpLeases
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
import conf
|
||||
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())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
|
||||
@@ -12,6 +12,12 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Objects, Plugin_Object
|
||||
from logger import mylog
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
import conf
|
||||
from pytz import timezone
|
||||
|
||||
# Make sure the TIMEZONE for logging is correct
|
||||
conf.tz = timezone(get_setting_value('TIMEZONE'))
|
||||
|
||||
def main():
|
||||
|
||||
|
||||
@@ -22,6 +22,11 @@ from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ, check_IP_format, get_setting_value
|
||||
from const import logPath, applicationPath, fullDbPath
|
||||
import conf
|
||||
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())
|
||||
|
||||
@@ -13,7 +13,12 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Objects
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
import conf
|
||||
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')
|
||||
|
||||
@@ -19,6 +19,11 @@ from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath
|
||||
import conf
|
||||
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())
|
||||
|
||||
7
front/plugins/mikrotik_scan/README.md
Executable file
7
front/plugins/mikrotik_scan/README.md
Executable file
@@ -0,0 +1,7 @@
|
||||
## Overview
|
||||
|
||||
Plugin for device name discovery via the Mikrotik dhcp-server leases
|
||||
|
||||
### Usage
|
||||
|
||||
- Check the Settings page for details.
|
||||
437
front/plugins/mikrotik_scan/config.json
Executable file
437
front/plugins/mikrotik_scan/config.json
Executable file
@@ -0,0 +1,437 @@
|
||||
{
|
||||
"code_name": "mikrotik_scan",
|
||||
"unique_prefix": "MTSCAN",
|
||||
"plugin_type": "other",
|
||||
"execution_order" : "Layer_4",
|
||||
"enabled": true,
|
||||
"data_source": "script",
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"show_ui": true,
|
||||
"localized": ["display_name", "description", "icon"],
|
||||
"display_name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Mikrotik (Name discovery)"
|
||||
}
|
||||
],
|
||||
"icon": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "<i class=\"fa-solid fa-search\"></i>"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "A plugin to discover device names."
|
||||
}
|
||||
],
|
||||
"params": [
|
||||
{
|
||||
"name": "ips",
|
||||
"type": "sql",
|
||||
"value": "SELECT dev_LastIP from DEVICES order by dev_MAC",
|
||||
"timeoutMultiplier": true
|
||||
},
|
||||
{
|
||||
"name": "mt_host",
|
||||
"type": "setting",
|
||||
"value": "MTSCAN_MT_HOST"
|
||||
},
|
||||
{
|
||||
"name": "mt_port",
|
||||
"type": "setting",
|
||||
"value": "MTSCAN_MT_PORT"
|
||||
},
|
||||
{
|
||||
"name": "mt_user",
|
||||
"type": "setting",
|
||||
"value": "MTSCAN_MT_USER"
|
||||
},
|
||||
{
|
||||
"name": "mt_pass",
|
||||
"type": "setting",
|
||||
"value": "MTSCAN_MT_PASS"
|
||||
}
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"function": "RUN",
|
||||
"events": ["run"],
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "select", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "disabled",
|
||||
"options": [
|
||||
"disabled",
|
||||
"before_name_updates",
|
||||
"on_new_device",
|
||||
"once",
|
||||
"schedule",
|
||||
"always_after_scan"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "When to run"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "When the plugin should be executed. If enabled this will execute the scan until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Setting this to <code>on_new_device</code> or a daily <code>schedule</code> is recommended."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "readonly": "true" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "python3 /app/front/plugins/mikrotik_scan/mikrotik.py",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Command"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Command to run. This can not be changed"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "RUN_SCHD",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "*/30 * * * *",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Schedule"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Only enabled if you select <code>schedule</code> in the <a href=\"#MKTSCAN_RUN\"><code>MKTSCAN_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "MT_HOST",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "192.168.88.1",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Mikrotik Host IP"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "IP for Mikrotik Router"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "MT_PORT",
|
||||
"type": {
|
||||
"dataType": "integer",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "number" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": 8728,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Mikrotik API Port"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "API Port for Mikrotik Router"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "MT_USER",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "admin",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Mikrotik User"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "User for Mikrotik Router"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "MT_PASS",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "input",
|
||||
"elementOptions": [{ "type": "password" }],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Mikrotik Password"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Password for Mikrotik Router"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"mapped_to_column": "cur_MAC",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Name"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "ForeignKey",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_mac",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "MAC"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"mapped_to_column": "cur_IP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_ip",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "IP"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_ip",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Lease IP"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"mapped_to_column": "cur_Name",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Name"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Host Name"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Last Seen"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "HelpVal1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Comment"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Dummy",
|
||||
"mapped_to_column": "cur_ScanMethod",
|
||||
"mapped_to_column_data": {
|
||||
"value": "MTSCAN"
|
||||
},
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Scan method"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Created"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Creado"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Changed"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Cambiado"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
142
front/plugins/mikrotik_scan/mikrotik.py
Executable file
142
front/plugins/mikrotik_scan/mikrotik.py
Executable file
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/env python
|
||||
# test script by running:
|
||||
# tbc
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
import argparse
|
||||
import subprocess
|
||||
import sys
|
||||
import hashlib
|
||||
import csv
|
||||
import sqlite3
|
||||
import re
|
||||
from io import StringIO
|
||||
from datetime import datetime
|
||||
|
||||
# Register NetAlertX directories
|
||||
INSTALL_PATH="/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath, fullDbPath
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
import conf
|
||||
from pytz import timezone
|
||||
from librouteros import connect
|
||||
from librouteros.exceptions import TrapError
|
||||
|
||||
# Make sure the TIMEZONE for logging is correct
|
||||
conf.tz = timezone(get_setting_value('TIMEZONE'))
|
||||
|
||||
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
RESULT_FILE = os.path.join(CUR_PATH, 'last_result.log')
|
||||
|
||||
pluginName = 'MTSCAN'
|
||||
|
||||
def main():
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] In script'])
|
||||
|
||||
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_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
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
|
||||
# Create a Device_obj instance
|
||||
device_handler = Device_obj(db)
|
||||
|
||||
# Retrieve devices
|
||||
#unknown_devices = device_handler.getUnknown()
|
||||
#mylog('verbose', [f'[{pluginName}] Unknown devices count: {len(unknown_devices)}'])
|
||||
|
||||
all_devices = device_handler.getAll()
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] all devices count: {len(all_devices)}'])
|
||||
|
||||
device_map = {d['dev_MAC']:d['dev_LastIP'] for d in all_devices}
|
||||
|
||||
try:
|
||||
# connect router
|
||||
api = connect(username=mt_user, password=mt_password, host=mt_host, port=mt_port)
|
||||
|
||||
# get dhcp leases
|
||||
leases = api('/ip/dhcp-server/lease/print')
|
||||
|
||||
|
||||
|
||||
for lease in leases:
|
||||
lease_id = lease.get('.id')
|
||||
address = lease.get('address')
|
||||
mac_address = lease.get('mac-address').lower()
|
||||
host_name = lease.get('host-name')
|
||||
comment = lease.get('comment')
|
||||
last_seen = lease.get('last-seen')
|
||||
|
||||
mylog('verbose', [f"ID: {lease_id}, Address: {address}, MAC Address: {mac_address}, Host Name: {host_name}, Comment: {comment}, Last Seen: {last_seen}"])
|
||||
if mac_address in device_map.keys():
|
||||
device_name = host_name
|
||||
if comment != '':
|
||||
device_name = comment
|
||||
|
||||
plugin_objects.add_object(
|
||||
# "Name-MAC", "LastIP", "IP", "Name","Host","LastSeen","Comment"
|
||||
primaryId = mac_address,
|
||||
secondaryId = device_map[mac_address],
|
||||
watched1 = address,
|
||||
watched2 = device_name,
|
||||
watched3 = host_name,
|
||||
watched4 = last_seen,
|
||||
extra = '',
|
||||
helpVal1 = comment,
|
||||
foreignKey = mac_address)
|
||||
|
||||
plugin_objects.write_result_file()
|
||||
except TrapError as e:
|
||||
mylog('error', [f"An error occurred: {e}"])
|
||||
except Exception as 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'])
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# BEGIN
|
||||
#===============================================================================
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -19,6 +19,11 @@ from helper import timeNowTZ, get_setting_value
|
||||
from notification import write_notification
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
import conf
|
||||
from pytz import timezone
|
||||
|
||||
# Make sure the TIMEZONE for logging is correct
|
||||
conf.tz = timezone(get_setting_value('TIMEZONE'))
|
||||
|
||||
# Define the current path and log file paths
|
||||
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||
|
||||
@@ -52,6 +52,16 @@
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
@@ -73,15 +83,6 @@
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -127,6 +128,16 @@
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
@@ -148,15 +159,6 @@
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -194,14 +196,24 @@
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "sourceSuffixes": ["_in"] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-sm-3" },
|
||||
{ "onClick": "removeAllOptions(this)" },
|
||||
{ "getStringKey": "Gen_Remove_All" }
|
||||
{ "cssClasses": "col-sm-2" },
|
||||
{ "onClick": "addList(this, false)" },
|
||||
{ "getStringKey": "Gen_Add" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": ["base64"]
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
@@ -216,22 +228,13 @@
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
{ "sourceSuffixes": ["_in"] },
|
||||
{ "sourceSuffixes": [] },
|
||||
{ "separator": "" },
|
||||
{ "cssClasses": "col-sm-2" },
|
||||
{ "onClick": "addList(this, false)" },
|
||||
{ "getStringKey": "Gen_Add" }
|
||||
{ "cssClasses": "col-sm-3" },
|
||||
{ "onClick": "removeAllOptions(this)" },
|
||||
{ "getStringKey": "Gen_Remove_All" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": ["base64"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -25,6 +25,11 @@ from helper import timeNowTZ, get_setting_value, extract_between_strings, extrac
|
||||
from const import logPath, applicationPath, fullDbPath
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
import conf
|
||||
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())
|
||||
|
||||
@@ -15,8 +15,13 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath
|
||||
import conf
|
||||
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())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
|
||||
@@ -24,7 +24,11 @@ from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath, fullDbPath
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
import conf
|
||||
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())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
|
||||
@@ -155,6 +155,16 @@
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
@@ -176,15 +186,6 @@
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -4,6 +4,12 @@ __version__ = "0.1" #initial
|
||||
__version__ = "0.2" # added logic to retry omada api call once as it seems to sometimes fail for some reasons, and error handling logic...
|
||||
__version__ = "0.3" # split devices API calls to allow multithreading but had to stop due to concurency issues.
|
||||
__version__ = "0.6" # found issue with multithreading - my omada calls redirect stdout which gets clubbered by normal stdout... not sure how to fix for now...
|
||||
__version__ = "0.7" # avoid updating omada sdn client name when it is the MAC, and naxname is also the same MAC...
|
||||
__version__ = "1.0" # fixed the timzone mylog issue by resetting the tz value at the begining of the script... I suspect it doesn't inherit the tz from the main.
|
||||
__version__ = "1.1" # added logic to handle gracefully a failure of omada devices so it won't try to populate uplinks on non-existent switches and AP.
|
||||
__version__ = "1.2" # finally got multiprocessing to work to parse devices AND to update names! yeah!
|
||||
|
||||
|
||||
# query OMADA SDN to populate NetAlertX witch omada switches, access points, clients.
|
||||
# try to identify and populate their connections by switch/accesspoints and ports/SSID
|
||||
# try to differentiate root bridges from accessory
|
||||
@@ -23,8 +29,10 @@ import importlib.util
|
||||
import time
|
||||
import io
|
||||
import re
|
||||
import concurrent.futures
|
||||
|
||||
#import concurrent.futures
|
||||
import subprocess
|
||||
import multiprocessing
|
||||
|
||||
|
||||
#import netifaces
|
||||
|
||||
@@ -38,6 +46,10 @@ from logger import mylog
|
||||
from const import pluginsPath, fullDbPath
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from notification import write_notification
|
||||
from pytz import timezone
|
||||
import conf
|
||||
conf.tz = timezone(get_setting_value('TIMEZONE'))
|
||||
PARALLELISM = 4
|
||||
|
||||
# Define the current path and log file paths
|
||||
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||
@@ -165,6 +177,7 @@ def add_uplink (uplink_mac, switch_mac, device_data_bymac, sadevices_linksbymac,
|
||||
# Main initialization
|
||||
def main():
|
||||
start_time = time.time()
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] starting execution'])
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
@@ -262,6 +275,20 @@ def get_omada_devices_details(msadevice_data):
|
||||
nswitch_dump = ''
|
||||
return mswitch_detail, mswitch_dump
|
||||
|
||||
def get_omada_devices_details_parallel(msadevice_data):
|
||||
mthisswitch = msadevice_data[dMAC]
|
||||
mtype = msadevice_data[dTYPE]
|
||||
mswitch_detail = ''
|
||||
mswitch_dump = ''
|
||||
if mtype == 'ap':
|
||||
mswitch_detail = subprocess.run('omada access-point '+mthisswitch, capture_output=True, text=True, shell=True).stdout
|
||||
elif mtype == 'switch':
|
||||
mswitch_detail = subprocess.run('omada switch '+mthisswitch, capture_output=True, text=True, shell=True).stdout
|
||||
mswitch_dump = subprocess.run('omada access-point '+mthisswitch, capture_output=True, text=True, shell=True).stdout
|
||||
else:
|
||||
mswitch_detail = ''
|
||||
mswitch_dump = ''
|
||||
return mthisswitch, mswitch_detail, mswitch_dump
|
||||
|
||||
|
||||
# ----------------------------------------------
|
||||
@@ -287,19 +314,36 @@ def get_device_data(omada_clients_output,switches_and_aps,device_handler):
|
||||
omada_force_overwrite = get_setting_value('OMDSDN_force_overwrite')
|
||||
switch_details = {}
|
||||
switch_dumps = {}
|
||||
|
||||
'''
|
||||
command = 'which omada'
|
||||
def run_command(command, index):
|
||||
result = subprocess.run(command, capture_output=True, text=True, shell=True)
|
||||
return str(index), result.stdout.strip()
|
||||
|
||||
myindex, command_output= run_command(command, 2)
|
||||
mylog('verbose', [f'[{pluginName}] command={command} index={myindex} results={command_output}'])
|
||||
'''
|
||||
sadevices = switches_and_aps.splitlines()
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] switches_and_aps rows: "{len(sadevices)}"'])
|
||||
|
||||
with multiprocessing.Pool(processes = PARALLELISM) as mypool:
|
||||
oresults = mypool.map(get_omada_devices_details_parallel, [sadevice.split() for sadevice in sadevices])
|
||||
|
||||
for thisswitch, details, dump in oresults:
|
||||
switch_details[thisswitch] = details
|
||||
switch_dumps[thisswitch] = dump
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] switch={thisswitch} details={details}'])
|
||||
|
||||
'''
|
||||
for sadevice in sadevices:
|
||||
sadevice_data = sadevice.split()
|
||||
thisswitch = sadevice_data[dMAC]
|
||||
thistype = sadevice_data[dTYPE]
|
||||
switch_details[thisswitch], switch_dumps[thisswitch] = get_omada_devices_details(sadevice_data)
|
||||
'''
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] switches details collected "{len(switch_details)}"'])
|
||||
mylog('verbose', [f'[{pluginName}] dump details collected "{len(switch_details)}"'])
|
||||
# Using ThreadPoolExecutor for parallel execution
|
||||
|
||||
for sadevice in sadevices:
|
||||
sadevice_data = sadevice.split()
|
||||
@@ -372,6 +416,8 @@ def get_device_data(omada_clients_output,switches_and_aps,device_handler):
|
||||
|
||||
odevices = omada_clients_output.splitlines()
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] omada_clients_outputs rows: "{len(odevices)}"'])
|
||||
omada_clients_to_rename = []
|
||||
|
||||
for odevice in odevices:
|
||||
odevice_data = odevice.split()
|
||||
odevice_data_reordered = [ MAC, IP, NAME, SWITCH_AP, PORT_SSID, TYPE]
|
||||
@@ -383,7 +429,7 @@ def get_device_data(omada_clients_output,switches_and_aps,device_handler):
|
||||
# if the name stored in Nax for a device is empty or the MAC addres or has some parenthhesis or is the same as in omada
|
||||
# don't bother updating omada's name at all.
|
||||
#
|
||||
|
||||
|
||||
naxname = real_naxname
|
||||
if real_naxname != None:
|
||||
if '(' in real_naxname:
|
||||
@@ -395,15 +441,27 @@ def get_device_data(omada_clients_output,switches_and_aps,device_handler):
|
||||
naxname = odevice_data[cNAME] if odevice_data[cNAME] != '' else odevice_data[cMAC]
|
||||
naxname = naxname.strip()
|
||||
mylog('debug', [f'[{pluginName}] TEST name from MAC: {naxname}'])
|
||||
if odevice_data[cNAME] in (odevice_data[cMAC], 'null', ''):
|
||||
if odevice_data[cNAME] in ('null', ''):
|
||||
mylog('verbose', [f'[{pluginName}] updating omada server because odevice_data is: {odevice_data[cNAME]} and naxname is: "{naxname}"'])
|
||||
callomada(['set-client-name', odevice_data[cMAC], naxname])
|
||||
omada_clients_to_rename.append(['set-client-name',odevice_data[cMAC], naxname])
|
||||
#callomada(['set-client-name', odevice_data[cMAC], naxname])
|
||||
odevice_data_reordered[NAME] = naxname
|
||||
elif odevice_data[cNAME] == odevice_data[cMAC] and ieee2ietf_mac_formater(naxname) != ieee2ietf_mac_formater(odevice_data[cNAME]) :
|
||||
mylog('verbose', [f'[{pluginName}] updating omada server because odevice_data is: "{odevice_data[cNAME]} and naxname is: "{naxname}"'])
|
||||
omada_clients_to_rename.append(['set-client-name',odevice_data[cMAC], naxname])
|
||||
#callomada(['set-client-name', odevice_data[cMAC], naxname])
|
||||
odevice_data_reordered[NAME] = naxname
|
||||
else:
|
||||
if omada_force_overwrite and naxname != odevice_data[cNAME] :
|
||||
mylog('verbose', [f'[{pluginName}] updating omada server because odevice_data is: "{odevice_data[cNAME]} and naxname is: "{naxname}"'])
|
||||
callomada(['set-client-name', odevice_data[cMAC], naxname])
|
||||
omada_clients_to_rename.append(['set-client-name',odevice_data[cMAC], naxname])
|
||||
#callomada(['set-client-name', odevice_data[cMAC], naxname])
|
||||
odevice_data_reordered[NAME] = naxname
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mightbeport = odevice_data[cPORT_SSID].lstrip('(')
|
||||
mightbeport = mightbeport.rstrip(')')
|
||||
if mightbeport.isdigit():
|
||||
@@ -425,9 +483,17 @@ def get_device_data(omada_clients_output,switches_and_aps,device_handler):
|
||||
device_data_mac_byip[odevice_data_reordered[IP]] = odevice_data_reordered[MAC]
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] tokens: "{odevice_data}"'])
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] tokens_reordered: "{odevice_data_reordered}"'])
|
||||
# RENAMING
|
||||
#for omada_client_to_rename in omada_clients_to_rename:
|
||||
# mylog('verbose', [f'[{pluginName}] calling omada: "{omada_client_to_rename}"'])
|
||||
#callomada(omada_client_to_rename)
|
||||
|
||||
# populating the uplinks nodes of the omada switches and access points manually
|
||||
# since OMADA SDN makes is unreliable if the gateway is not their own tplink hardware...
|
||||
|
||||
#
|
||||
with multiprocessing.Pool(processes = PARALLELISM) as mypool2:
|
||||
oresults = mypool2.map(callomada, omada_clients_to_rename)
|
||||
mylog(OMDLOGLEVEL, [f'[{pluginName}] results are: "{oresults}"'])
|
||||
|
||||
# step1 let's find the the default router
|
||||
#
|
||||
@@ -443,7 +509,8 @@ def get_device_data(omada_clients_output,switches_and_aps,device_handler):
|
||||
# step4, let's go recursively through switches other links to mark update their uplinks
|
||||
# and pray it ends one day...
|
||||
#
|
||||
add_uplink(default_router_mac,first_switch, device_data_bymac,sadevices_linksbymac,port_byswitchmac_byclientmac)
|
||||
if len(sadevices) > 0:
|
||||
add_uplink(default_router_mac,first_switch, device_data_bymac,sadevices_linksbymac,port_byswitchmac_byclientmac)
|
||||
return device_data_bymac.values()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -16,8 +16,13 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from logger import mylog
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects
|
||||
from helper import timeNowTZ
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath
|
||||
import conf
|
||||
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())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
|
||||
@@ -49,6 +49,33 @@ def handleEmpty(input):
|
||||
input = re.sub(r'[^\x00-\x7F]+', ' ', input)
|
||||
input = input.replace('\n', '') # Removing new lines
|
||||
return input
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Sanitizes string
|
||||
def rmBadChars(input):
|
||||
|
||||
input = handleEmpty(input)
|
||||
input = input.replace("'", '_') # Removing ' (single quotes)
|
||||
|
||||
return input
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# check if this is a router IP
|
||||
def is_typical_router_ip(ip_address):
|
||||
# List of common default gateway IP addresses
|
||||
common_router_ips = [
|
||||
"192.168.0.1", "192.168.1.1", "192.168.1.254", "192.168.0.254",
|
||||
"10.0.0.1", "10.1.1.1", "192.168.2.1", "192.168.10.1", "192.168.11.1",
|
||||
"192.168.100.1", "192.168.101.1", "192.168.123.254", "192.168.223.1",
|
||||
"192.168.31.1", "192.168.8.1", "192.168.254.254", "192.168.50.1",
|
||||
"192.168.3.1", "192.168.4.1", "192.168.5.1", "192.168.9.1",
|
||||
"192.168.15.1", "192.168.16.1", "192.168.20.1", "192.168.30.1",
|
||||
"192.168.42.1", "192.168.62.1", "192.168.178.1", "192.168.1.1",
|
||||
"192.168.1.254", "192.168.0.1", "192.168.0.10", "192.168.0.100",
|
||||
"192.168.0.254"
|
||||
]
|
||||
|
||||
return ip_address in common_router_ips
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Check if a valid MAC address
|
||||
@@ -99,7 +126,7 @@ def normalize_mac(mac):
|
||||
# -------------------------------------------------------------------
|
||||
class Plugin_Object:
|
||||
"""
|
||||
Plugin_Object class to manage one object introduced by the plugin
|
||||
Plugin_Object class to manage one object introduced by the plugin.
|
||||
An object typically is a device but could also be a website or something
|
||||
else that is monitored by the plugin.
|
||||
"""
|
||||
@@ -114,11 +141,15 @@ class Plugin_Object:
|
||||
watched4="",
|
||||
extra="",
|
||||
foreignKey="",
|
||||
helpVal1="",
|
||||
helpVal2="",
|
||||
helpVal3="",
|
||||
helpVal4="",
|
||||
):
|
||||
self.pluginPref = ""
|
||||
self.primaryId = primaryId
|
||||
self.secondaryId = secondaryId
|
||||
self.created = datetime.now(timeZone).strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.created = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.changed = ""
|
||||
self.watched1 = watched1
|
||||
self.watched2 = watched2
|
||||
@@ -128,13 +159,17 @@ class Plugin_Object:
|
||||
self.extra = extra
|
||||
self.userData = ""
|
||||
self.foreignKey = foreignKey
|
||||
self.helpVal1 = helpVal1 or ""
|
||||
self.helpVal2 = helpVal2 or ""
|
||||
self.helpVal3 = helpVal3 or ""
|
||||
self.helpVal4 = helpVal4 or ""
|
||||
|
||||
def write(self):
|
||||
"""
|
||||
write the object details as a string in the
|
||||
format required to write the result file
|
||||
Write the object details as a string in the
|
||||
format required to write the result file.
|
||||
"""
|
||||
line = "{}|{}|{}|{}|{}|{}|{}|{}|{}\n".format(
|
||||
line = "{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}\n".format(
|
||||
self.primaryId,
|
||||
self.secondaryId,
|
||||
self.created,
|
||||
@@ -144,10 +179,12 @@ class Plugin_Object:
|
||||
self.watched4,
|
||||
self.extra,
|
||||
self.foreignKey,
|
||||
self.helpVal1,
|
||||
self.helpVal2,
|
||||
self.helpVal3,
|
||||
self.helpVal4
|
||||
)
|
||||
return line
|
||||
|
||||
|
||||
|
||||
class Plugin_Objects:
|
||||
"""
|
||||
@@ -155,7 +192,7 @@ class Plugin_Objects:
|
||||
It contains a list of Plugin_Object instances.
|
||||
And can write the required result file.
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, result_file):
|
||||
self.result_file = result_file
|
||||
self.objects = []
|
||||
@@ -170,6 +207,10 @@ class Plugin_Objects:
|
||||
watched4="",
|
||||
extra="",
|
||||
foreignKey="",
|
||||
helpVal1="",
|
||||
helpVal2="",
|
||||
helpVal3="",
|
||||
helpVal4="",
|
||||
):
|
||||
self.objects.append(
|
||||
Plugin_Object(
|
||||
@@ -181,16 +222,17 @@ class Plugin_Objects:
|
||||
watched4,
|
||||
extra,
|
||||
foreignKey,
|
||||
helpVal1,
|
||||
helpVal2,
|
||||
helpVal3,
|
||||
helpVal4
|
||||
)
|
||||
)
|
||||
|
||||
def write_result_file(self):
|
||||
# print ("writing file: "+self.result_file)
|
||||
with open(self.result_file, mode="w") as fp:
|
||||
for obj in self.objects:
|
||||
fp.write(obj.write())
|
||||
fp.close()
|
||||
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, Plugin_Objects):
|
||||
|
||||
@@ -434,6 +434,16 @@
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
@@ -455,15 +465,6 @@
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -13,8 +13,13 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64, handleEmpty, normalize_mac
|
||||
from logger import mylog
|
||||
from helper import timeNowTZ
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath
|
||||
import conf
|
||||
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')
|
||||
|
||||
@@ -20,6 +20,11 @@ from const import pluginsPath, fullDbPath
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from cryptography import encrypt_data
|
||||
from notification import write_notification
|
||||
import conf
|
||||
from pytz import timezone
|
||||
|
||||
# Make sure the TIMEZONE for logging is correct
|
||||
conf.tz = timezone(get_setting_value('TIMEZONE'))
|
||||
|
||||
# Define the current path and log file paths
|
||||
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||
|
||||
@@ -301,6 +301,16 @@
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
@@ -322,15 +332,6 @@
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -13,8 +13,13 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath
|
||||
import conf
|
||||
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())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## 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
|
||||
|
||||
@@ -17,5 +17,4 @@ Specify the following settings in the Settings section of NetAlertX:
|
||||
|
||||
### 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
|
||||
@@ -271,6 +271,7 @@
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"mapped_to_column": "cur_Type",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
@@ -388,6 +389,38 @@
|
||||
"show": true,
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "HelpVal1",
|
||||
"mapped_to_column": "cur_NetworkNodeMAC",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Parent Network MAC"
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"show": true,
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "HelpVal2",
|
||||
"mapped_to_column": "cur_PORT",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Port"
|
||||
}
|
||||
],
|
||||
"options": [],
|
||||
"show": true,
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"css_classes": "col-sm-1",
|
||||
@@ -492,7 +525,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"default_value": "python3 /app/front/plugins/unifi_import/script.py username={username} password={password} host={host} sites={sites} port={port} verifyssl={verifyssl} version={version} fullimport={fullimport}",
|
||||
"default_value": "python3 /app/front/plugins/unifi_import/script.py",
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
@@ -776,6 +809,16 @@
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
@@ -797,15 +840,6 @@
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -14,12 +14,19 @@ from requests import Request, Session, packages
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
from pyunifi.controller import Controller
|
||||
|
||||
|
||||
# Register NetAlertX directories
|
||||
INSTALL_PATH="/app"
|
||||
sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, rmBadChars, is_typical_router_ip
|
||||
from logger import mylog
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
import conf
|
||||
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())
|
||||
LOG_FILE = os.path.join(CUR_PATH, 'script.log')
|
||||
@@ -35,52 +42,30 @@ pluginName = 'UNFIMP'
|
||||
|
||||
def main():
|
||||
|
||||
mylog('verbose', ['[UNFIMP] In script'])
|
||||
mylog('verbose', [f'[{pluginName}] In script'])
|
||||
|
||||
|
||||
# init global variables
|
||||
global UNIFI_USERNAME, UNIFI_PASSWORD, UNIFI_HOST, UNIFI_SITES, PORT, VERIFYSSL, VERSION, FULL_IMPORT
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='Import devices from a UNIFI controller')
|
||||
|
||||
parser.add_argument('username', action="store", help="Username used to login into the UNIFI controller")
|
||||
parser.add_argument('password', action="store", help="Password used to login into the UNIFI controller")
|
||||
parser.add_argument('host', action="store", help="Host url or IP address where the UNIFI controller is hosted (excluding http://)")
|
||||
parser.add_argument('sites', action="store", help="Name of the sites (usually 'default', check the URL in your UniFi controller UI). Separated by comma (,) if passing multiple sites")
|
||||
parser.add_argument('port', action="store", help="Usually 8443")
|
||||
parser.add_argument('verifyssl', action="store", help="verify SSL certificate [true|false]")
|
||||
parser.add_argument('version', action="store", help="The base version of the controller API [v4|v5|unifiOS|UDMP-unifiOS]")
|
||||
parser.add_argument('fullimport', action="store", help="Defines if a full import or only online devices hould be imported [disabled|once|always]")
|
||||
|
||||
values = parser.parse_args()
|
||||
|
||||
|
||||
|
||||
|
||||
# parse output
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
|
||||
mylog('verbose', [f'[UNFIMP] Check if all login information is available: {values}'])
|
||||
UNIFI_USERNAME = get_setting_value("UNFIMP_username")
|
||||
UNIFI_PASSWORD = get_setting_value("UNFIMP_password")
|
||||
UNIFI_HOST = get_setting_value("UNFIMP_host")
|
||||
UNIFI_SITES = get_setting_value("UNFIMP_sites")
|
||||
PORT = get_setting_value("UNFIMP_port")
|
||||
VERIFYSSL = get_setting_value("UNFIMP_verifyssl")
|
||||
VERSION = get_setting_value("UNFIMP_version")
|
||||
FULL_IMPORT = get_setting_value("UNFIMP_fullimport")
|
||||
|
||||
if values.username and values.password and values.host and values.sites:
|
||||
|
||||
UNIFI_USERNAME = values.username.split('=')[1]
|
||||
UNIFI_PASSWORD = values.password.split('=')[1]
|
||||
UNIFI_HOST = values.host.split('=')[1]
|
||||
UNIFI_SITES = values.sites.split('=')[1]
|
||||
PORT = values.port.split('=')[1]
|
||||
VERIFYSSL = values.verifyssl.split('=')[1]
|
||||
VERSION = values.version.split('=')[1]
|
||||
FULL_IMPORT = values.fullimport.split('=')[1]
|
||||
|
||||
plugin_objects = get_entries(plugin_objects)
|
||||
plugin_objects = get_entries(plugin_objects)
|
||||
|
||||
plugin_objects.write_result_file()
|
||||
|
||||
|
||||
mylog('verbose', [f'[UNFIMP] Scan finished, found {len(plugin_objects)} devices'])
|
||||
mylog('verbose', [f'[{pluginName}] Scan finished, found {len(plugin_objects)} devices'])
|
||||
|
||||
# .............................................
|
||||
|
||||
@@ -91,152 +76,175 @@ def get_entries(plugin_objects: Plugin_Objects) -> Plugin_Objects:
|
||||
lock_file_value = read_lock_file()
|
||||
perform_full_run = check_full_run_state(FULL_IMPORT, lock_file_value)
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] sites: {UNIFI_SITES}'])
|
||||
|
||||
sites = []
|
||||
|
||||
if ',' in UNIFI_SITES:
|
||||
sites = UNIFI_SITES.split(',')
|
||||
|
||||
else:
|
||||
sites.append(UNIFI_SITES)
|
||||
|
||||
if (VERIFYSSL.upper() == "TRUE"):
|
||||
VERIFYSSL = True
|
||||
else:
|
||||
VERIFYSSL = False
|
||||
|
||||
for site in sites:
|
||||
|
||||
# mylog('verbose', [f'[{pluginName}] sites: {sites}'])
|
||||
|
||||
for site in UNIFI_SITES:
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] site: {site}'])
|
||||
|
||||
c = Controller(UNIFI_HOST, UNIFI_USERNAME, UNIFI_PASSWORD, port=PORT, version=VERSION, ssl_verify=VERIFYSSL, site_id=site)
|
||||
|
||||
mylog('verbose', [f'[UNFIMP] Identify Unifi Devices'])
|
||||
# get all Unifi devices
|
||||
for ap in c.get_aps():
|
||||
|
||||
# mylog('verbose', [f'{json.dumps(ap)}'])
|
||||
|
||||
deviceType = ''
|
||||
if (ap['type'] == 'udm'):
|
||||
deviceType = 'Router'
|
||||
elif (ap['type'] == 'usg'):
|
||||
deviceType = 'Router'
|
||||
elif (ap['type'] == 'usw'):
|
||||
deviceType = 'Switch'
|
||||
elif (ap['type'] == 'uap'):
|
||||
deviceType = 'AP'
|
||||
|
||||
name = get_unifi_val(ap, 'name')
|
||||
hostName = get_unifi_val(ap, 'hostname')
|
||||
|
||||
name = set_name(name, hostName)
|
||||
|
||||
ipTmp = get_unifi_val(ap, 'ip')
|
||||
|
||||
# if IP not found use a default value
|
||||
if ipTmp == "null":
|
||||
ipTmp = '0.0.0.0'
|
||||
|
||||
plugin_objects.add_object(
|
||||
primaryId=ap['mac'],
|
||||
secondaryId=ipTmp,
|
||||
watched1=name,
|
||||
watched2='Ubiquiti Networks Inc.',
|
||||
watched3=deviceType,
|
||||
watched4=ap['state'],
|
||||
extra=get_unifi_val(ap, 'connection_network_name')
|
||||
)
|
||||
|
||||
|
||||
mylog('verbose', [f'[UNFIMP] Found {len(plugin_objects)} Unifi Devices'])
|
||||
|
||||
|
||||
online_macs = set()
|
||||
processed_macs = []
|
||||
|
||||
# get_clients() returns all clients which are currently online.
|
||||
for cl in c.get_clients():
|
||||
mylog('verbose', [f'[{pluginName}] Get Online Devices'])
|
||||
|
||||
# mylog('verbose', [f'{json.dumps(cl)}'])
|
||||
online_macs.add(cl['mac'])
|
||||
# Collect details for online clients
|
||||
collect_details(
|
||||
device_type={'cl': ''},
|
||||
devices=c.get_clients(),
|
||||
online_macs=online_macs,
|
||||
processed_macs=processed_macs,
|
||||
plugin_objects=plugin_objects,
|
||||
device_label='client',
|
||||
device_vendor="",
|
||||
force_import=True # These are online clients, force import
|
||||
)
|
||||
|
||||
|
||||
mylog('verbose', [f'[UNFIMP] Found {len(plugin_objects)} Online Devices'])
|
||||
mylog('verbose', [f'[{pluginName}] Found {len(plugin_objects)} Online Devices'])
|
||||
|
||||
# get_users() returns all clients known by the controller
|
||||
for user in c.get_users():
|
||||
mylog('verbose', [f'[{pluginName}] Identify Unifi Devices'])
|
||||
|
||||
#mylog('verbose', [f'{json.dumps(user)}'])
|
||||
# Collect details for Unifi devices
|
||||
collect_details(
|
||||
device_type={
|
||||
'udm': 'Router',
|
||||
'usg': 'Router',
|
||||
'usw': 'Switch',
|
||||
'uap': 'AP'
|
||||
},
|
||||
devices=c.get_aps(),
|
||||
online_macs=online_macs,
|
||||
processed_macs=processed_macs,
|
||||
plugin_objects=plugin_objects,
|
||||
device_label='ap',
|
||||
device_vendor="Ubiquiti Networks Inc.",
|
||||
force_import=perform_full_run
|
||||
)
|
||||
|
||||
name = get_unifi_val(user, 'name')
|
||||
hostName = get_unifi_val(user, 'hostname')
|
||||
mylog('verbose', [f'[{pluginName}] Found {len(plugin_objects)} Unifi Devices'])
|
||||
|
||||
name = set_name(name, hostName)
|
||||
# Collect details for users
|
||||
collect_details(
|
||||
device_type={'user': ''},
|
||||
devices=c.get_users(),
|
||||
online_macs=online_macs,
|
||||
processed_macs=processed_macs,
|
||||
plugin_objects=plugin_objects,
|
||||
device_label='user',
|
||||
device_vendor="",
|
||||
force_import=perform_full_run
|
||||
)
|
||||
|
||||
status = 1 if user['mac'] in online_macs else 0
|
||||
mylog('verbose', [f'[{pluginName}] Found {len(plugin_objects)} Users'])
|
||||
|
||||
if status == 1 or perform_full_run is True:
|
||||
|
||||
ipTmp = get_unifi_val(user, 'last_ip')
|
||||
|
||||
if ipTmp == 'null':
|
||||
ipTmp = get_unifi_val(user, 'fixed_ip')
|
||||
|
||||
# if IP not found use a default value
|
||||
if ipTmp == "null":
|
||||
ipTmp = '0.0.0.0'
|
||||
|
||||
plugin_objects.add_object(
|
||||
primaryId=user['mac'],
|
||||
secondaryId=ipTmp,
|
||||
watched1=name,
|
||||
watched2=get_unifi_val(user, 'oui'),
|
||||
watched3='Other',
|
||||
watched4=status,
|
||||
extra=get_unifi_val(user, 'last_connection_network_name')
|
||||
)
|
||||
|
||||
# check if the lockfile needs to be adapted
|
||||
|
||||
mylog('verbose', [f'[UNFIMP] check if Lock file needs to be modified'])
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] check if Lock file needs to be modified'])
|
||||
set_lock_file_value(FULL_IMPORT, lock_file_value)
|
||||
|
||||
|
||||
mylog('verbose', [f'[UNFIMP] Found {len(plugin_objects)} Clients overall'])
|
||||
mylog('verbose', [f'[{pluginName}] Found {len(plugin_objects)} Clients overall'])
|
||||
|
||||
return plugin_objects
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_unifi_val(obj, key):
|
||||
def collect_details(device_type, devices, online_macs, processed_macs, plugin_objects, device_label, device_vendor, force_import):
|
||||
for device in devices:
|
||||
mylog('verbose', [f'{json.dumps(device)}'])
|
||||
|
||||
res = ''
|
||||
# try extracting variables from teh json
|
||||
name = get_name(get_unifi_val(device, 'name'), get_unifi_val(device, 'hostname'))
|
||||
ipTmp = get_ip(get_unifi_val(device, 'lan_ip'), get_unifi_val(device, 'last_ip'), get_unifi_val(device, 'fixed_ip'), get_unifi_val(device, 'ip'))
|
||||
macTmp = device['mac']
|
||||
status = 1 if macTmp in online_macs else device.get('state', 0)
|
||||
deviceType = device_type.get(device.get('type'), '')
|
||||
parentMac = get_parent_mac(get_unifi_val(device, 'uplink_mac'), get_unifi_val(device, 'ap_mac'), get_unifi_val(device, 'sw_mac'))
|
||||
|
||||
# override parent MAC if this is a router
|
||||
if parentMac == 'null' and is_typical_router_ip(ipTmp):
|
||||
parentMac = 'Internet'
|
||||
|
||||
res = obj.get(key, None)
|
||||
|
||||
if res not in ['','None', None]:
|
||||
return res
|
||||
|
||||
mylog('debug', [f'[{pluginName}] Value not found for key "{key}" in obj "{json.dumps(obj)}"'])
|
||||
|
||||
return 'null'
|
||||
# Add object only if not processed
|
||||
if macTmp not in processed_macs and ( status == 1 or force_import is True ):
|
||||
plugin_objects.add_object(
|
||||
primaryId=macTmp,
|
||||
secondaryId=ipTmp,
|
||||
watched1=name,
|
||||
watched2=get_unifi_val(device, 'oui', device_vendor),
|
||||
watched3=deviceType,
|
||||
watched4=status,
|
||||
extra=get_unifi_val(device, 'connection_network_name', ''),
|
||||
foreignKey="",
|
||||
helpVal1=parentMac,
|
||||
helpVal2=get_port(get_unifi_val(device, 'sw_port'), get_unifi_val(device, 'uplink_remote_port')),
|
||||
helpVal3=device_label,
|
||||
helpVal4="",
|
||||
)
|
||||
processed_macs.append(macTmp)
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_unifi_val(obj, key, default='null'):
|
||||
if isinstance(obj, dict):
|
||||
if key in obj and obj[key] not in ['', 'None', None]:
|
||||
return obj[key]
|
||||
for k, v in obj.items():
|
||||
if isinstance(v, dict):
|
||||
result = get_unifi_val(v, key, default)
|
||||
if result not in ['','None', None, 'null']:
|
||||
return result
|
||||
|
||||
mylog('debug', [f'[{pluginName}] Value not found for key "{key}" in obj "{json.dumps(obj)}"'])
|
||||
return default
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def set_name(name: str, hostName: str) -> str:
|
||||
def get_name(*names: str) -> str:
|
||||
for name in names:
|
||||
if name and name != 'null':
|
||||
return rmBadChars(name)
|
||||
return 'null'
|
||||
|
||||
if name != 'null':
|
||||
return name
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_parent_mac(*macs: str) -> str:
|
||||
for mac in macs:
|
||||
if mac and mac != 'null':
|
||||
return mac
|
||||
return 'null'
|
||||
|
||||
elif name == 'null' and hostName != 'null':
|
||||
return hostName
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_port(*ports: str) -> str:
|
||||
for port in ports:
|
||||
if port and port != 'null':
|
||||
return port
|
||||
return 'null'
|
||||
|
||||
else:
|
||||
return 'null'
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_port(*macs: str) -> str:
|
||||
for mac in macs:
|
||||
if mac and mac != 'null':
|
||||
return mac
|
||||
return 'null'
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def get_ip(*ips: str) -> str:
|
||||
for ip in ips:
|
||||
if ip and ip != 'null':
|
||||
return ip
|
||||
return '0:0:0:0'
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
def set_lock_file_value(config_value: str, lock_file_value: bool) -> None:
|
||||
|
||||
mylog('verbose', [f'[UNFIMP] Lock Params: config_value={config_value}, lock_file_value={lock_file_value}'])
|
||||
mylog('verbose', [f'[{pluginName}] Lock Params: config_value={config_value}, lock_file_value={lock_file_value}'])
|
||||
# set lock if 'once' is set and the lock is not set
|
||||
if config_value == 'once' and lock_file_value is False:
|
||||
out = 1
|
||||
@@ -244,10 +252,10 @@ def set_lock_file_value(config_value: str, lock_file_value: bool) -> None:
|
||||
elif config_value != 'once' and lock_file_value is True:
|
||||
out = 0
|
||||
else:
|
||||
mylog('verbose', [f'[UNFIMP] No change on lock file needed'])
|
||||
mylog('verbose', [f'[{pluginName}] No change on lock file needed'])
|
||||
return
|
||||
|
||||
mylog('verbose', [f'[UNFIMP] Setting lock value for "full import" to {out}'])
|
||||
mylog('verbose', [f'[{pluginName}] Setting lock value for "full import" to {out}'])
|
||||
with open(LOCK_FILE, 'w') as lock_file:
|
||||
lock_file.write(str(out))
|
||||
|
||||
@@ -265,10 +273,10 @@ def read_lock_file() -> bool:
|
||||
# -----------------------------------------------------------------------------
|
||||
def check_full_run_state(config_value: str, lock_file_value: bool) -> bool:
|
||||
if config_value == 'always' or (config_value == 'once' and lock_file_value == False):
|
||||
mylog('verbose', [f'[UNFIMP] Full import needs to be done: config_value: {config_value} and lock_file_value: {lock_file_value}'])
|
||||
mylog('verbose', [f'[{pluginName}] Full import needs to be done: config_value: {config_value} and lock_file_value: {lock_file_value}'])
|
||||
return True
|
||||
else:
|
||||
mylog('verbose', [f'[UNFIMP] Full import NOT needed: config_value: {config_value} and lock_file_value: {lock_file_value}'])
|
||||
mylog('verbose', [f'[{pluginName}] Full import NOT needed: config_value: {config_value} and lock_file_value: {lock_file_value}'])
|
||||
return False
|
||||
|
||||
#===============================================================================
|
||||
|
||||
@@ -17,9 +17,14 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
|
||||
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64, handleEmpty
|
||||
from logger import mylog, append_line_to_file
|
||||
from helper import timeNowTZ
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath, fullDbPath
|
||||
from device import query_MAC_vendor
|
||||
import conf
|
||||
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())
|
||||
|
||||
@@ -624,6 +624,16 @@
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementHasInputValue": 1,
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "button",
|
||||
"elementOptions": [
|
||||
@@ -645,15 +655,6 @@
|
||||
{ "getStringKey": "Gen_Remove_Last" }
|
||||
],
|
||||
"transformers": []
|
||||
},
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [
|
||||
{ "multiple": "true" },
|
||||
{ "readonly": "true" },
|
||||
{ "editable": "true" }
|
||||
],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -15,6 +15,12 @@ sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"])
|
||||
from plugin_helper import Plugin_Objects
|
||||
from datetime import datetime
|
||||
from const import logPath
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
import conf
|
||||
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')
|
||||
|
||||
@@ -219,7 +219,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
|
||||
try {
|
||||
const isMetadata = codeName.includes('__metadata');
|
||||
// is this isn't a metadata entry, get corresponding metadata object from the dummy setting
|
||||
// if this isn't a metadata entry, get corresponding metadata object from the dummy setting
|
||||
const setObj = isMetadata ? {} : JSON.parse(getSetting(`${codeName}__metadata`));
|
||||
|
||||
} catch (error) {
|
||||
@@ -459,6 +459,8 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
}
|
||||
|
||||
// INPUT
|
||||
|
||||
console.log(codeName);
|
||||
|
||||
// Parse the setType JSON string into an object
|
||||
let inputHtml = '';
|
||||
@@ -614,8 +616,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
clearCache()
|
||||
}, 1500);
|
||||
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
var settingsArray = [];
|
||||
|
||||
// collect values for each of the different input form controls
|
||||
@@ -628,12 +629,18 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
setType = set["Type"]
|
||||
setCodeName = set["Code_Name"]
|
||||
|
||||
console.log(prefix);
|
||||
|
||||
const setTypeObject = JSON.parse(setType.replace(/'/g, '"'));
|
||||
// console.log(setTypeObject);
|
||||
|
||||
const dataType = setTypeObject.dataType;
|
||||
const lastElementObj = setTypeObject.elements[setTypeObject.elements.length - 1];
|
||||
const { elementType, elementOptions = [], transformers = [] } = lastElementObj;
|
||||
// const lastElementObj = setTypeObject.elements[setTypeObject.elements.length - 1]; //🔽
|
||||
|
||||
// get the element with the input value(s)
|
||||
const elementsWithInputValue = setTypeObject.elements.filter(element => element.elementHasInputValue === 1);
|
||||
|
||||
const { elementType, elementOptions = [], transformers = [] } = elementsWithInputValue;
|
||||
const {
|
||||
inputType,
|
||||
readOnly,
|
||||
@@ -714,13 +721,15 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
success: function(data, textStatus) {
|
||||
|
||||
if(data == "OK")
|
||||
{
|
||||
showMessage (getString("settings_saved"), 5000, "modal_grey");
|
||||
{
|
||||
// showMessage (getString("settings_saved"), 5000, "modal_grey");
|
||||
// Remove navigation prompt "Are you sure you want to leave..."
|
||||
window.onbeforeunload = null;
|
||||
|
||||
// Reloads the current page
|
||||
setTimeout("clearCache()", 5000);
|
||||
// setTimeout("clearCache()", 5000);
|
||||
|
||||
clearCache()
|
||||
} else{
|
||||
// something went wrong
|
||||
// write_notification(data, 'interrupt')
|
||||
@@ -746,7 +755,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
|
||||
<!-- INIT THE PAGE -->
|
||||
<script defer>
|
||||
|
||||
function handleLoadingDialog()
|
||||
function handleLoadingDialog()
|
||||
{
|
||||
|
||||
// check if config file has been updated
|
||||
@@ -779,7 +788,7 @@ function handleLoadingDialog()
|
||||
getData()
|
||||
|
||||
// reload page if outdated information might be displayed
|
||||
if(secondsSincePageLoad() > 3)
|
||||
if(secondsSincePageLoad() > 5)
|
||||
{
|
||||
clearCache()
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ fi
|
||||
apt-get install -y \
|
||||
tini snmp ca-certificates curl libwww-perl arp-scan perl apt-utils cron sudo \
|
||||
nginx-light php php-cgi php-fpm php-sqlite3 php-curl php-openssl sqlite3 dnsutils net-tools \
|
||||
python3 python3-dev iproute2 nmap python3-pip zip systemctl usbutils traceroute nbtscan
|
||||
python3 python3-dev iproute2 nmap python3-pip zip systemctl usbutils traceroute nbtscan build-essential
|
||||
|
||||
# alternate dependencies
|
||||
sudo apt-get install nginx nginx-core mtr php-fpm php8.2-fpm php-cli php8.2 php8.2-sqlite3 -y
|
||||
@@ -30,5 +30,5 @@ source myenv/bin/activate
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3 10
|
||||
|
||||
# install packages thru pip3
|
||||
pip3 install netifaces tplink-omada-client pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython 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
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
server {
|
||||
listen 20211 default_server;
|
||||
root /var/www/html/app;
|
||||
root /var/www/html/netalertx;
|
||||
index index.php;
|
||||
#rewrite /app/(.*) / permanent;
|
||||
add_header X-Forwarded-Prefix "/app" always;
|
||||
proxy_set_header X-Forwarded-Prefix "/app";
|
||||
add_header X-Forwarded-Prefix "/netalertx" always;
|
||||
proxy_set_header X-Forwarded-Prefix "/netalertx";
|
||||
|
||||
location ~* \.php$ {
|
||||
# Set Cache-Control header to prevent caching on the first load
|
||||
|
||||
@@ -385,6 +385,18 @@ class DB():
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Plugins_Objects" ADD "SyncHubNodeName" TEXT
|
||||
""")
|
||||
|
||||
# helper columns HelpVal1-4
|
||||
plug_HelpValues_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Objects') WHERE name='HelpVal1'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if plug_HelpValues_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding HelpVal1-4 to the Plugins_Objects table"])
|
||||
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal1" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal2" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal3" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Objects" ADD COLUMN "HelpVal4" TEXT')
|
||||
|
||||
# Plugin execution results
|
||||
sql_Plugins_Events = """ CREATE TABLE IF NOT EXISTS Plugins_Events(
|
||||
@@ -416,6 +428,18 @@ class DB():
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Plugins_Events" ADD "SyncHubNodeName" TEXT
|
||||
""")
|
||||
|
||||
# helper columns HelpVal1-4
|
||||
plug_HelpValues_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_Events') WHERE name='HelpVal1'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if plug_HelpValues_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding HelpVal1-4 to the Plugins_Events table"])
|
||||
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal1" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal2" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal3" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_Events" ADD COLUMN "HelpVal4" TEXT')
|
||||
|
||||
|
||||
# Plugin execution history
|
||||
@@ -448,6 +472,18 @@ class DB():
|
||||
self.sql.execute("""
|
||||
ALTER TABLE "Plugins_History" ADD "SyncHubNodeName" TEXT
|
||||
""")
|
||||
|
||||
# helper columns HelpVal1-4
|
||||
plug_HelpValues_missing = self.sql.execute ("""
|
||||
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('Plugins_History') WHERE name='HelpVal1'
|
||||
""").fetchone()[0] == 0
|
||||
|
||||
if plug_HelpValues_missing :
|
||||
mylog('verbose', ["[upgradeDB] Adding HelpVal1-4 to the Plugins_History table"])
|
||||
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal1" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal2" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal3" TEXT')
|
||||
self.sql.execute('ALTER TABLE "Plugins_History" ADD COLUMN "HelpVal4" TEXT')
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
274
server/device.py
274
server/device.py
@@ -171,40 +171,48 @@ def create_new_devices (db):
|
||||
mylog('debug','[New Devices] 2 Create devices')
|
||||
|
||||
# default New Device values preparation
|
||||
newDevColumns = """dev_AlertEvents,
|
||||
dev_AlertDeviceDown,
|
||||
dev_PresentLastScan,
|
||||
dev_Archived,
|
||||
dev_NewDevice,
|
||||
dev_SkipRepeated,
|
||||
dev_ScanCycle,
|
||||
dev_Owner,
|
||||
dev_Favorite,
|
||||
dev_Group,
|
||||
dev_Comments,
|
||||
dev_LogEvents,
|
||||
dev_Location,
|
||||
dev_Icon"""
|
||||
newDevColumns = """dev_AlertEvents,
|
||||
dev_AlertDeviceDown,
|
||||
dev_PresentLastScan,
|
||||
dev_Archived,
|
||||
dev_NewDevice,
|
||||
dev_SkipRepeated,
|
||||
dev_ScanCycle,
|
||||
dev_Owner,
|
||||
dev_Favorite,
|
||||
dev_Group,
|
||||
dev_Comments,
|
||||
dev_LogEvents,
|
||||
dev_Location"""
|
||||
|
||||
newDevDefaults = f"""{get_setting_value('NEWDEV_dev_AlertEvents')},
|
||||
{get_setting_value('NEWDEV_dev_AlertDeviceDown')},
|
||||
{get_setting_value('NEWDEV_dev_PresentLastScan')},
|
||||
{get_setting_value('NEWDEV_dev_Archived')},
|
||||
{get_setting_value('NEWDEV_dev_NewDevice')},
|
||||
{get_setting_value('NEWDEV_dev_SkipRepeated')},
|
||||
{get_setting_value('NEWDEV_dev_ScanCycle')},
|
||||
'{get_setting_value('NEWDEV_dev_Owner')}',
|
||||
{get_setting_value('NEWDEV_dev_Favorite')},
|
||||
'{get_setting_value('NEWDEV_dev_Group')}',
|
||||
'{get_setting_value('NEWDEV_dev_Comments')}',
|
||||
{get_setting_value('NEWDEV_dev_LogEvents')},
|
||||
'{get_setting_value('NEWDEV_dev_Location')}',
|
||||
'{get_setting_value('NEWDEV_dev_Icon')}'
|
||||
"""
|
||||
newDevDefaults = f"""{get_setting_value('NEWDEV_dev_AlertEvents')},
|
||||
{get_setting_value('NEWDEV_dev_AlertDeviceDown')},
|
||||
{get_setting_value('NEWDEV_dev_PresentLastScan')},
|
||||
{get_setting_value('NEWDEV_dev_Archived')},
|
||||
{get_setting_value('NEWDEV_dev_NewDevice')},
|
||||
{get_setting_value('NEWDEV_dev_SkipRepeated')},
|
||||
{get_setting_value('NEWDEV_dev_ScanCycle')},
|
||||
'{get_setting_value('NEWDEV_dev_Owner')}',
|
||||
{get_setting_value('NEWDEV_dev_Favorite')},
|
||||
'{get_setting_value('NEWDEV_dev_Group')}',
|
||||
'{get_setting_value('NEWDEV_dev_Comments')}',
|
||||
{get_setting_value('NEWDEV_dev_LogEvents')},
|
||||
'{get_setting_value('NEWDEV_dev_Location')}'"""
|
||||
|
||||
# Bulk-inserting devices from the CurrentScan table as new devices in the table Devices ...
|
||||
# ... with new device defaults and ignoring specidfied IPs and MACs)
|
||||
sqlQuery = f"""INSERT OR IGNORE INTO Devices
|
||||
# Fetch data from CurrentScan
|
||||
current_scan_data = sql.execute("SELECT cur_MAC, cur_Name, cur_Vendor, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type FROM CurrentScan").fetchall()
|
||||
|
||||
for row in current_scan_data:
|
||||
cur_MAC, cur_Name, cur_Vendor, cur_IP, cur_SyncHubNodeName, cur_NetworkNodeMAC, cur_PORT, cur_NetworkSite, cur_SSID, cur_Type = row
|
||||
|
||||
# Handle NoneType
|
||||
cur_Name = cur_Name.strip() if cur_Name else '(unknown)'
|
||||
cur_Type = cur_Type.strip() if cur_Type else get_setting_value("NEWDEV_dev_DeviceType")
|
||||
cur_NetworkNodeMAC = cur_NetworkNodeMAC.strip() if cur_NetworkNodeMAC else ''
|
||||
cur_NetworkNodeMAC = cur_NetworkNodeMAC if cur_NetworkNodeMAC and cur_MAC != "Internet" else (get_setting_value("NEWDEV_dev_Network_Node_MAC_ADDR") if cur_MAC != "Internet" else "null")
|
||||
|
||||
# Preparing the individual insert statement
|
||||
sqlQuery = f"""INSERT OR IGNORE INTO Devices
|
||||
(
|
||||
dev_MAC,
|
||||
dev_name,
|
||||
@@ -221,44 +229,28 @@ def create_new_devices (db):
|
||||
dev_DeviceType,
|
||||
{newDevColumns}
|
||||
)
|
||||
SELECT
|
||||
cur_MAC,
|
||||
CASE
|
||||
WHEN LENGTH(TRIM(cur_Name)) > 0 THEN cur_Name ELSE '(unknown)'
|
||||
END,
|
||||
cur_Vendor,
|
||||
cur_IP,
|
||||
VALUES
|
||||
(
|
||||
'{cur_MAC}',
|
||||
'{cur_Name}',
|
||||
'{cur_Vendor}',
|
||||
'{cur_IP}',
|
||||
?,
|
||||
?,
|
||||
cur_SyncHubNodeName,
|
||||
{sql_generateGuid},
|
||||
CASE
|
||||
WHEN LENGTH(TRIM(cur_NetworkNodeMAC)) > 0
|
||||
AND cur_MAC != 'Internet'
|
||||
THEN cur_NetworkNodeMAC
|
||||
ELSE
|
||||
CASE
|
||||
WHEN cur_MAC = 'Internet'
|
||||
THEN 'null'
|
||||
ELSE '{get_setting_value('NEWDEV_dev_Network_Node_MAC_ADDR')}'
|
||||
END
|
||||
END,
|
||||
cur_PORT,
|
||||
cur_NetworkSite,
|
||||
cur_SSID,
|
||||
CASE
|
||||
WHEN LENGTH(TRIM(cur_Type)) > 0 THEN cur_Type ELSE '{get_setting_value('NEWDEV_dev_DeviceType')}'
|
||||
END,
|
||||
'{cur_SyncHubNodeName}',
|
||||
{sql_generateGuid},
|
||||
'{cur_NetworkNodeMAC}',
|
||||
'{cur_PORT}',
|
||||
'{cur_NetworkSite}',
|
||||
'{cur_SSID}',
|
||||
'{cur_Type}',
|
||||
{newDevDefaults}
|
||||
FROM CurrentScan
|
||||
WHERE 1=1
|
||||
{list_to_where('OR', 'cur_MAC', 'NOT LIKE', get_setting_value('NEWDEV_ignored_MACs'))}
|
||||
{list_to_where('OR', 'cur_IP', 'NOT LIKE', get_setting_value('NEWDEV_ignored_IPs'))}
|
||||
"""
|
||||
)"""
|
||||
|
||||
mylog('debug',f'[New Devices] Create devices SQL: {sqlQuery}')
|
||||
mylog('trace', f'[New Devices] Create device SQL: {sqlQuery}')
|
||||
|
||||
sql.execute(sqlQuery, (startTime, startTime))
|
||||
|
||||
sql.execute (sqlQuery, (startTime, startTime) )
|
||||
|
||||
mylog('debug','[New Devices] New Devices end')
|
||||
db.commitDB()
|
||||
@@ -410,6 +402,7 @@ def update_devices_data_from_scan (db):
|
||||
AND cur_Name <> ''
|
||||
) """)
|
||||
|
||||
# Update VENDORS
|
||||
recordsToUpdate = []
|
||||
query = """SELECT * FROM Devices
|
||||
WHERE dev_Vendor = '(unknown)' OR dev_Vendor =''
|
||||
@@ -420,8 +413,40 @@ def update_devices_data_from_scan (db):
|
||||
if vendor != -1 and vendor != -2 :
|
||||
recordsToUpdate.append ([vendor, device['dev_MAC']])
|
||||
|
||||
sql.executemany ("UPDATE Devices SET dev_Vendor = ? WHERE dev_MAC = ? ",
|
||||
recordsToUpdate )
|
||||
if len(recordsToUpdate) > 0:
|
||||
sql.executemany ("UPDATE Devices SET dev_Vendor = ? WHERE dev_MAC = ? ", recordsToUpdate )
|
||||
|
||||
# Guess ICONS
|
||||
recordsToUpdate = []
|
||||
query = """SELECT * FROM Devices
|
||||
WHERE dev_Icon in ('', 'null')
|
||||
OR dev_Icon IS NULL"""
|
||||
default_icon = get_setting_value('NEWDEV_dev_Icon')
|
||||
|
||||
for device in sql.execute (query) :
|
||||
# Conditional logic for dev_Icon guessing
|
||||
dev_Icon = guess_icon(device['dev_Vendor'], device['dev_MAC'], device['dev_LastIP'], device['dev_Name'], default_icon)
|
||||
|
||||
recordsToUpdate.append ([dev_Icon, device['dev_MAC']])
|
||||
|
||||
if len(recordsToUpdate) > 0:
|
||||
sql.executemany ("UPDATE Devices SET dev_Icon = ? WHERE dev_MAC = ? ", recordsToUpdate )
|
||||
|
||||
# Guess Type
|
||||
recordsToUpdate = []
|
||||
query = """SELECT * FROM Devices
|
||||
WHERE dev_DeviceType in ('', 'null')
|
||||
OR dev_DeviceType IS NULL"""
|
||||
default_type = get_setting_value('NEWDEV_dev_DeviceType')
|
||||
|
||||
for device in sql.execute (query) :
|
||||
# Conditional logic for dev_Icon guessing
|
||||
dev_DeviceType = guess_type(device['dev_Vendor'], device['dev_MAC'], device['dev_LastIP'], device['dev_Name'], default_type)
|
||||
|
||||
recordsToUpdate.append ([dev_DeviceType, device['dev_MAC']])
|
||||
|
||||
if len(recordsToUpdate) > 0:
|
||||
sql.executemany ("UPDATE Devices SET dev_DeviceType = ? WHERE dev_MAC = ? ", recordsToUpdate )
|
||||
|
||||
|
||||
mylog('debug','[Update Devices] Update devices end')
|
||||
@@ -582,3 +607,118 @@ def query_MAC_vendor (pMAC):
|
||||
mylog('none', [f"[Vendor Check] ⚠ ERROR: Vendors file {vendorsPath} not found."])
|
||||
return -1
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# Icons
|
||||
#===============================================================================
|
||||
#-------------------------------------------------------------------------------
|
||||
# Base64 encoded HTML string for FontAwesome icons
|
||||
icons = {
|
||||
"globe": "PGkgY2xhc3M9ImZhcyBmYS1nbG9iZSI+PC9pPg==", # globe icon
|
||||
"phone": "PGkgY2xhc3M9ImZhcyBmYS1tb2JpbGUtYWx0Ij48L2k+",
|
||||
"laptop": "PGkgY2xhc3M9ImZhIGZhLWxhcHRvcCI+PC9pPg==",
|
||||
"printer": "PGkgY2xhc3M9ImZhIGZhLXByaW50ZXIiPjwvaT4=",
|
||||
"router": "PGkgY2xhc3M9ImZhcyBmYS1yYW5kb20iPjwvaT4=",
|
||||
"tv": "PGkgY2xhc3M9ImZhIGZhLXR2Ij48L2k+",
|
||||
"desktop": "PGkgY2xhc3M9ImZhIGZhLWRlc2t0b3AiPjwvaT4=",
|
||||
"tablet": "PGkgY2xhc3M9ImZhIGZhLXRhYmxldCI+PC9pPg==",
|
||||
"watch": "PGkgY2xhc3M9ImZhIGZhLXdhbmNoIj48L2k+",
|
||||
"camera": "PGkgY2xhc3M9ImZhIGZhLWNhbWVyYSI+PC9pPg==",
|
||||
"home": "PGkgY2xhc3M9ImZhIGZhLWhvbWUiPjwvaT4=",
|
||||
"apple": "PGkgY2xhc3M9ImZhYiBmYS1hcHBsZSI+PC9pPg==",
|
||||
"ethernet": "PGkgY2xhc3M9ImZhcyBmYS1ldGhlcm5ldCI+PC9pPg==",
|
||||
"google": "PGkgY2xhc3M9ImZhYiBmYS1nb29nbGUiPjwvaT4=",
|
||||
"raspberry": "PGkgY2xhc3M9ImZhYiBmYS1yYXNwYmVycnktcGkiPjwvaT4=",
|
||||
"microchip": "PGkgY2xhc3M9ImZhcyBmYS1taWNyb2NoaXAiPjwvaT4="
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Guess device icon
|
||||
def guess_icon(vendor, mac, ip, name, default):
|
||||
result = default
|
||||
mac = mac.upper()
|
||||
vendor = vendor.lower()
|
||||
name = name.lower()
|
||||
|
||||
# Guess icon based on vendor
|
||||
if any(brand in vendor for brand in {"samsung", "motorola"}):
|
||||
result = icons.get("phone")
|
||||
elif "dell" in vendor:
|
||||
result = icons.get("laptop")
|
||||
elif "hp" in vendor:
|
||||
result = icons.get("printer")
|
||||
elif "cisco" in vendor:
|
||||
result = icons.get("router")
|
||||
elif "lg" in vendor:
|
||||
result = icons.get("tv")
|
||||
elif "raspberry" in vendor:
|
||||
result = icons.get("raspberry")
|
||||
elif "apple" in vendor:
|
||||
result = icons.get("apple")
|
||||
elif "google" in vendor:
|
||||
result = icons.get("google")
|
||||
elif "ubiquiti" in vendor:
|
||||
result = icons.get("router")
|
||||
elif any(brand in vendor for brand in {"espressif"}):
|
||||
result = icons.get("microchip")
|
||||
|
||||
# Guess icon based on MAC address patterns
|
||||
elif mac == "INTERNET": # Apple
|
||||
result = icons.get("globe")
|
||||
elif mac.startswith("00:1A:79"): # Apple
|
||||
result = icons.get("apple")
|
||||
elif mac.startswith("B0:BE:83"): # Apple
|
||||
result = icons.get("apple")
|
||||
elif mac.startswith("00:1B:63"): # Sony
|
||||
result = icons.get("tablet")
|
||||
elif mac.startswith("74:AC:B9"): # Unifi
|
||||
result = icons.get("ethernet")
|
||||
|
||||
|
||||
# Guess icon based on name
|
||||
elif 'google' in name:
|
||||
result = icons.get("google")
|
||||
elif 'desktop' in name:
|
||||
result = icons.get("desktop")
|
||||
|
||||
# Guess icon based on IP address ranges
|
||||
elif ip.startswith("192.168.1."):
|
||||
result = icons.get("laptop")
|
||||
|
||||
|
||||
return result
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Guess device type
|
||||
def guess_type(vendor, mac, ip, name, default):
|
||||
result = default
|
||||
mac = mac.upper()
|
||||
vendor = vendor.lower()
|
||||
name = name.lower()
|
||||
|
||||
# Guess icon based on vendor
|
||||
if any(brand in vendor for brand in {"samsung", "motorola"}):
|
||||
result = "Phone"
|
||||
elif "cisco" in vendor:
|
||||
result = "Router"
|
||||
elif "lg" in vendor:
|
||||
result = "TV"
|
||||
elif "google" in vendor:
|
||||
result = "Phone"
|
||||
elif "ubiquiti" in vendor:
|
||||
result = "Router"
|
||||
|
||||
# Guess type based on MAC address patterns
|
||||
elif mac == "INTERNET":
|
||||
result = "Internet"
|
||||
|
||||
# Guess type based on name
|
||||
elif 'google' in name:
|
||||
result = "Phone"
|
||||
|
||||
# Guess type based on IP address ranges
|
||||
elif ip == ("192.168.1.1"):
|
||||
result = "Router"
|
||||
|
||||
return result
|
||||
|
||||
@@ -352,11 +352,16 @@ def setting_value_to_python_type(set_type, set_value):
|
||||
mylog('none', [f'[HELPER] No elements provided in set_type: {set_type} '])
|
||||
return value
|
||||
|
||||
# Use the last element in the list
|
||||
last_element = elements[len(elements)-1]
|
||||
elementType = last_element.get('elementType', '')
|
||||
elementOptions = last_element.get('elementOptions', [])
|
||||
transformers = last_element.get('transformers', [])
|
||||
# Find the first element where elementHasInputValue is 1
|
||||
element_with_input_value = next((elem for elem in elements if elem.get("elementHasInputValue") == 1), None)
|
||||
|
||||
# If no such element is found, use the last element
|
||||
if element_with_input_value is None:
|
||||
element_with_input_value = elements[-1]
|
||||
|
||||
elementType = element_with_input_value.get('elementType', '')
|
||||
elementOptions = element_with_input_value.get('elementOptions', [])
|
||||
transformers = element_with_input_value.get('transformers', [])
|
||||
|
||||
# Convert value based on dataType and elementType
|
||||
if dataType == 'string' and elementType in ['input', 'select']:
|
||||
|
||||
@@ -132,7 +132,7 @@ def importConfigs (db, all_plugins):
|
||||
# ccd(key, default, config_dir, name, inputtype, options, group, events=[], desc = "", regex = "", setJsonMetadata = {}, overrideTemplate = {})
|
||||
|
||||
conf.LOADED_PLUGINS = ccd('LOADED_PLUGINS', [] , c_d, 'Loaded plugins', '{"dataType":"array", "elements": [{"elementType" : "select", "elementOptions" : [{"multiple":"true"}] ,"transformers": []}]}', '[]', 'General')
|
||||
conf.SCAN_SUBNETS = ccd('SCAN_SUBNETS', ['192.168.1.0/24 --interface=eth1', '192.168.1.0/24 --interface=eth0'] , c_d, 'Subnets to scan', '{"dataType": "array","elements": [ {"elementType": "input","elementOptions": [{ "placeholder": "192.168.1.0/24 --interface=eth1" },{ "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": [] }]}', '[]', 'General')
|
||||
conf.SCAN_SUBNETS = ccd('SCAN_SUBNETS', ['192.168.1.0/24 --interface=eth1', '192.168.1.0/24 --interface=eth0'] , c_d, 'Subnets to scan', '{"dataType": "array","elements": [{"elementType": "input","elementOptions": [{"placeholder": "192.168.1.0/24 --interface=eth1"},{"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.LOG_LEVEL = ccd('LOG_LEVEL', 'verbose' , c_d, 'Log verboseness', '{"dataType":"string", "elements": [{"elementType" : "select", "elementOptions" : [] ,"transformers": []}]}', "['none', 'minimal', 'verbose', 'debug', 'trace']", 'General')
|
||||
conf.TIMEZONE = ccd('TIMEZONE', 'Europe/Berlin' , c_d, 'Time zone', '{"dataType":"string", "elements": [{"elementType" : "input", "elementOptions" : [] ,"transformers": []}]}', '[]', 'General')
|
||||
conf.PLUGINS_KEEP_HIST = ccd('PLUGINS_KEEP_HIST', 250 , c_d, 'Keep history entries', '{"dataType":"integer", "elements": [{"elementType" : "input", "elementOptions" : [{"type": "number"}] ,"transformers": []}]}', '[]', 'General')
|
||||
@@ -140,12 +140,12 @@ 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.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.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": "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": [] }]}', '[]', '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')
|
||||
|
||||
# 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_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', ['PGkgY2xhc3M9ImZhIGZhLWNvbXB1dGVyIj48L2k+', 'PGkgY2xhc3M9ImZhIGZhLWV0aGVybmV0Ij48L2k+', 'PGkgY2xhc3M9ImZhIGZhLWdhbWVwYWQiPjwvaT4', 'PGkgY2xhc3M9ImZhIGZhLWdsb2JlIj48L2k+', 'PGkgY2xhc3M9ImZhIGZhLWxhcHRvcCI+PC9pPg==', 'PGkgY2xhc3M9ImZhIGZhLWxpZ2h0YnVsYiI+PC9pPg==', 'PGkgY2xhc3M9ImZhIGZhLXNoaWVsZCI+PC9pPg==', 'PGkgY2xhc3M9ImZhIGZhLXdpZmkiPjwvaT4'] , 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_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')
|
||||
|
||||
231
server/plugin.py
231
server/plugin.py
@@ -248,32 +248,51 @@ def execute_plugin(db, all_plugins, plugin, pluginsState = plugins_state() ):
|
||||
|
||||
for line in newLines:
|
||||
columns = line.split("|")
|
||||
# There have to be always 9 columns
|
||||
if len(columns) == 9:
|
||||
# Create a tuple containing values to be inserted into the database.
|
||||
# Each value corresponds to a column in the table in the order of the columns.
|
||||
# must match the Plugins_Objects and Plugins_Events database tables and can be used as input for the plugin_object_class.
|
||||
sqlParams.append(
|
||||
(
|
||||
0, # "Index" placeholder
|
||||
plugin["unique_prefix"], # "Plugin" column value from the plugin dictionary
|
||||
columns[0], # "Object_PrimaryID" value from columns list
|
||||
columns[1], # "Object_SecondaryID" value from columns list
|
||||
'null', # Placeholder for "DateTimeCreated" column
|
||||
columns[2], # "DateTimeChanged" value from columns list
|
||||
columns[3], # "Watched_Value1" value from columns list
|
||||
columns[4], # "Watched_Value2" value from columns list
|
||||
columns[5], # "Watched_Value3" value from columns list
|
||||
columns[6], # "Watched_Value4" value from columns list
|
||||
'not-processed', # "Status" column (placeholder)
|
||||
columns[7], # "Extra" value from columns list
|
||||
'null', # Placeholder for "UserData" column
|
||||
columns[8], # "ForeignKey" value from columns list
|
||||
tmp_SyncHubNodeName # Sync Hub Node name
|
||||
)
|
||||
)
|
||||
# There have to be 9 or 13 columns
|
||||
# Common part of the SQL parameters
|
||||
base_params = [
|
||||
0, # "Index" placeholder
|
||||
plugin["unique_prefix"], # "Plugin" column value from the plugin dictionary
|
||||
columns[0], # "Object_PrimaryID" value from columns list
|
||||
columns[1], # "Object_SecondaryID" value from columns list
|
||||
'null', # Placeholder for "DateTimeCreated" column
|
||||
columns[2], # "DateTimeChanged" value from columns list
|
||||
columns[3], # "Watched_Value1" value from columns list
|
||||
columns[4], # "Watched_Value2" value from columns list
|
||||
columns[5], # "Watched_Value3" value from columns list
|
||||
columns[6], # "Watched_Value4" value from columns list
|
||||
'not-processed', # "Status" column (placeholder)
|
||||
columns[7], # "Extra" value from columns list
|
||||
'null', # Placeholder for "UserData" column
|
||||
columns[8], # "ForeignKey" value from columns list
|
||||
tmp_SyncHubNodeName # Sync Hub Node name
|
||||
]
|
||||
|
||||
# Extend the common part with the additional values if there are 13 columns
|
||||
if len(columns) == 13:
|
||||
base_params.extend([
|
||||
columns[9], # "HelpVal1" value from columns list
|
||||
columns[10], # "HelpVal2" value from columns list
|
||||
columns[11], # "HelpVal3" value from columns list
|
||||
columns[12] # "HelpVal4" value from columns list
|
||||
])
|
||||
elif len(columns) == 9:
|
||||
# add padding
|
||||
base_params.extend([
|
||||
'null', # "HelpVal1"
|
||||
'null', # "HelpVal2"
|
||||
'null', # "HelpVal3"
|
||||
'null' # "HelpVal4"
|
||||
])
|
||||
else:
|
||||
mylog('none', ['[Plugins] Skipped invalid line in the output: ', line])
|
||||
mylog('none', [f'[Plugins] Wrong number of input values, must be 9 or 13, got {len(columns)} from: {line} '])
|
||||
|
||||
# Create a tuple containing values to be inserted into the database.
|
||||
# Each value corresponds to a column in the table in the order of the columns.
|
||||
# must match the Plugins_Objects and Plugins_Events database tables and can be used as input for the plugin_object_class.
|
||||
|
||||
# Append the final parameters to sqlParams
|
||||
sqlParams.append(tuple(base_params))
|
||||
|
||||
# keep current instance log file, delete all from other nodes
|
||||
if filename != 'last_result.log' and os.path.exists(full_path):
|
||||
@@ -293,30 +312,48 @@ def execute_plugin(db, all_plugins, plugin, pluginsState = plugins_state() ):
|
||||
arr = db.get_sql_array (q)
|
||||
|
||||
for row in arr:
|
||||
# There has to be always 9 columns
|
||||
if len(row) == 9 and (row[0] in ['','null']) == False :
|
||||
# Create a tuple containing values to be inserted into the database.
|
||||
# There has to be always 9 or 13 columns
|
||||
if len(row) in [9, 13] and row[0] not in ['', 'null']:
|
||||
# Create a base tuple containing values to be inserted into the database.
|
||||
# Each value corresponds to a column in the table in the order of the columns.
|
||||
# must match the Plugins_Objects and Plugins_Events database tables and can be used as input for the plugin_object_class
|
||||
sqlParams.append(
|
||||
(
|
||||
0, # "Index" placeholder
|
||||
plugin["unique_prefix"], # "Plugin" plugin dictionary
|
||||
row[0], # "Object_PrimaryID" row
|
||||
handle_empty(row[1]), # "Object_SecondaryID" column after handling empty values
|
||||
'null', # Placeholder "DateTimeCreated" column
|
||||
row[2], # "DateTimeChanged" row
|
||||
row[3], # "Watched_Value1" row
|
||||
row[4], # "Watched_Value2" row
|
||||
handle_empty(row[5]), # "Watched_Value3" column after handling empty values
|
||||
handle_empty(row[6]), # "Watched_Value4" column after handling empty values
|
||||
'not-processed', # "Status" column (placeholder)
|
||||
row[7], # "Extra" row
|
||||
'null', # Placeholder "UserData" column
|
||||
row[8], # "ForeignKey" row
|
||||
'null' # Sync Hub Node name - Only supported with scripts
|
||||
)
|
||||
)
|
||||
# Must match the Plugins_Objects and Plugins_Events database tables and can be used as input for the plugin_object_class.
|
||||
base_params = [
|
||||
0, # "Index" placeholder
|
||||
plugin["unique_prefix"], # "Plugin" plugin dictionary
|
||||
row[0], # "Object_PrimaryID" row
|
||||
handle_empty(row[1]), # "Object_SecondaryID" column after handling empty values
|
||||
'null', # Placeholder "DateTimeCreated" column
|
||||
row[2], # "DateTimeChanged" row
|
||||
row[3], # "Watched_Value1" row
|
||||
row[4], # "Watched_Value2" row
|
||||
handle_empty(row[5]), # "Watched_Value3" column after handling empty values
|
||||
handle_empty(row[6]), # "Watched_Value4" column after handling empty values
|
||||
'not-processed', # "Status" column (placeholder)
|
||||
row[7], # "Extra" row
|
||||
'null', # Placeholder "UserData" column
|
||||
row[8], # "ForeignKey" row
|
||||
'null' # Sync Hub Node name - Only supported with scripts
|
||||
]
|
||||
|
||||
# Extend the base tuple with additional values if there are 13 columns
|
||||
if len(row) == 13:
|
||||
base_params.extend([
|
||||
row[9], # "HelpVal1" row
|
||||
row[10], # "HelpVal2" row
|
||||
row[11], # "HelpVal3" row
|
||||
row[12] # "HelpVal4" row
|
||||
])
|
||||
else:
|
||||
# add padding
|
||||
base_params.extend([
|
||||
'null', # "HelpVal1"
|
||||
'null', # "HelpVal2"
|
||||
'null', # "HelpVal3"
|
||||
'null' # "HelpVal4"
|
||||
])
|
||||
|
||||
# Append the final parameters to sqlParams
|
||||
sqlParams.append(tuple(base_params))
|
||||
else:
|
||||
mylog('none', ['[Plugins] Skipped invalid sql result'])
|
||||
|
||||
@@ -352,28 +389,48 @@ def execute_plugin(db, all_plugins, plugin, pluginsState = plugins_state() ):
|
||||
return pluginsState
|
||||
|
||||
for row in arr:
|
||||
# There has to be always 9 columns
|
||||
if len(row) == 9 and (row[0] in ['','null']) == False :
|
||||
# Create a tuple containing values to be inserted into the database.
|
||||
# There has to be always 9 or 13 columns
|
||||
if len(row) in [9, 13] and row[0] not in ['', 'null']:
|
||||
# Create a base tuple containing values to be inserted into the database.
|
||||
# Each value corresponds to a column in the table in the order of the columns.
|
||||
# must match the Plugins_Objects and Plugins_Events database tables and can be used as input for the plugin_object_class
|
||||
sqlParams.append((
|
||||
0, # "Index" placeholder
|
||||
plugin["unique_prefix"], # "Plugin"
|
||||
row[0], # "Object_PrimaryID"
|
||||
handle_empty(row[1]), # "Object_SecondaryID"
|
||||
'null', # "DateTimeCreated" column (null placeholder)
|
||||
row[2], # "DateTimeChanged"
|
||||
row[3], # "Watched_Value1"
|
||||
row[4], # "Watched_Value2"
|
||||
handle_empty(row[5]), # "Watched_Value3"
|
||||
handle_empty(row[6]), # "Watched_Value4"
|
||||
'not-processed', # "Status" column (placeholder)
|
||||
row[7], # "Extra"
|
||||
'null', # "UserData" column (null placeholder)
|
||||
row[8], # "ForeignKey"
|
||||
'null' # Sync Hub Node name - Only supported with scripts
|
||||
))
|
||||
# Must match the Plugins_Objects and Plugins_Events database tables and can be used as input for the plugin_object_class.
|
||||
base_params = [
|
||||
0, # "Index" placeholder
|
||||
plugin["unique_prefix"], # "Plugin"
|
||||
row[0], # "Object_PrimaryID"
|
||||
handle_empty(row[1]), # "Object_SecondaryID"
|
||||
'null', # "DateTimeCreated" column (null placeholder)
|
||||
row[2], # "DateTimeChanged"
|
||||
row[3], # "Watched_Value1"
|
||||
row[4], # "Watched_Value2"
|
||||
handle_empty(row[5]), # "Watched_Value3"
|
||||
handle_empty(row[6]), # "Watched_Value4"
|
||||
'not-processed', # "Status" column (placeholder)
|
||||
row[7], # "Extra"
|
||||
'null', # "UserData" column (null placeholder)
|
||||
row[8], # "ForeignKey"
|
||||
'null' # Sync Hub Node name - Only supported with scripts
|
||||
]
|
||||
|
||||
# Extend the base tuple with additional values if there are 13 columns
|
||||
if len(row) == 13:
|
||||
base_params.extend([
|
||||
row[9], # "HelpVal1"
|
||||
row[10], # "HelpVal2"
|
||||
row[11], # "HelpVal3"
|
||||
row[12] # "HelpVal4"
|
||||
])
|
||||
else:
|
||||
# add padding
|
||||
base_params.extend([
|
||||
'null', # "HelpVal1"
|
||||
'null', # "HelpVal2"
|
||||
'null', # "HelpVal3"
|
||||
'null' # "HelpVal4"
|
||||
])
|
||||
|
||||
# Append the final parameters to sqlParams
|
||||
sqlParams.append(tuple(base_params))
|
||||
else:
|
||||
mylog('none', ['[Plugins] Skipped invalid sql result'])
|
||||
|
||||
@@ -509,12 +566,13 @@ def process_plugin_events(db, plugin, pluginsState, plugEventsArr):
|
||||
for plugObj in pluginObjects:
|
||||
# keep old createdTime time if the plugObj already was created before
|
||||
createdTime = plugObj.changed if plugObj.status == 'new' else plugObj.created
|
||||
# 14 values without Index
|
||||
# 18 values without Index
|
||||
values = (
|
||||
plugObj.pluginPref, plugObj.primaryId, plugObj.secondaryId, createdTime,
|
||||
plugObj.changed, plugObj.watched1, plugObj.watched2, plugObj.watched3,
|
||||
plugObj.watched4, plugObj.status, plugObj.extra, plugObj.userData,
|
||||
plugObj.foreignKey, plugObj.syncHubNodeName
|
||||
plugObj.foreignKey, plugObj.syncHubNodeName,
|
||||
plugObj.helpVal1, plugObj.helpVal2, plugObj.helpVal3, plugObj.helpVal4
|
||||
)
|
||||
|
||||
if plugObj.status == 'new':
|
||||
@@ -547,8 +605,9 @@ def process_plugin_events(db, plugin, pluginsState, plugEventsArr):
|
||||
INSERT INTO Plugins_Objects
|
||||
("Plugin", "Object_PrimaryID", "Object_SecondaryID", "DateTimeCreated",
|
||||
"DateTimeChanged", "Watched_Value1", "Watched_Value2", "Watched_Value3",
|
||||
"Watched_Value4", "Status", "Extra", "UserData", "ForeignKey", "SyncHubNodeName")
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
"Watched_Value4", "Status", "Extra", "UserData", "ForeignKey", "SyncHubNodeName",
|
||||
"HelpVal1", "HelpVal2", "HelpVal3", "HelpVal4")
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""", objects_to_insert
|
||||
)
|
||||
|
||||
@@ -559,7 +618,7 @@ def process_plugin_events(db, plugin, pluginsState, plugEventsArr):
|
||||
UPDATE Plugins_Objects
|
||||
SET "Plugin" = ?, "Object_PrimaryID" = ?, "Object_SecondaryID" = ?, "DateTimeCreated" = ?,
|
||||
"DateTimeChanged" = ?, "Watched_Value1" = ?, "Watched_Value2" = ?, "Watched_Value3" = ?,
|
||||
"Watched_Value4" = ?, "Status" = ?, "Extra" = ?, "UserData" = ?, "ForeignKey" = ?, "SyncHubNodeName" = ?
|
||||
"Watched_Value4" = ?, "Status" = ?, "Extra" = ?, "UserData" = ?, "ForeignKey" = ?, "SyncHubNodeName" = ?, "HelpVal1" = ?, "HelpVal2" = ?, "HelpVal3" = ?, "HelpVal4" = ?
|
||||
WHERE "Index" = ?
|
||||
""", objects_to_update
|
||||
)
|
||||
@@ -572,8 +631,9 @@ def process_plugin_events(db, plugin, pluginsState, plugEventsArr):
|
||||
INSERT INTO Plugins_Events
|
||||
("Plugin", "Object_PrimaryID", "Object_SecondaryID", "DateTimeCreated",
|
||||
"DateTimeChanged", "Watched_Value1", "Watched_Value2", "Watched_Value3",
|
||||
"Watched_Value4", "Status", "Extra", "UserData", "ForeignKey", "SyncHubNodeName")
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
"Watched_Value4", "Status", "Extra", "UserData", "ForeignKey", "SyncHubNodeName",
|
||||
"HelpVal1", "HelpVal2", "HelpVal3", "HelpVal4")
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""", events_to_insert
|
||||
)
|
||||
|
||||
@@ -585,8 +645,9 @@ def process_plugin_events(db, plugin, pluginsState, plugEventsArr):
|
||||
INSERT INTO Plugins_History
|
||||
("Plugin", "Object_PrimaryID", "Object_SecondaryID", "DateTimeCreated",
|
||||
"DateTimeChanged", "Watched_Value1", "Watched_Value2", "Watched_Value3",
|
||||
"Watched_Value4", "Status", "Extra", "UserData", "ForeignKey", "SyncHubNodeName")
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
"Watched_Value4", "Status", "Extra", "UserData", "ForeignKey", "SyncHubNodeName",
|
||||
"HelpVal1", "HelpVal2", "HelpVal3", "HelpVal4")
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""", history_to_insert
|
||||
)
|
||||
|
||||
@@ -665,6 +726,14 @@ def process_plugin_events(db, plugin, pluginsState, plugEventsArr):
|
||||
tmpList.append(plgEv.status)
|
||||
elif col['column'] == 'SyncHubNodeName':
|
||||
tmpList.append(plgEv.syncHubNodeName)
|
||||
elif col['column'] == 'HelpVal1':
|
||||
tmpList.append(plgEv.helpVal1)
|
||||
elif col['column'] == 'HelpVal2':
|
||||
tmpList.append(plgEv.helpVal2)
|
||||
elif col['column'] == 'HelpVal3':
|
||||
tmpList.append(plgEv.helpVal3)
|
||||
elif col['column'] == 'HelpVal4':
|
||||
tmpList.append(plgEv.helpVal4)
|
||||
|
||||
# Check if there's a default value specified for this column in the JSON.
|
||||
if 'mapped_to_column_data' in col and 'value' in col['mapped_to_column_data']:
|
||||
@@ -714,6 +783,11 @@ class plugin_object_class:
|
||||
self.userData = objDbRow[12]
|
||||
self.foreignKey = objDbRow[13]
|
||||
self.syncHubNodeName = objDbRow[14]
|
||||
self.helpVal1 = objDbRow[15]
|
||||
self.helpVal2 = objDbRow[16]
|
||||
self.helpVal3 = objDbRow[17]
|
||||
self.helpVal4 = objDbRow[18]
|
||||
|
||||
|
||||
# Check if self.status is valid
|
||||
if self.status not in ["exists", "watched-changed", "watched-not-changed", "new", "not-processed", "missing-in-last-scan"]:
|
||||
@@ -727,6 +801,7 @@ class plugin_object_class:
|
||||
|
||||
setObj = get_plugin_setting_obj(plugin, 'WATCH')
|
||||
|
||||
# hash for comapring watched value changes
|
||||
indexNameColumnMapping = [(6, 'Watched_Value1' ), (7, 'Watched_Value2' ), (8, 'Watched_Value3' ), (9, 'Watched_Value4' )]
|
||||
|
||||
if setObj is not None:
|
||||
|
||||
Reference in New Issue
Block a user