diff --git a/server/app_state.py b/server/app_state.py index ec2ffc1c..c6eee593 100755 --- a/server/app_state.py +++ b/server/app_state.py @@ -39,7 +39,8 @@ class app_state_class: showSpinner=None, graphQLServerStarted=0, processScan=False, - pluginsStates=None): + pluginsStates=None, + appVersion=None): """ Initialize the application state, optionally overwriting previous values. @@ -54,6 +55,7 @@ class app_state_class: graphQLServerStarted (int, optional): Initial GraphQL server timestamp. processScan (bool, optional): Initial processScan flag. pluginsStates (dict, optional): Initial plugin states to merge with previous state. + appVersion (str, optional): Application version. """ # json file containing the state to communicate with the frontend stateFile = apiPath + 'app_state.json' @@ -80,6 +82,7 @@ class app_state_class: self.graphQLServerStarted = previousState.get("graphQLServerStarted", 0) self.currentState = previousState.get("currentState", "Init") self.pluginsStates = previousState.get("pluginsStates", {}) + self.appVersion = previousState.get("appVersion", "") else: # init first time values self.settingsSaved = 0 self.settingsImported = 0 @@ -90,6 +93,7 @@ class app_state_class: self.graphQLServerStarted = 0 self.currentState = "Init" self.pluginsStates = {} + self.appVersion = "" # Overwrite with provided parameters if supplied if settingsSaved is not None: @@ -118,7 +122,8 @@ class app_state_class: # Optionally ignore or add new plugin entries # To ignore new plugins, comment out the next line self.pluginsStates[plugin] = state - + if appVersion is not None: + self.appVersion = appVersion # check for new version every hour and if currently not running new version if self.isNewVersion is False and self.isNewVersionChecked + 3600 < int(timeNow().timestamp()): self.isNewVersion = checkNewVersion() @@ -154,7 +159,8 @@ def updateState(newState = None, showSpinner = None, graphQLServerStarted = None, processScan = None, - pluginsStates=None): + pluginsStates=None, + appVersion=None): """ Convenience method to create or update the app state. @@ -166,6 +172,7 @@ def updateState(newState = None, graphQLServerStarted (int, optional): Timestamp of GraphQL server start. processScan (bool, optional): Flag indicating if a scan is active. pluginsStates (dict, optional): Plugin state updates. + appVersion (str, optional): Application version. Returns: app_state_class: Updated state object. @@ -176,7 +183,8 @@ def updateState(newState = None, showSpinner, graphQLServerStarted, processScan, - pluginsStates) + pluginsStates, + appVersion) #------------------------------------------------------------------------------- diff --git a/server/helper.py b/server/helper.py index d33767af..8398705c 100755 --- a/server/helper.py +++ b/server/helper.py @@ -636,37 +636,42 @@ def collect_lang_strings(json, pref, stringSqlParams): #------------------------------------------------------------------------------- # Get the value from the buildtimestamp.txt and initialize it if missing -def getBuildTimeStamp(): +def getBuildTimeStampAndVersion(): """ - Retrieves the build timestamp from 'front/buildtimestamp.txt' within the - application directory. - - If the file does not exist, it is created and initialized with the value '0'. + Retrieves the build timestamp and version from files within the + application directory. Initializes them if missing. Returns: - int: The integer value of the build timestamp read from the file. - Returns 0 if the file is empty or just initialized. + tuple: (int buildTimestamp, str version) """ - buildTimestamp = 0 - build_timestamp_path = os.path.join(applicationPath, 'front/buildtimestamp.txt') + files_defaults = [ + ('front/buildtimestamp.txt', '0'), + ('.VERSION', 'unknown') + ] - # Ensure file exists, initialize if missing - if not os.path.exists(build_timestamp_path): - with open(build_timestamp_path, 'w') as f: - f.write("0") + results = [] - # Now safely read the timestamp - with open(build_timestamp_path, 'r') as f: - buildTimestamp = int(f.read().strip() or 0) + for filename, default in files_defaults: + path = os.path.join(applicationPath, filename) + if not os.path.exists(path): + with open(path, 'w') as f: + f.write(default) + + with open(path, 'r') as f: + content = f.read().strip() or default + # Convert buildtimestamp to int, leave version as string + value = int(content) if filename.endswith('buildtimestamp.txt') else content + results.append(value) + + return tuple(results) - return buildTimestamp #------------------------------------------------------------------------------- def checkNewVersion(): mylog('debug', [f"[Version check] Checking if new version available"]) - buildTimestamp = getBuildTimeStamp() + buildTimestamp, _version = getBuildTimeStampAndVersion() try: response = requests.get( diff --git a/server/initialise.py b/server/initialise.py index 8f55476d..f0fb0237 100755 --- a/server/initialise.py +++ b/server/initialise.py @@ -12,7 +12,7 @@ import re # Register NetAlertX libraries import conf from const import fullConfPath, applicationPath, fullConfFolder, default_tz -from helper import getBuildTimeStamp, fixPermissions, collect_lang_strings, updateSubnets, isJsonObject, setting_value_to_python_type, get_setting_value, generate_random_string +from helper import getBuildTimeStampAndVersion, fixPermissions, collect_lang_strings, updateSubnets, isJsonObject, setting_value_to_python_type, get_setting_value, generate_random_string from utils.datetime_utils import timeNowDB from app_state import updateState from logger import mylog @@ -380,21 +380,19 @@ def importConfigs (pm, db, all_plugins): # Check if app was upgraded - buildTimestamp = getBuildTimeStamp() - cur_version = conf.VERSION + buildTimestamp, new_version = getBuildTimeStampAndVersion() + prev_version = conf.VERSION - mylog('debug', [f"[Config] buildTimestamp: '{buildTimestamp}'"]) - mylog('debug', [f"[Config] conf.VERSION : '{cur_version}'"]) + mylog('debug', [f"[Config] buildTimestamp | prev_version | .VERSION file: '{buildTimestamp}|{prev_version}|{new_version}'"]) - if str(cur_version) != str(buildTimestamp): + if str(prev_version) != str(new_version): mylog('none', ['[Config] App upgraded 🚀']) # 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', new_version , c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", None, None, True) - write_notification(f'[Upgrade] : App upgraded 🚀 Please clear the cache:
  1. Click OK below
  2. Clear the browser cache (shift + browser refresh button)
  3. Clear app cache with the (reload) button in the header
  4. Go to Settings and click Save
Check out new features and what has changed in the 📓 release notes.', 'interrupt', timeNowDB()) - + write_notification(f'[Upgrade] : App upgraded from {prev_version} to {new_version} 🚀 Please clear the cache:
  1. Click OK below
  2. Clear the browser cache (shift + browser refresh button)
  3. Clear app cache with the (reload) button in the header
  4. Go to Settings and click Save
Check out new features and what has changed in the 📓 release notes.', 'interrupt', timeNowDB()) # ----------------- @@ -424,7 +422,7 @@ def importConfigs (pm, db, all_plugins): # settingsImported = None (timestamp), # showSpinner = False (1/0), # graphQLServerStarted = 1 (1/0)) - updateState("Config imported", conf.lastImportedConfFile, conf.lastImportedConfFile, False, 1) + updateState("Config imported", conf.lastImportedConfFile, conf.lastImportedConfFile, False, 1, None, None, new_version) msg = '[Config] Imported new settings config' mylog('minimal', msg)