chore:Settings DB table refactor

This commit is contained in:
jokob-sk
2024-11-23 09:28:40 +11:00
parent 0e438ffd57
commit f1f40021ee
19 changed files with 201 additions and 193 deletions

View File

@@ -819,7 +819,7 @@ function initializeCombos () {
initializeCombo ( '#dropdownDevices', 'getDevices', 'txtFromDevice', false); initializeCombo ( '#dropdownDevices', 'getDevices', 'txtFromDevice', false);
// Initiate dropdown // Initiate dropdown
// generateSetOptions(settingKey, // Identifier for the setting // generateSetOptions(setKey, // Identifier for the setting
// valuesArray, // Array of values to be pre-selected in the dropdown // 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) // targetLocation, // ID of the HTML element where dropdown should be rendered (will be replaced)
// callbackToGenerateEntries, // Callback function to generate entries based on options // callbackToGenerateEntries, // Callback function to generate entries based on options

View File

@@ -15,8 +15,6 @@
<?php <?php
require 'php/templates/header.php'; require 'php/templates/header.php';
require 'php/components/graph_online_history.php';
// check permissions // check permissions
$dbPath = "../db/app.db"; $dbPath = "../db/app.db";
$confPath = "../config/app.conf"; $confPath = "../config/app.conf";
@@ -56,8 +54,10 @@
<div class="box-body"> <div class="box-body">
<div class="chart"> <div class="chart">
<script src="lib/AdminLTE/bower_components/chart.js/Chart.js?v=<?php include 'php/templates/version.php'; ?>"></script> <script src="lib/AdminLTE/bower_components/chart.js/Chart.js?v=<?php include 'php/templates/version.php'; ?>"></script>
<!-- The online history chart is rendered here --> <!-- presence chart -->
<canvas id="OnlineChart" style="width:100%; height: 150px; margin-bottom: 15px;"></canvas> <?php
require 'php/components/graph_online_history.php';
?>
</div> </div>
</div> </div>
<!-- /.box-body --> <!-- /.box-body -->
@@ -195,36 +195,30 @@ function mapIndx(oldIndex)
// Query total numbers of Devices by status // Query total numbers of Devices by status
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function getDevicesTotals() { function getDevicesTotals() {
// Check cache first
let resultJSON = getCache("getDevicesTotals");
if (resultJSON !== "") { // Fetch data via AJAX
resultJSON = JSON.parse(resultJSON); $.ajax({
processDeviceTotals(resultJSON); url: '/api/table_devices_tiles.json?nocache=' + Date.now(),
} else { type: "GET",
// Fetch data via AJAX dataType: "json",
$.ajax({ success: function(response) {
url: "/api/table_devices_tiles.json", if (response && response.data) {
type: "GET", resultJSON = response.data[0]; // Assuming the structure {"data": [ ... ]}
dataType: "json",
success: function(response) {
if (response && response.data) {
resultJSON = response.data[0]; // Assuming the structure {"data": [ ... ]}
// Save the result to cache // Save the result to cache
setCache("getDevicesTotals", JSON.stringify(resultJSON)); setCache("getDevicesTotals", JSON.stringify(resultJSON));
// Process the fetched data // Process the fetched data
processDeviceTotals(resultJSON); processDeviceTotals(resultJSON);
} else { } else {
console.error("Invalid response format from API"); console.error("Invalid response format from API");
}
},
error: function(xhr, status, error) {
console.error("Failed to fetch devices data:", error);
} }
}); },
} error: function(xhr, status, error) {
console.error("Failed to fetch devices data:", error);
}
});
} }
function processDeviceTotals(devicesData) { function processDeviceTotals(devicesData) {

View File

@@ -124,19 +124,19 @@ function cacheSettings()
settingsData.forEach((set) => { settingsData.forEach((set) => {
resolvedOptions = createArray(set.Options) resolvedOptions = createArray(set.setOptions)
resolvedOptionsOld = resolvedOptions resolvedOptionsOld = resolvedOptions
setPlugObj = {}; setPlugObj = {};
options_params = []; options_params = [];
resolved = "" resolved = ""
// proceed only if first option item contains something to resolve // proceed only if first option item contains something to resolve
if( !set.Code_Name.includes("__metadata") && if( !set.setKey.includes("__metadata") &&
resolvedOptions.length != 0 && resolvedOptions.length != 0 &&
resolvedOptions[0].includes("{value}")) resolvedOptions[0].includes("{value}"))
{ {
// get setting definition from the plugin config if available // get setting definition from the plugin config if available
setPlugObj = getPluginSettingObject(pluginsData, set.Code_Name) setPlugObj = getPluginSettingObject(pluginsData, set.setKey)
// check if options contains parameters and resolve // check if options contains parameters and resolve
if(setPlugObj != {} && setPlugObj["options_params"]) if(setPlugObj != {} && setPlugObj["options_params"])
@@ -161,8 +161,8 @@ function cacheSettings()
} }
} }
setCache(`pia_set_${set.Code_Name}`, set.Value) setCache(`pia_set_${set.setKey}`, set.setValue)
setCache(`pia_set_opt_${set.Code_Name}`, resolvedOptions) setCache(`pia_set_opt_${set.setKey}`, resolvedOptions)
}); });
}).then(() => handleSuccess('cacheSettings', resolve())).catch(() => handleFailure('cacheSettings', reject("cacheSettings already completed"))); // handle AJAX synchronization }).then(() => handleSuccess('cacheSettings', resolve())).catch(() => handleFailure('cacheSettings', reject("cacheSettings already completed"))); // handle AJAX synchronization
}) })
@@ -1167,9 +1167,9 @@ function arraysContainSameValues(arr1, arr2) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Hide elements on the page based on the supplied setting // Hide elements on the page based on the supplied setting
function hideUIelements(settingKey) { function hideUIelements(setKey) {
hiddenSectionsSetting = getSetting(settingKey) hiddenSectionsSetting = getSetting(setKey)
if(hiddenSectionsSetting != "") // handle if settings not yet initialized if(hiddenSectionsSetting != "") // handle if settings not yet initialized
{ {

View File

@@ -215,14 +215,14 @@ function settingsCollectedCorrectly(settingsArray, settingsJSON_DB) {
} }
}); });
const settingsCodeNames = settingsJSON_DB.map((setting) => setting.Code_Name); const settingsCodeNames = settingsJSON_DB.map((setting) => setting.setKey);
const detailedCodeNames = settingsArray.map((item) => item[1]); const detailedCodeNames = settingsArray.map((item) => item[1]);
const missingCodeNamesOnPage = detailedCodeNames.filter( const missingCodeNamesOnPage = detailedCodeNames.filter(
(codeName) => !settingsCodeNames.includes(codeName) (setKey) => !settingsCodeNames.includes(setKey)
); );
const missingCodeNamesInDB = settingsCodeNames.filter( const missingCodeNamesInDB = settingsCodeNames.filter(
(codeName) => !detailedCodeNames.includes(codeName) (setKey) => !detailedCodeNames.includes(setKey)
); );
// check if the number of settings on the page and in the DB are the same // check if the number of settings on the page and in the DB are the same
@@ -453,11 +453,11 @@ function filterRows(inputText) {
} }
var description = $row.find(".setting_description").text().toLowerCase(); var description = $row.find(".setting_description").text().toLowerCase();
var codeName = $row.find(".setting_name code").text().toLowerCase(); var setKey = $row.find(".setting_name code").text().toLowerCase();
if ( if (
description.includes(inputText.toLowerCase()) || description.includes(inputText.toLowerCase()) ||
codeName.includes(inputText.toLowerCase()) setKey.includes(inputText.toLowerCase())
) { ) {
$row.show(); $row.show();
anyVisible = true; // Set the flag to true if at least one row is visible anyVisible = true; // Set the flag to true if at least one row is visible
@@ -554,7 +554,7 @@ function overrideToggle(element) {
// Generate options or set options based on the provided parameters // Generate options or set options based on the provided parameters
function generateOptionsOrSetOptions( function generateOptionsOrSetOptions(
codeName, setKey,
valuesArray, // Array of values to be pre-selected in the dropdown valuesArray, // Array of values to be pre-selected in the dropdown
placeholder, // ID of the HTML element where dropdown should be rendered (will be replaced) placeholder, // ID of the HTML element where dropdown should be rendered (will be replaced)
processDataCallback, // Callback function to generate entries based on options processDataCallback, // Callback function to generate entries based on options
@@ -562,10 +562,10 @@ function generateOptionsOrSetOptions(
transformers = [] // Transformers to be applied to the values transformers = [] // Transformers to be applied to the values
) { ) {
// console.log(codeName); // console.log(setKey);
// NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function // NOTE {value} options to replace with a setting or SQL value are handled in the cacheSettings() function
options = arrayToObject(createArray(getSettingOptions(codeName))) options = arrayToObject(createArray(getSettingOptions(setKey)))
// Call to render lists // Call to render lists
renderList( renderList(
@@ -638,7 +638,7 @@ function reverseTransformers(val, transformers) {
// ------------------------------------------------------------ // ------------------------------------------------------------
// Function to initialize relevant variables based on HTML element // Function to initialize relevant variables based on HTML element
const handleElementOptions = (codeName, elementOptions, transformers, val) => { const handleElementOptions = (setKey, elementOptions, transformers, val) => {
let inputType = "text"; let inputType = "text";
let readOnly = ""; let readOnly = "";
let isMultiSelect = false; let isMultiSelect = false;
@@ -687,7 +687,7 @@ const handleElementOptions = (codeName, elementOptions, transformers, val) => {
} }
if (option.sourceSuffixes) { if (option.sourceSuffixes) {
$.each(option.sourceSuffixes, function (index, suf) { $.each(option.sourceSuffixes, function (index, suf) {
sourceIds.push(codeName + suf); sourceIds.push(setKey + suf);
}); });
} }
if (option.separator) { if (option.separator) {

View File

@@ -923,10 +923,10 @@ var wysihtml5 = {
} }
}; };
function DOMException(codeName) { function DOMException(settingKey) {
this.code = this[codeName]; this.code = this[settingKey];
this.codeName = codeName; this.settingKey = settingKey;
this.message = "DOMException: " + this.codeName; this.message = "DOMException: " + this.settingKey;
} }
DOMException.prototype = { DOMException.prototype = {
@@ -1343,9 +1343,9 @@ var wysihtml5 = {
} }
} }
function assertNode(node, codeName) { function assertNode(node, settingKey) {
if (!node) { if (!node) {
throw new DOMException(codeName); throw new DOMException(settingKey);
} }
} }

File diff suppressed because one or more lines are too long

View File

@@ -80,10 +80,10 @@
excludedColumns = ["NEWDEV_devMac", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devLastNotification", "NEWDEV_devLastIP", "NEWDEV_devStaticIP", "NEWDEV_devScan", "NEWDEV_devPresentLastScan" ] excludedColumns = ["NEWDEV_devMac", "NEWDEV_devFirstConnection", "NEWDEV_devLastConnection", "NEWDEV_devLastNotification", "NEWDEV_devLastIP", "NEWDEV_devStaticIP", "NEWDEV_devScan", "NEWDEV_devPresentLastScan" ]
const relevantColumns = settingsData.filter(set => const relevantColumns = settingsData.filter(set =>
set.Group === "NEWDEV" && set.setGroup === "NEWDEV" &&
set.Code_Name.includes("_dev") && set.setKey.includes("_dev") &&
!excludedColumns.includes(set.Code_Name) && !excludedColumns.includes(set.setKey) &&
!set.Code_Name.includes("__metadata") !set.setKey.includes("__metadata")
); );
const generateSimpleForm = columns => { const generateSimpleForm = columns => {
@@ -100,7 +100,7 @@
// Append form groups to the column // Append form groups to the column
for (let j = i * elementsPerColumn; j < Math.min((i + 1) * elementsPerColumn, columns.length); j++) { for (let j = i * elementsPerColumn; j < Math.min((i + 1) * elementsPerColumn, columns.length); j++) {
const setTypeObject = JSON.parse(columns[j].Type.replace(/'/g, '"')); const setTypeObject = JSON.parse(columns[j].setType.replace(/'/g, '"'));
// get the element with the input value(s) // get the element with the input value(s)
let elements = setTypeObject.elements.filter(element => element.elementHasInputValue === 1); let elements = setTypeObject.elements.filter(element => element.elementHasInputValue === 1);
@@ -137,31 +137,31 @@
// render based on element type // render based on element type
if (elementType === 'select') { if (elementType === 'select') {
targetLocation = columns[j].Code_Name + "_generateSetOptions" targetLocation = columns[j].setKey + "_generateSetOptions"
generateOptionsOrSetOptions(columns[j].Code_Name, [], targetLocation, generateOptions) generateOptionsOrSetOptions(columns[j].setKey, [], targetLocation, generateOptions)
console.log(columns[j].Code_Name) console.log(columns[j].setKey)
// Handle Icons as they need a preview // Handle Icons as they need a preview
if(columns[j].Code_Name == 'NEWDEV_devIcon') if(columns[j].setKey == 'NEWDEV_devIcon')
{ {
input = ` input = `
<span class="input-group-addon iconPreview" my-customid="NEWDEV_devIcon_preview"></span> <span class="input-group-addon iconPreview" my-customid="NEWDEV_devIcon_preview"></span>
<select class="form-control" <select class="form-control"
onChange="updateIconPreview(this)" onChange="updateIconPreview(this)"
my-customparams="NEWDEV_devIcon,NEWDEV_devIcon_preview" my-customparams="NEWDEV_devIcon,NEWDEV_devIcon_preview"
id="${columns[j].Code_Name}" id="${columns[j].setKey}"
data-my-column="${columns[j].Code_Name}" data-my-column="${columns[j].setKey}"
data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}" > data-my-targetColumns="${columns[j].setKey.replace('NEWDEV_','')}" >
<option id="${targetLocation}"></option> <option id="${targetLocation}"></option>
</select>` </select>`
} else{ } else{
input = `<select class="form-control" input = `<select class="form-control"
id="${columns[j].Code_Name}" id="${columns[j].setKey}"
data-my-column="${columns[j].Code_Name}" data-my-column="${columns[j].setKey}"
data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}" > data-my-targetColumns="${columns[j].setKey.replace('NEWDEV_','')}" >
<option id="${targetLocation}"></option> <option id="${targetLocation}"></option>
</select>` </select>`
} }
@@ -174,20 +174,20 @@
input = `<input class="${inputClass}" input = `<input class="${inputClass}"
id="${columns[j].Code_Name}" id="${columns[j].setKey}"
my-customid="${columns[j].Code_Name}" my-customid="${columns[j].setKey}"
data-my-column="${columns[j].Code_Name}" data-my-column="${columns[j].setKey}"
data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}" data-my-targetColumns="${columns[j].setKey.replace('NEWDEV_','')}"
type="${inputType}">` type="${inputType}">`
} }
const inputEntry = `<div class="form-group col-sm-12" > const inputEntry = `<div class="form-group col-sm-12" >
<label class="col-sm-3 control-label">${columns[j].Display_Name}</label> <label class="col-sm-3 control-label">${columns[j].setName}</label>
<div class="col-sm-9"> <div class="col-sm-9">
<div class="input-group red-hover-border"> <div class="input-group red-hover-border">
${input} ${input}
<span class="input-group-addon pointer red-hover-background" onclick="massUpdateField('${columns[j].Code_Name}');" title="${getString('Device_MultiEdit_Tooltip')}"> <span class="input-group-addon pointer red-hover-background" onclick="massUpdateField('${columns[j].setKey}');" title="${getString('Device_MultiEdit_Tooltip')}">
<i class="fa fa-save"></i> <i class="fa fa-save"></i>
</span> </span>
</div> </div>

View File

@@ -40,3 +40,5 @@ $.get('api/table_online_history.json?nocache=' + Date.now(), function(res) {
console.error('Error fetching online history data.'); console.error('Error fetching online history data.');
}); });
</script> </script>
<!-- <canvas id="clientsChart" width="800" height="140" class="extratooltipcanvas no-user-select"></canvas> -->
<canvas id="OnlineChart" style="width:100%; height: 150px; margin-bottom: 15px;"></canvas>

View File

@@ -161,6 +161,11 @@ function checkPermissions($files)
{ {
foreach ($files as $file) foreach ($files as $file)
{ {
// // make sure the file ownership is correct
// chown($file, 'nginx');
// chgrp($file, 'www-data');
// check access to database // check access to database
if(file_exists($file) != 1) if(file_exists($file) != 1)
{ {
@@ -331,7 +336,7 @@ function saveSettings()
foreach ($decodedSettings as $setting) { foreach ($decodedSettings as $setting) {
$settingGroup = $setting[0]; $settingGroup = $setting[0];
$settingKey = $setting[1]; $setKey = $setting[1];
$dataType = $setting[2]; $dataType = $setting[2];
$settingValue = $setting[3]; $settingValue = $setting[3];
@@ -339,7 +344,7 @@ function saveSettings()
// $settingType = json_decode($settingTypeJson, true); // $settingType = json_decode($settingTypeJson, true);
// Sanity check // Sanity check
if($settingKey == "UI_LANG" && $settingValue == "") { if($setKey == "UI_LANG" && $settingValue == "") {
echo "🔴 Error: important settings missing. Refresh the page with 🔃 on the top and try again."; echo "🔴 Error: important settings missing. Refresh the page with 🔃 on the top and try again.";
return; return;
} }
@@ -348,14 +353,14 @@ function saveSettings()
if ($dataType == 'string' ) { if ($dataType == 'string' ) {
$val = encode_single_quotes($settingValue); $val = encode_single_quotes($settingValue);
$txt .= $settingKey . "='" . $val . "'\n"; $txt .= $setKey . "='" . $val . "'\n";
} elseif ($dataType == 'integer') { } elseif ($dataType == 'integer') {
$txt .= $settingKey . "=" . $settingValue . "\n"; $txt .= $setKey . "=" . $settingValue . "\n";
} elseif ($dataType == 'json') { } elseif ($dataType == 'json') {
$txt .= $settingKey . "=" . $settingValue . "\n"; $txt .= $setKey . "=" . $settingValue . "\n";
} elseif ($dataType == 'boolean') { } elseif ($dataType == 'boolean') {
$val = ($settingValue === true || $settingValue === 1 || strtolower($settingValue) === 'true') ? "True" : "False"; $val = ($settingValue === true || $settingValue === 1 || strtolower($settingValue) === 'true') ? "True" : "False";
$txt .= $settingKey . "=" . $val . "\n"; $txt .= $setKey . "=" . $val . "\n";
} elseif ($dataType == 'array' ) { } elseif ($dataType == 'array' ) {
$temp = ''; $temp = '';
@@ -373,18 +378,16 @@ function saveSettings()
} }
$temp = '['.$temp.']'; // wrap brackets $temp = '['.$temp.']'; // wrap brackets
$txt .= $settingKey . "=" . $temp . "\n"; $txt .= $setKey . "=" . $temp . "\n";
} else { } else {
$txt .= $settingKey . "='⭕Not handled⭕'\n"; $txt .= $setKey . "='⭕Not handled⭕'\n";
} }
} }
} }
} }
$txt = $txt."\n\n"; $txt = $txt."\n\n";
$txt = $txt."#-------------------IMPORTANT INFO-------------------#\n"; $txt = $txt."#-------------------IMPORTANT INFO-------------------#\n";
$txt = $txt."# This file is ingested by a python script, so if #\n"; $txt = $txt."# This file is ingested by a python script, so if #\n";
@@ -395,13 +398,15 @@ function saveSettings()
// Create a temporary file // Create a temporary file
$tempConfPath = $fullConfPath . ".tmp"; $tempConfPath = $fullConfPath . ".tmp";
// Write your changes to the temporary file // Backup the original file
$tempConfig = fopen($tempConfPath, "w") or die("Unable to open file!"); if (file_exists($fullConfPath)) {
fwrite($tempConfig, $txt); copy($fullConfPath, $fullConfPath . ".bak");
fclose($tempConfig); }
// Replace the original file with the temporary file // Open the file for writing without changing permissions
rename($tempConfPath, $fullConfPath); $file = fopen($fullConfPath, "w") or die("Unable to open file!");
fwrite($file, $txt);
fclose($file);
// displayMessage(lang('settings_saved'), // displayMessage(lang('settings_saved'),
// FALSE, TRUE, TRUE, TRUE); // FALSE, TRUE, TRUE, TRUE);
@@ -411,9 +416,9 @@ function saveSettings()
} }
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
function getString ($codeName, $default) { function getString ($setKey, $default) {
$result = lang($codeName); $result = lang($setKey);
if ($result ) if ($result )
{ {
@@ -423,7 +428,7 @@ function getString ($codeName, $default) {
return $default; return $default;
} }
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
function getSettingValue($codeName) { function getSettingValue($setKey) {
// Define the JSON endpoint URL // Define the JSON endpoint URL
$url = dirname(__FILE__).'/../../../front/api/table_settings.json'; $url = dirname(__FILE__).'/../../../front/api/table_settings.json';
@@ -443,16 +448,16 @@ function getSettingValue($codeName) {
return 'Could not decode json data'; return 'Could not decode json data';
} }
// Search for the setting by Code_Name // Search for the setting by setKey
foreach ($data['data'] as $setting) { foreach ($data['data'] as $setting) {
if ($setting['Code_Name'] === $codeName) { if ($setting['setKey'] === $setKey) {
return $setting['Value']; return $setting['setValue'];
// echo $setting['Value']; // echo $setting['setValue'];
} }
} }
// Return false if the setting was not found // Return false if the setting was not found
return 'Could not find setting '.$codeName; return 'Could not find setting '.$setKey;
} }
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------

View File

@@ -10,7 +10,7 @@ $allLanguages = ["en_us", "es_es", "de_de", "fr_fr", "it_it", "ru_ru", "nb_no",
global $db; global $db;
$result = $db->querySingle("SELECT Value FROM Settings WHERE Code_Name = 'UI_LANG'"); $result = $db->querySingle("SELECT setValue FROM Settings WHERE setKey = 'UI_LANG'");
// below has to match exactly teh values in /front/php/templates/language/lang.php & /front/js/common.js // below has to match exactly teh values in /front/php/templates/language/lang.php & /front/js/common.js
switch($result){ switch($result){

View File

@@ -922,7 +922,7 @@
{ {
"name": "value", "name": "value",
"type": "sql", "type": "sql",
"value": "SELECT '❌None' as name, '' as id UNION SELECT devName as name, devMac as id FROM Devices WHERE EXISTS (SELECT 1 FROM Settings WHERE Code_Name = 'NETWORK_DEVICE_TYPES' AND LOWER(value) LIKE '%' || LOWER(devType) || '%' AND devType <> '')" "value": "SELECT '❌None' as name, '' as id UNION SELECT devName as name, devMac as id FROM Devices WHERE EXISTS (SELECT 1 FROM Settings WHERE setKey = 'NETWORK_DEVICE_TYPES' AND LOWER(setValue) LIKE '%' || LOWER(devType) || '%' AND devType <> '')"
}, },
{ {
"name": "target_macs", "name": "target_macs",
@@ -1006,7 +1006,7 @@
{ {
"name": "value", "name": "value",
"type": "sql", "type": "sql",
"value": "WITH RECURSIVE SettingsIcons AS (SELECT REPLACE(REPLACE(REPLACE(Value, '[', ''), ']', ''), '''', '') AS icon_list FROM Settings WHERE Code_Name = 'UI_ICONS'), SplitIcons AS (SELECT TRIM(SUBSTR(icon_list, 1, INSTR(icon_list || ',', ',') - 1)) AS icon, SUBSTR(icon_list, INSTR(icon_list || ',', ',') + 1) AS remaining_icons FROM SettingsIcons WHERE icon_list <> '' UNION ALL SELECT TRIM(SUBSTR(remaining_icons, 1, INSTR(remaining_icons || ',', ',') - 1)) AS icon, SUBSTR(remaining_icons, INSTR(remaining_icons || ',', ',') + 1) AS remaining_icons FROM SplitIcons WHERE remaining_icons <> '') SELECT DISTINCT * FROM (SELECT icon as name, icon as id FROM SplitIcons UNION SELECT '❌None' AS name, '' AS id UNION SELECT devIcon AS name, devIcon AS id FROM Devices WHERE devIcon <> '') AS combined_results;" "value": "WITH RECURSIVE SettingsIcons AS (SELECT REPLACE(REPLACE(REPLACE(setValue, '[', ''), ']', ''), '''', '') AS icon_list FROM Settings WHERE setKey = 'UI_ICONS'), SplitIcons AS (SELECT TRIM(SUBSTR(icon_list, 1, INSTR(icon_list || ',', ',') - 1)) AS icon, SUBSTR(icon_list, INSTR(icon_list || ',', ',') + 1) AS remaining_icons FROM SettingsIcons WHERE icon_list <> '' UNION ALL SELECT TRIM(SUBSTR(remaining_icons, 1, INSTR(remaining_icons || ',', ',') - 1)) AS icon, SUBSTR(remaining_icons, INSTR(remaining_icons || ',', ',') + 1) AS remaining_icons FROM SplitIcons WHERE remaining_icons <> '') SELECT DISTINCT * FROM (SELECT icon as name, icon as id FROM SplitIcons UNION SELECT '❌None' AS name, '' AS id UNION SELECT devIcon AS name, devIcon AS id FROM Devices WHERE devIcon <> '') AS combined_results;"
} }
], ],
"localized": ["name", "description"], "localized": ["name", "description"],

View File

@@ -14,7 +14,6 @@
<?php <?php
require 'php/templates/header.php'; require 'php/templates/header.php';
require 'php/components/graph_online_history.php';
?> ?>
<!-- Page ------------------------------------------------------------------ --> <!-- Page ------------------------------------------------------------------ -->
@@ -117,8 +116,10 @@
<div class="box-body"> <div class="box-body">
<div class="chart"> <div class="chart">
<script src="lib/AdminLTE/bower_components/chart.js/Chart.js"></script> <script src="lib/AdminLTE/bower_components/chart.js/Chart.js"></script>
<!-- <canvas id="clientsChart" width="800" height="140" class="extratooltipcanvas no-user-select"></canvas> --> <!-- presence chart -->
<canvas id="OnlineChart" style="width:100%; height: 150px; margin-bottom: 15px;"></canvas> <?php
require 'php/components/graph_online_history.php';
?>
</div> </div>
</div> </div>
<!-- /.box-body --> <!-- /.box-body -->

View File

@@ -33,15 +33,14 @@ $result = $db->query("SELECT * FROM Settings");
$settings = array(); $settings = array();
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
// Push row data // Push row data
$settings[] = array( 'Code_Name' => $row['Code_Name'], $settings[] = array( 'setKey' => $row['setKey'],
'Display_Name' => $row['Display_Name'], 'setName' => $row['setName'],
'Description' => $row['Description'], 'setDescription' => $row['setDescription'],
'Type' => $row['Type'], 'setType' => $row['setType'],
'Options' => $row['Options'], 'setOptions' => $row['setOptions'],
'RegEx' => $row['RegEx'], 'setValue' => $row['setValue'],
'Value' => $row['Value'], 'setGroup' => $row['setGroup'],
'Group' => $row['Group'], 'setEvents' => $row['setEvents']
'Events' => $row['Events']
); );
} }
@@ -195,12 +194,12 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
pluginsData = res["data"]; pluginsData = res["data"];
// Sort settingsData alphabetically based on the "Group" property // Sort settingsData alphabetically based on the "setGroup" property
settingsData.sort((a, b) => { settingsData.sort((a, b) => {
if (a["Group"] < b["Group"]) { if (a["setGroup"] < b["setGroup"]) {
return -1; return -1;
} }
if (a["Group"] > b["Group"]) { if (a["setGroup"] > b["setGroup"]) {
return 1; return 1;
} }
return 0; return 0;
@@ -214,15 +213,15 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
// let's use that to verify settings were initialized correctly // let's use that to verify settings were initialized correctly
settingsData.forEach((set) => { settingsData.forEach((set) => {
codeName = set['Code_Name'] setKey = set['setKey']
try { try {
const isMetadata = codeName.includes('__metadata'); const isMetadata = setKey.includes('__metadata');
// if 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`)); const setObj = isMetadata ? {} : JSON.parse(getSetting(`${setKey}__metadata`));
} catch (error) { } catch (error) {
console.error(`Error getting setting for ${codeName}:`, error); console.error(`Error getting setting for ${setKey}:`, error);
showModalOk('WARNING', "Outdated cache - refreshing (refresh browser cache if needed)"); showModalOk('WARNING', "Outdated cache - refreshing (refresh browser cache if needed)");
setTimeout(() => { setTimeout(() => {
@@ -260,8 +259,8 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
settingsData.forEach((set) => { settingsData.forEach((set) => {
// settingPluginPrefixes // settingPluginPrefixes
if (!settingPluginPrefixes.includes(set.Group)) { if (!settingPluginPrefixes.includes(set.setGroup)) {
settingPluginPrefixes.push(set.Group); // = Unique plugin prefix settingPluginPrefixes.push(set.setGroup); // = Unique plugin prefix
} }
}); });
@@ -375,36 +374,36 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
// go thru all settings and collect settings per settings prefix // go thru all settings and collect settings per settings prefix
settingsData.forEach((set) => { settingsData.forEach((set) => {
const valIn = set['Value']; const valIn = set['setValue'];
const codeName = set['Code_Name']; const setKey = set['setKey'];
const overriddenByEnv = set['OverriddenByEnv'] == 1; const overriddenByEnv = set['setOverriddenByEnv'] == 1;
const setType = set['Type']; const setType = set['setType'];
const isMetadata = codeName.includes('__metadata'); const isMetadata = setKey.includes('__metadata');
// is this isn't a metadata entry, get corresponding metadata object from the dummy setting // is this isn't a metadata entry, get corresponding metadata object from the dummy setting
const setObj = isMetadata ? {} : JSON.parse(getSetting(`${codeName}__metadata`)); const setObj = isMetadata ? {} : JSON.parse(getSetting(`${setKey}__metadata`));
// not initialized properly, reload // not initialized properly, reload
if(isMetadata && valIn == "" ) if(isMetadata && valIn == "" )
{ {
console.warn(`Metadata setting value is empty: ${codeName}`); console.warn(`Metadata setting value is empty: ${setKey}`);
clearCache(); clearCache();
} }
// constructing final HTML for the setting // constructing final HTML for the setting
setHtml = "" setHtml = ""
if(set["Group"] == prefix) if(set["setGroup"] == prefix)
{ {
// hide metadata by default by assigning it a special class // hide metadata by default by assigning it a special class
isMetadata ? metadataClass = 'metadata' : metadataClass = ''; isMetadata ? metadataClass = 'metadata' : metadataClass = '';
isMetadata ? showMetadata = '' : showMetadata = `<i isMetadata ? showMetadata = '' : showMetadata = `<i
my-to-toggle="row_${codeName}__metadata" my-to-toggle="row_${setKey}__metadata"
title="${getString("Settings_Metadata_Toggle")}" title="${getString("Settings_Metadata_Toggle")}"
class="fa fa-circle-question pointer hideOnMobile" class="fa fa-circle-question pointer hideOnMobile"
onclick="toggleMetadata(this)"> onclick="toggleMetadata(this)">
</i>` ; </i>` ;
infoIcon = `<i my-to-show="#row_${codeName} .setting_description" infoIcon = `<i my-to-show="#row_${setKey} .setting_description"
title="${getString("Settings_Show_Description")}" title="${getString("Settings_Show_Description")}"
class="fa fa-circle-info pointer hideOnBigScreen" class="fa fa-circle-info pointer hideOnBigScreen"
onclick="showDescription(this)"> onclick="showDescription(this)">
@@ -412,15 +411,15 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
// NAME & DESCRIPTION columns // NAME & DESCRIPTION columns
setHtml += ` setHtml += `
<div class="row table_row ${metadataClass} " id="row_${codeName}"> <div class="row table_row ${metadataClass} " id="row_${setKey}">
<div class="table_cell setting_name bold col-sm-2"> <div class="table_cell setting_name bold col-sm-2">
<label>${getString(codeName + '_name', set['Display_Name'])}</label> <label>${getString(setKey + '_name', set['setName'])}</label>
<div class="small text-overflow-hidden"> <div class="small text-overflow-hidden">
<code>${codeName}</code>${showMetadata}${infoIcon} <code>${setKey}</code>${showMetadata}${infoIcon}
</div> </div>
</div> </div>
<div class="table_cell setting_description col-sm-4"> <div class="table_cell setting_description col-sm-4">
${getString(codeName + '_description', set['Description'])} ${getString(setKey + '_description', set['setDescription'])}
</div> </div>
<div class="table_cell input-group setting_input ${overriddenByEnv ? "setting_overriden_by_env" : ""} input-group col-xs-12 col-sm-6"> <div class="table_cell input-group setting_input ${overriddenByEnv ? "setting_overriden_by_env" : ""} input-group col-xs-12 col-sm-6">
`; `;
@@ -455,7 +454,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
overrideHtml = `<div class="override col-xs-12"> overrideHtml = `<div class="override col-xs-12">
<div class="override-check col-xs-1"> <div class="override-check col-xs-1">
<input onChange="overrideToggle(this)" my-data-type="${setType}" my-input-toggle-readonly="${codeName}" class="checkbox" id="${codeName}_override" type="checkbox" ${checked} /> <input onChange="overrideToggle(this)" my-data-type="${setType}" my-input-toggle-readonly="${setKey}" class="checkbox" id="${setKey}_override" type="checkbox" ${checked} />
</div> </div>
<div class="override-text col-xs-11" title="${getString("Setting_Override_Description")}"> <div class="override-text col-xs-11" title="${getString("Setting_Override_Description")}">
${getString("Setting_Override")} ${getString("Setting_Override")}
@@ -469,7 +468,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
// Parse the setType JSON string into an object // Parse the setType JSON string into an object
let inputHtml = ''; let inputHtml = '';
console.log(codeName); console.log(setKey);
console.log(setType); console.log(setType);
const setTypeObject = JSON.parse(setType.replace(/'/g, '"')); const setTypeObject = JSON.parse(setType.replace(/'/g, '"'));
@@ -497,7 +496,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
onChange, onChange,
customParams, customParams,
customId customId
} = handleElementOptions(codeName, elementOptions, transformers, valIn); } = handleElementOptions(setKey, elementOptions, transformers, valIn);
// override // override
val = valRes; val = valRes;
@@ -513,15 +512,15 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
my-data-type="${dataType}" my-data-type="${dataType}"
my-editable="${editable}" my-editable="${editable}"
class="form-control ${addCss}" class="form-control ${addCss}"
name="${codeName}" name="${setKey}"
id="${codeName}" id="${setKey}"
my-customparams="${customParams}" my-customparams="${customParams}"
my-customid="${customId}" my-customid="${customId}"
${multi}> ${multi}>
<option value="" id="${codeName + "_temp_"}"></option> <option value="" id="${setKey + "_temp_"}"></option>
</select>`; </select>`;
generateOptionsOrSetOptions(codeName, createArray(val), `${codeName}_temp_`, generateOptions, targetField = null, transformers); generateOptionsOrSetOptions(setKey, createArray(val), `${setKey}_temp_`, generateOptions, targetField = null, transformers);
break; break;
@@ -536,7 +535,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
my-data-type="${dataType}" my-data-type="${dataType}"
my-customparams="${customParams}" my-customparams="${customParams}"
my-customid="${customId}" my-customid="${customId}"
id="${codeName}${suffix}" id="${setKey}${suffix}"
type="${inputType}" type="${inputType}"
value="${val}" value="${val}"
${readOnly} ${readOnly}
@@ -553,7 +552,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
my-customparams="${customParams}" my-customparams="${customParams}"
my-customid="${customId}" my-customid="${customId}"
my-input-from="${sourceIds}" my-input-from="${sourceIds}"
my-input-to="${codeName}" my-input-to="${setKey}"
onclick="${onClick}"> onclick="${onClick}">
${getString(getStringKey)} ${getString(getStringKey)}
</button>`; </button>`;
@@ -565,7 +564,7 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
my-customparams="${customParams}" my-customparams="${customParams}"
my-customid="${customId}" my-customid="${customId}"
my-data-type="${dataType}" my-data-type="${dataType}"
id="${codeName}" id="${setKey}"
${readOnly}> ${readOnly}>
${val} ${val}
</textarea>`; </textarea>`;
@@ -591,13 +590,13 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
// process events (e.g. run a scan, or test a notification) if associated with the setting // process events (e.g. run a scan, or test a notification) if associated with the setting
let eventsHtml = ""; let eventsHtml = "";
const eventsList = createArray(set['Events']); const eventsList = createArray(set['setEvents']);
if (eventsList.length > 0) { if (eventsList.length > 0) {
// console.log(eventsList) // console.log(eventsList)
eventsList.forEach(event => { eventsList.forEach(event => {
eventsHtml += `<span class="input-group-addon pointer" eventsHtml += `<span class="input-group-addon pointer"
data-myparam="${codeName}" data-myparam="${setKey}"
data-myparam-plugin="${prefix}" data-myparam-plugin="${prefix}"
data-myevent="${event}" data-myevent="${event}"
onclick="addToExecutionQueue_settingEvent(this)" onclick="addToExecutionQueue_settingEvent(this)"
@@ -666,9 +665,9 @@ $settingsJSON_DB = json_encode($settings, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX
// loop through the settings definitions from the json // loop through the settings definitions from the json
res["data"].forEach(set => { res["data"].forEach(set => {
prefix = set["Group"] prefix = set["setGroup"]
setType = set["Type"] setType = set["setType"]
setCodeName = set["Code_Name"] setCodeName = set["setKey"]
console.log(prefix); console.log(prefix);

View File

@@ -77,9 +77,9 @@ sql_appevents = """select * from AppEvents"""
# as well as a combined count for devices that match any status listed in the UI_MY_DEVICES setting # as well as a combined count for devices that match any status listed in the UI_MY_DEVICES setting
sql_devices_tiles = """ sql_devices_tiles = """
WITH Statuses AS ( WITH Statuses AS (
SELECT Value SELECT setValue
FROM Settings FROM Settings
WHERE Code_Name = 'UI_MY_DEVICES' WHERE setKey = 'UI_MY_DEVICES'
), ),
MyDevicesFilter AS ( MyDevicesFilter AS (
SELECT SELECT
@@ -87,11 +87,11 @@ sql_devices_tiles = """
devPresentLastScan, devAlertDown, devIsNew, devIsArchived devPresentLastScan, devAlertDown, devIsNew, devIsArchived
FROM Devices FROM Devices
WHERE WHERE
(instr((SELECT Value FROM Statuses), 'online') > 0 AND devPresentLastScan = 1) OR (instr((SELECT setValue FROM Statuses), 'online') > 0 AND devPresentLastScan = 1) OR
(instr((SELECT Value FROM Statuses), 'offline') > 0 AND devPresentLastScan = 0) OR (instr((SELECT setValue FROM Statuses), 'offline') > 0 AND devPresentLastScan = 0) OR
(instr((SELECT Value FROM Statuses), 'down') > 0 AND devPresentLastScan = 0 AND devAlertDown = 1) OR (instr((SELECT setValue FROM Statuses), 'down') > 0 AND devPresentLastScan = 0 AND devAlertDown = 1) OR
(instr((SELECT Value FROM Statuses), 'new') > 0 AND devIsNew = 1) OR (instr((SELECT setValue FROM Statuses), 'new') > 0 AND devIsNew = 1) OR
(instr((SELECT Value FROM Statuses), 'archived') > 0 AND devIsArchived = 1) (instr((SELECT setValue FROM Statuses), 'archived') > 0 AND devIsArchived = 1)
) )
SELECT SELECT
-- Counts for each individual status -- Counts for each individual status

View File

@@ -487,16 +487,15 @@ class DB():
self.sql.execute(""" DROP TABLE IF EXISTS Settings;""") self.sql.execute(""" DROP TABLE IF EXISTS Settings;""")
self.sql.execute(""" self.sql.execute("""
CREATE TABLE "Settings" ( CREATE TABLE "Settings" (
"Code_Name" TEXT, "setKey" TEXT,
"Display_Name" TEXT, "setName" TEXT,
"Description" TEXT, "setDescription" TEXT,
"Type" TEXT, "setType" TEXT,
"Options" TEXT, "setOptions" TEXT,
"RegEx" TEXT, "setGroup" TEXT,
"Group" TEXT, "setValue" TEXT,
"Value" TEXT, "setEvents" TEXT,
"Events" TEXT, "setOverriddenByEnv" INTEGER
"OverriddenByEnv" INTEGER
); );
""") """)

View File

@@ -18,6 +18,11 @@ app = Flask(__name__)
# Retrieve API token and port # Retrieve API token and port
graphql_port_value = get_setting_value("GRAPHQL_PORT") graphql_port_value = get_setting_value("GRAPHQL_PORT")
# Endpoint used when accessed via browser
@app.route("/graphql", methods=["GET"])
def graphql_debug():
# Handles GET requests
return "NetAlertX GraphQL server running."
# Endpoint for GraphQL queries # Endpoint for GraphQL queries
@app.route("/graphql", methods=["POST"]) @app.route("/graphql", methods=["POST"])

View File

@@ -292,7 +292,7 @@ def get_setting(key):
data = json.load(json_file) data = json.load(json_file)
for item in data.get("data",[]): for item in data.get("data",[]):
if item.get("Code_Name") == key: if item.get("setKey") == key:
return item return item
mylog('debug', [f'[Settings] ⚠ ERROR - setting_missing - Setting not found for key: {key} in file {settingsFile}']) mylog('debug', [f'[Settings] ⚠ ERROR - setting_missing - Setting not found for key: {key} in file {settingsFile}'])
@@ -327,8 +327,8 @@ def get_setting_value(key):
set_type = 'Error: Not handled' set_type = 'Error: Not handled'
set_value = 'Error: Not handled' set_value = 'Error: Not handled'
set_value = setting["Value"] # Setting value (Value (upper case) = user overridden default_value) set_value = setting["setValue"] # Setting value (Value (upper case) = user overridden default_value)
set_type = setting["Type"] # Setting type # lower case "type" - default json value vs uppper-case "Type" (= from user defined settings) set_type = setting["setType"] # Setting type # lower case "type" - default json value vs uppper-case "setType" (= from user defined settings)
value = setting_value_to_python_type(set_type, set_value) value = setting_value_to_python_type(set_type, set_value)

View File

@@ -12,7 +12,7 @@ import re
import conf import conf
from const import fullConfPath, applicationPath, fullConfFolder from const import fullConfPath, applicationPath, fullConfFolder
from helper import collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, updateState, setting_value_to_python_type, timeNowTZ, get_setting_value, generate_random_string from helper import fixPermissions, collect_lang_strings, updateSubnets, initOrSetParam, isJsonObject, updateState, setting_value_to_python_type, timeNowTZ, get_setting_value, generate_random_string
from logger import mylog from logger import mylog
from api import update_api from api import update_api
from scheduler import schedule_class from scheduler import schedule_class
@@ -30,7 +30,7 @@ from notification import write_notification
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# managing application settings, ensuring SQL safety for user input, and updating internal configuration lists # managing application settings, ensuring SQL safety for user input, and updating internal configuration lists
def ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False, overriddenByEnv=0): def ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False, overriddenByEnv=0):
if events is None: if events is None:
events = [] events = []
if setJsonMetadata is None: if setJsonMetadata is None:
@@ -51,8 +51,8 @@ def ccd(key, default, config_dir, name, inputtype, options, group, events=None,
# Create the tuples # Create the tuples
sql_safe_tuple = (key, name, desc, str(inputtype), options, regex, str(result), group, str(events), overriddenByEnv) sql_safe_tuple = (key, name, desc, str(inputtype), options, str(result), group, str(events), overriddenByEnv)
settings_tuple = (key, name, desc, inputtype, options, regex, result, group, str(events), overriddenByEnv) settings_tuple = (key, name, desc, inputtype, options, result, group, str(events), overriddenByEnv)
# Update or append the tuples in the lists # Update or append the tuples in the lists
conf.mySettingsSQLsafe = update_or_append(conf.mySettingsSQLsafe, sql_safe_tuple, key) conf.mySettingsSQLsafe = update_or_append(conf.mySettingsSQLsafe, sql_safe_tuple, key)
@@ -60,7 +60,7 @@ def ccd(key, default, config_dir, name, inputtype, options, group, events=None,
# Save metadata in dummy setting if not a metadata key # Save metadata in dummy setting if not a metadata key
if '__metadata' not in key: if '__metadata' not in key:
metadata_tuple = (f'{key}__metadata', "metadata name", "metadata desc", '{"dataType":"json", "elements": [{"elementType" : "textarea", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]}', '[]', "", json.dumps(setJsonMetadata), group, '[]', overriddenByEnv) metadata_tuple = (f'{key}__metadata', "metadata name", "metadata desc", '{"dataType":"json", "elements": [{"elementType" : "textarea", "elementOptions" : [{"readonly": "true"}] ,"transformers": []}]}', '[]', json.dumps(setJsonMetadata), group, '[]', overriddenByEnv)
conf.mySettingsSQLsafe = update_or_append(conf.mySettingsSQLsafe, metadata_tuple, f'{key}__metadata') conf.mySettingsSQLsafe = update_or_append(conf.mySettingsSQLsafe, metadata_tuple, f'{key}__metadata')
conf.mySettings = update_or_append(conf.mySettings, metadata_tuple, f'{key}__metadata') conf.mySettings = update_or_append(conf.mySettings, metadata_tuple, f'{key}__metadata')
@@ -123,7 +123,7 @@ def importConfigs (db, all_plugins):
# Header # Header
updateState("Import config", showSpinner = True) updateState("Import config", showSpinner = True)
# remove all plugin langauge strings # remove all plugin language strings
sql.execute("DELETE FROM Plugins_Language_Strings;") sql.execute("DELETE FROM Plugins_Language_Strings;")
db.commitDB() db.commitDB()
@@ -216,7 +216,7 @@ def importConfigs (db, all_plugins):
setting_obj = get_plugin_setting_obj(plugin, "RUN") setting_obj = get_plugin_setting_obj(plugin, "RUN")
if setting_obj is not None: if setting_obj is not None:
set_type = setting_obj.get('type') # lower case "type" - default json value vs uppper-case "Type" (= from user defined settings) set_type = setting_obj.get('type') # lower case "type" - default json value vs uppper-case "setType" (= from user defined settings)
set_value = setting_obj.get('default_value') set_value = setting_obj.get('default_value')
plugin_run = setting_value_to_python_type(set_type, set_value) plugin_run = setting_value_to_python_type(set_type, set_value)
@@ -239,7 +239,7 @@ def importConfigs (db, all_plugins):
key = pref + "_" + setFunction key = pref + "_" + setFunction
# set.get() - returns None if not found, set["options"] raises error # set.get() - returns None if not found, set["options"] raises error
# ccd(key, default, config_dir, name, inputtype, options, group, events=[], desc = "", regex = "", setJsonMetadata = {}): # ccd(key, default, config_dir, name, inputtype, options, group, events=[], desc = "", setJsonMetadata = {}):
v = ccd(key, v = ccd(key,
set["default_value"], set["default_value"],
c_d, c_d,
@@ -249,7 +249,6 @@ def importConfigs (db, all_plugins):
group = pref, group = pref,
events = set.get("events"), events = set.get("events"),
desc = set["description"][0]["string"], desc = set["description"][0]["string"],
regex = "",
setJsonMetadata = set) setJsonMetadata = set)
# Save the user defined value into the object # Save the user defined value into the object
@@ -323,9 +322,9 @@ def importConfigs (db, all_plugins):
value = str(value) value = str(value)
# Log the value being passed # Log the value being passed
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False) # ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
mylog('verbose', [f"[Config] Setting override {setting_name} with value: {value}"]) mylog('verbose', [f"[Config] Setting override {setting_name} with value: {value}"])
ccd(setting_name, value, c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True, 1) ccd(setting_name, value, c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", None, None, True, 1)
except json.JSONDecodeError: except json.JSONDecodeError:
mylog('none', [f"[Config] [ERROR] Setting override decoding JSON from {app_conf_override_path}"]) mylog('none', [f"[Config] [ERROR] Setting override decoding JSON from {app_conf_override_path}"])
@@ -348,8 +347,8 @@ def importConfigs (db, all_plugins):
mylog('none', ['[Config] App upgraded 🚀']) mylog('none', ['[Config] App upgraded 🚀'])
# ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", regex="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False) # ccd(key, default, config_dir, name, inputtype, options, group, events=None, desc="", setJsonMetadata=None, overrideTemplate=None, forceDefault=False)
ccd('VERSION', buildTimestamp , c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", "", None, None, True) ccd('VERSION', buildTimestamp , c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", None, None, True)
write_notification(f'[Upgrade] : App upgraded 🚀 Please clear the cache: <ol> <li>Click OK below</li> <li>Clear the browser cache (shift + browser refresh button)</li> <li> Clear app cache with the 🔄 (reload) button in the header</li><li>Go to Settings and click Save</li> </ol> Check out new features and what has changed in the <a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.', 'interrupt', timeNowTZ()) write_notification(f'[Upgrade] : App upgraded 🚀 Please clear the cache: <ol> <li>Click OK below</li> <li>Clear the browser cache (shift + browser refresh button)</li> <li> Clear app cache with the 🔄 (reload) button in the header</li><li>Go to Settings and click Save</li> </ol> Check out new features and what has changed in the <a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.', 'interrupt', timeNowTZ())
@@ -360,8 +359,8 @@ def importConfigs (db, all_plugins):
# Insert settings into the DB # Insert settings into the DB
sql.execute ("DELETE FROM Settings") sql.execute ("DELETE FROM Settings")
# mylog('debug', [f"[Config] conf.mySettingsSQLsafe : '{conf.mySettingsSQLsafe}'"]) # mylog('debug', [f"[Config] conf.mySettingsSQLsafe : '{conf.mySettingsSQLsafe}'"])
sql.executemany ("""INSERT INTO Settings ("Code_Name", "Display_Name", "Description", "Type", "Options", sql.executemany ("""INSERT INTO Settings ("setKey", "setName", "setDescription", "setType", "setOptions",
"RegEx", "Value", "Group", "Events", "OverriddenByEnv" ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", conf.mySettingsSQLsafe) "setValue", "setGroup", "setEvents", "setOverriddenByEnv" ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)""", conf.mySettingsSQLsafe)
db.commitDB() db.commitDB()
@@ -420,7 +419,7 @@ replacements = {
r'REPORT_WEBHOOK=True': "WEBHOOK_RUN='on_notification'", r'REPORT_WEBHOOK=True': "WEBHOOK_RUN='on_notification'",
r'REPORT_PUSHSAFER=True': "PUSHSAFER_RUN='on_notification'", r'REPORT_PUSHSAFER=True': "PUSHSAFER_RUN='on_notification'",
r'REPORT_MQTT=True': "MQTT_RUN='on_notification'", r'REPORT_MQTT=True': "MQTT_RUN='on_notification'",
r'PIHOLE_CMD=': 'PIHOLE_CMD_OLD=', # r'PIHOLE_CMD=': 'PIHOLE_CMD_OLD=',
r'\bINCLUDED_SECTIONS\b': 'NTFPRCS_INCLUDED_SECTIONS', r'\bINCLUDED_SECTIONS\b': 'NTFPRCS_INCLUDED_SECTIONS',
r'\bDIG_GET_IP_ARG\b': 'INTRNT_DIG_GET_IP_ARG', r'\bDIG_GET_IP_ARG\b': 'INTRNT_DIG_GET_IP_ARG',
r'dev_MAC': 'devMac', r'dev_MAC': 'devMac',
@@ -463,6 +462,7 @@ def renameSettings(config_file):
for line in original_file: for line in original_file:
# Use regular expressions with word boundaries to check for the old setting code names # Use regular expressions with word boundaries to check for the old setting code names
if any(re.search(key, line) for key in replacements.keys()): if any(re.search(key, line) for key in replacements.keys()):
mylog('debug', f'[Config] Old setting names found in line: ({line})')
contains_old_settings = True contains_old_settings = True
break # Exit the loop if any old setting is found break # Exit the loop if any old setting is found
@@ -492,6 +492,9 @@ def renameSettings(config_file):
# Replace the original config_file with the temporary file # Replace the original config_file with the temporary file
shutil.move(str(config_file) + "_temp", str(config_file)) # Convert config_file to a string shutil.move(str(config_file) + "_temp", str(config_file)) # Convert config_file to a string
# ensure correct ownership
fixPermissions()
else: else:
mylog('debug', '[Config] No old setting names found in the file. No changes made.') mylog('debug', '[Config] No old setting names found in the file. No changes made.')

View File

@@ -31,8 +31,8 @@ class plugin_param:
inputValue = get_setting(param["value"]) inputValue = get_setting(param["value"])
if inputValue != None: if inputValue != None:
setVal = inputValue["Value"] # setting value setVal = inputValue["setValue"] # setting value
setTyp = inputValue["Type"] # setting type setTyp = inputValue["setType"] # setting type
setTypJSN = json.loads(setTyp.replace('"','\"').replace("'",'"')) setTypJSN = json.loads(setTyp.replace('"','\"').replace("'",'"'))