From 44856f9c0435471c615067b4e449674002837d6c Mon Sep 17 00:00:00 2001 From: Jokob-sk Date: Sat, 16 Sep 2023 21:14:34 +1000 Subject: [PATCH] Loading spinner + app_state.json, settings work --- front/devices.php | 22 ++++++++ front/js/pialert_common.js | 5 +- front/php/templates/header.php | 8 --- front/php/templates/language/en_us.json | 2 +- front/php/templates/language/es_es.json | 2 +- front/settings.php | 70 ++++++++++++++++++------- pialert/helper.py | 36 ++++++++++--- pialert/initialise.py | 24 ++++----- 8 files changed, 117 insertions(+), 52 deletions(-) diff --git a/front/devices.php b/front/devices.php index 9ee2dc68..4e261d9b 100755 --- a/front/devices.php +++ b/front/devices.php @@ -209,6 +209,8 @@ // ----------------------------------------------------------------------------- function main () { + handleLoadingDialog() + // get from cookie if available (need to use decodeURI as saved as part of URI in PHP) cookieColumnsVisibleStr = decodeURI(getCookie("Front_Devices_Columns_Visible")).replaceAll('%2C',',') @@ -542,6 +544,26 @@ function getDevicesList (status) { 'php/server/devices.php?action=getDevicesList&status=' + deviceStatus).load(); }; +function handleLoadingDialog() + { + $.get('api/app_state.json?nocache=' + Date.now(), function(appState) { + + console.log(appState["showSpinner"]) + if(appState["showSpinner"]) + { + showSpinner("settings_old") + + setTimeout("handleLoadingDialog()", 1000); + + } else + { + hideSpinner() + } + + }) + + } + diff --git a/front/js/pialert_common.js b/front/js/pialert_common.js index aa4d5c52..8ab122e9 100755 --- a/front/js/pialert_common.js +++ b/front/js/pialert_common.js @@ -539,11 +539,12 @@ function isEmpty(value) // ----------------------------------------------------------------------------- function showSpinner(stringKey='Loading') { - if($("#loadingSpinner")) + if($("#loadingSpinner").length) { + $("#loadingSpinner").show(); } - else{ + else{ html = `
diff --git a/front/php/templates/header.php b/front/php/templates/header.php index d3354373..c0946cfe 100755 --- a/front/php/templates/header.php +++ b/front/php/templates/header.php @@ -85,8 +85,6 @@ if ($ENABLED_DARKMODE === True) { function updateState(){ $.get('api/app_state.json?nocache=' + Date.now(), function(appState) { - // console.log(appState) - document.getElementById('state').innerHTML = appState["currentState"].replaceAll('"', ''); setTimeout("updateState()", 1000); @@ -106,12 +104,6 @@ if ($ENABLED_DARKMODE === True) { setTimeout("show_pia_servertime()", 1000); } - // refresh page on focus - adds a lot of SQL queries overhead onto the DB - disabling for now - // document.addEventListener("visibilitychange",()=>{ - // if(document.visibilityState==="visible"){ - // window.location.href = window.location.href.split('#')[0]; - // } - // }) diff --git a/front/php/templates/language/en_us.json b/front/php/templates/language/en_us.json index 99634409..5e269628 100755 --- a/front/php/templates/language/en_us.json +++ b/front/php/templates/language/en_us.json @@ -460,7 +460,7 @@ "Settings_Metadata_Toggle" : "Show/hide metadata for the given setting.", "settings_missing" : "Not all settings loaded, refresh the page! This is probably caused by a high load on the database.", "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_old" : "The settings in the DB (shown on this page) are outdated. This is probably caused by a running scan. The settings were saved in the pialert.conf file, but the background process didn not have time to import it yet to the DB. You can wait until the settings get refreshed so you do not overwrite your old values. Feel free to save your settings either way if you do not mind losing the settings between the last save and now. There are also backup files created if you need to compare your settings later.", + "settings_old" : "Importing settings and re-initializing...", "settings_imported" : "Last time settings were imported from the pialert.conf file:", "settings_expand_all" : "Expand all", "Setting_Override" : "Override value", diff --git a/front/php/templates/language/es_es.json b/front/php/templates/language/es_es.json index c0a2a68c..01ca5dbe 100755 --- a/front/php/templates/language/es_es.json +++ b/front/php/templates/language/es_es.json @@ -450,7 +450,7 @@ "Settings_Title" : " Configuración", "settings_missing" : "Actualiza la página, no todos los ajustes se han cargado. Probablemente sea por una sobrecarga de la base de datos.", "settings_missing_block" : "No puedes guardar los ajustes sin establecer todas las claves. Actualiza la página. Problabmente esté causado por una sobrecarga de la base de datos.", - "settings_old" : "Los ajustes mostrados en esta página están desactualizados. Probablemente sea por un escaneo en proceso. Los ajustes se guardan en el archivo pialert.conf, pero el proceso en segundo plano no las ha importado todavía a la base de datos. Puedes esperar a que los ajustes se actualicen para evitar sobreescribirlos con los ajustes antiguos. Si te da igual perder los ajustes desde la última vez que guardaste y ahora, siéntete libre de guardarlos de nuevo. También hay copias de seguridad creadas si necesitas comparar tus ajustes más tarde.", + "settings_old" : "N/A", "settings_imported" : "Última vez que los ajustes fueron importados desde el archivo pialert.conf:", "settings_expand_all" : "Expandir todo", "Setting_Override" : "Sobreescribir el valor", diff --git a/front/settings.php b/front/settings.php index 996ea8a6..d18cbcf1 100755 --- a/front/settings.php +++ b/front/settings.php @@ -575,16 +575,24 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { showModalOk('WARNING', ""); } else { + + // trigger a save settings event in the backend $.ajax({ method: "POST", url: "php/server/util.php", data: { function: 'savesettings', settings: JSON.stringify(collectSettings()) }, - success: function(data, textStatus) { + success: function(data, textStatus) { + showModalOk ('Result', data ); + // Remove navigation prompt "Are you sure you want to leave..." - window.onbeforeunload = null; + window.onbeforeunload = null; + + // Reloads the current page + setTimeout("window.location.reload()", 3000); + } }); @@ -607,25 +615,45 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { var result = data; - if(key == "Back_Settings_Imported") - { - fileModificationTime = ; - importedMiliseconds = parseInt(result.match( /\d+/g ).join('')); // sanitize the string and get only the numbers - - result = (new Date(importedMiliseconds)).toLocaleString("en-UK", { timeZone: "" }); //.toDateString(""); - - // check if displayed settings are outdated - if(fileModificationTime > importedMiliseconds) - { - showModalOk('WARNING: Outdated settings displayed', ""); - } - } else{ - result = result.replaceAll('"', ''); - } - + result = result.replaceAll('"', ''); + document.getElementById(targetId).innerHTML = result.replaceAll('"', ''); }); } + + // ----------------------------------------------------------------------------- + function handleLoadingDialog() + { + $.get('api/app_state.json?nocache=' + Date.now(), function(appState) { + + fileModificationTime = ; + + console.log(appState["settingsImported"]*1000) + importedMiliseconds = parseInt((appState["settingsImported"]*1000)); + + humanReadable = (new Date(importedMiliseconds)).toLocaleString("en-UK", { timeZone: "" }); + + console.log(humanReadable.replaceAll('"', '')) + + // check if displayed settings are outdated + // if(fileModificationTime > importedMiliseconds) + if(appState["showSpinner"] || fileModificationTime > importedMiliseconds) + { + showSpinner("settings_old") + + setTimeout("handleLoadingDialog()", 1000); + + } else + { + hideSpinner() + } + + document.getElementById('lastImportedTime').innerHTML = humanReadable; + + }) + + } + // ----------------------------------------------------------------------------- @@ -722,6 +750,10 @@ while ($row = $result -> fetchArray (SQLITE3_ASSOC)) { // --------------------------------------------------------- // Show last time settings have been imported - getParam("lastImportedTime", "Back_Settings_Imported", skipCache = true); + // getParam("lastImportedTime", "Back_Settings_Imported", skipCache = true); + + handleLoadingDialog() + + diff --git a/pialert/helper.py b/pialert/helper.py index dba8b0d8..2d11c440 100755 --- a/pialert/helper.py +++ b/pialert/helper.py @@ -37,17 +37,37 @@ def timeNow(): #------------------------------------------------------------------------------- # A class to manage the application state and to provide a frontend accessible API point class app_state_class: - def __init__(self, currentState): - - # json file containing the state to communicate with teh frontend + def __init__(self, currentState, settingsSaved=None, settingsImported=None, showSpinner=False): + # json file containing the state to communicate with the frontend stateFile = apiPath + '/app_state.json' - # update self + # Update self self.currentState = currentState self.lastUpdated = str(timeNowTZ()) - # update .json file - write_file(stateFile , json.dumps(self, cls=AppStateEncoder)) + # Check if the file exists and init values + if os.path.exists(stateFile): + with open(stateFile, 'r') as json_file: + previousState = json.load(json_file) + self.settingsSaved = previousState.get("settingsSaved", 0) + self.settingsImported = previousState.get("settingsImported", 0) + self.showSpinner = previousState.get("showSpinner", False) + else: + self.settingsSaved = 0 + self.settingsImported = 0 + self.showSpinner = False + + # Overwrite with provided parameters if not None + if settingsSaved is not None: + self.settingsSaved = settingsSaved + if settingsImported is not None: + self.settingsImported = settingsImported + if showSpinner is not None: + self.showSpinner = showSpinner + + # Update .json file + with open(stateFile, 'w') as json_file: + json.dump(self, json_file, cls=AppStateEncoder, indent=4) def isSet(self): @@ -69,9 +89,9 @@ class AppStateEncoder(json.JSONEncoder): return super().default(obj) #------------------------------------------------------------------------------- -def updateState(newState): +def updateState(newState, settingsSaved = None, settingsImported = None, showSpinner = False): - state = app_state_class(newState) + state = app_state_class(newState, settingsSaved, settingsImported, showSpinner) #------------------------------------------------------------------------------- def updateSubnets(scan_subnets): diff --git a/pialert/initialise.py b/pialert/initialise.py index 634bcb6c..3e71db3f 100755 --- a/pialert/initialise.py +++ b/pialert/initialise.py @@ -74,7 +74,7 @@ def importConfigs (db): return # Header - updateState("Import config") + updateState("Import config", showSpinner = True) mylog('debug', ['[Import Config] importing config file']) conf.mySettings = [] # reset settings @@ -170,15 +170,15 @@ def importConfigs (db): #cron_instance = Cron() # timestamps of last execution times - conf.startTime = conf.time_started - now_minus_24h = conf.time_started - datetime.timedelta(hours = 24) + conf.startTime = conf.time_started + now_minus_24h = conf.time_started - datetime.timedelta(hours = 24) # set these times to the past to force the first run - conf.last_internet_IP_scan = now_minus_24h - conf.last_scan_run = now_minus_24h - conf.last_cleanup = now_minus_24h - conf.last_update_vendors = conf.time_started - datetime.timedelta(days = 6) # update vendors 24h after first run and then once a week - conf.last_version_check = now_minus_24h + conf.last_internet_IP_scan = now_minus_24h + conf.last_scan_run = now_minus_24h + conf.last_cleanup = now_minus_24h + conf.last_update_vendors = conf.time_started - datetime.timedelta(days = 6) # update vendors 24h after first run and then once a week + conf.last_version_check = now_minus_24h # TODO cleanup later ---------------------------------------------------------------------------------- @@ -254,8 +254,6 @@ def importConfigs (db): - - conf.plugins_once_run = False # ----------------- # Plugins END @@ -279,9 +277,9 @@ def importConfigs (db): run_plugin_scripts(db, 'before_config_save' ) # Used to determine the next import - conf.lastImportedConfFile = os.path.getmtime(config_file) - - #TO DO this creates a circular reference between API and HELPER ! + conf.lastImportedConfFile = os.path.getmtime(config_file) + + updateState("Config imported", conf.lastImportedConfFile, conf.lastImportedConfFile, False) mylog('minimal', '[Config] Imported new config')