Better version handling #458 + docs

This commit is contained in:
Jokob-sk
2023-09-30 09:53:15 +10:00
parent 07367a2ca3
commit ebeeb6c3a5
10 changed files with 115 additions and 132 deletions

View File

@@ -545,7 +545,7 @@ function getDevicesList (status) {
};
function handleLoadingDialog()
{
{
$.get('api/app_state.json?nocache=' + Date.now(), function(appState) {
console.log(appState["showSpinner"])
@@ -562,7 +562,7 @@ function handleLoadingDialog()
})
}
}
</script>

View File

@@ -1,14 +1,13 @@
function handleVersion(){
//--------------------------------------------------------------
// Handle the UI changes to show or hide notifications about a new version
function versionUpdateUI(){
release_timestamp = getCookie("release_timestamp")
isNewVersion = getCookie("isNewVersion")
if(release_timestamp != "")
{
build_timestamp = parseInt($('#version').attr("data-build-time").match( /\d+/g ).join(''))
console.log(isNewVersion)
// if the release_timestamp is older by 10 min or more as the build timestamp then there is a new release available
if(release_timestamp > build_timestamp + 600 )
if(isNewVersion != "false")
{
console.log("New release!")
// handling the navigation menu icon
@@ -27,54 +26,26 @@ function handleVersion(){
{
$(maintenanceDiv).attr("class", $(maintenanceDiv).attr("class").replace("myhidden", ""))
}
}
}
}
//--------------------------------------------------------------
//--------------------------------------------------------------
// Checks if a new version is available via the global app_state.json
function checkIfNewVersionAvailable()
{
$.get('api/app_state.json?nocache=' + Date.now(), function(appState) {
function getVersion()
{
release_timestamp = getCookie("release_timestamp")
release_timestampNum = Number(release_timestamp)
// logging
console.log(`Latest release in cookie: ${new Date(release_timestampNum*1000)}`)
// no cached value available
if(release_timestamp == "")
{
$.get('https://api.github.com/repos/jokob-sk/Pi.Alert/releases').done(function(response) {
// Handle successful response
var releases = response;
console.log(response)
if(releases.length > 0)
{
release_datetime = releases[0].published_at; // get latest release
release_timestamp = new Date(release_datetime).getTime() / 1000;
console.log(appState["isNewVersionChecked"])
console.log(appState["isNewVersion"])
// cache value
setCookie("release_timestamp", release_timestamp, 30);
setCookie("isNewVersion", appState["isNewVersion"], 30);
setCookie("isNewVersionChecked", appState["isNewVersionChecked"], 30);
handleVersion();
}
}).fail(function(jqXHR, textStatus, errorThrown) {
$('.version').append(`<p>Github API: ${errorThrown} (${jqXHR.status}), ${jqXHR.responseJSON.message}</p>`)
});
} else
{
// cache is available, just call the handler
handleVersion()
}
}
versionUpdateUI();
})
}
// handle the dispaly of the NEW icon
getVersion()
checkIfNewVersionAvailable()

View File

@@ -174,6 +174,12 @@ $db->close();
<?php echo date("Y-m-d", ((int)file_get_contents( "buildtimestamp.txt")));?>
</div>
</div>
<div class="db_info_table_row">
<div class="db_info_table_cell" style="min-width: 140px"><?= lang('Maintenance_Running_Version');?></div>
<div class="db_info_table_cell">
<?php include 'php/templates/version.php'; ?>
</div>
</div>
<div class="db_info_table_row">
<div class="db_info_table_cell" style="min-width: 140px"><?= lang('Maintenance_database_path');?></div>
<div class="db_info_table_cell">

View File

@@ -260,6 +260,7 @@
"Maintenance_new_version" : "🆕 A new version is available. Check out the <a href=\"https://github.com/jokob-sk/Pi.Alert/releases\" target=\"_blank\">release notes</a>.",
"Maintenance_current_version" : "You are up-to-date. Check out what <a href=\"https://github.com/jokob-sk/Pi.Alert/issues/138\" target=\"_blank\">I am working on</a>.",
"Maintenance_built_on" : "Built on",
"Maintenance_Running_Version" : "Installed version",
"Maintenance_database_path" : "Database-Path",
"Maintenance_database_size" : "Database-Size",
"Maintenance_database_rows" : "Table (Rows)",

View File

@@ -19,6 +19,7 @@
| | Yes | ARPSCAN | Script | 📚[arp_scan](/front/plugins/arp_scan/) |
| | | CSVBCKP | Script | 📚[csv_backup](/front/plugins/csv_backup/) |
| Yes* | | DBCLNP | Script | 📚[db_cleanup](/front/plugins/db_cleanup/) |
| | | DDNS | Script | 📚[ddns_update](/front/plugins/ddns_update/) |
| | Yes | DHCPLSS | Script | 📚[dhcp_leases](/front/plugins/dhcp_leases/) |
| | | DHCPSRVS | Script | 📚[dhcp_servers](/front/plugins/dhcp_servers/) |
| | Yes | INTRNT | Script | 📚[internet_ip](/front/plugins/internet_ip/) |

View File

@@ -1,6 +1,6 @@
## Overview
Plugin to run regular database cleanup tasks. It is strongly recommended to have an hourly or at least daily schedule running.
Plugin to run regular DDNS update tasks.
### Usage

View File

@@ -75,7 +75,7 @@ def ddns_update ( DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN, PREV_I
mylog('none', ['[DDNS] ', dns_IP])
# Check DNS Change
if dns_IP != internet_IP :
if dns_IP != PREV_IP :
mylog('none', ['[DDNS] Updating Dynamic DNS IP'])
message = set_dynamic_DNS_IP (DDNS_UPDATE_URL, DDNS_USER, DDNS_PASSWORD, DDNS_DOMAIN)
mylog('none', ['[DDNS] ', message])

View File

@@ -1,6 +1,6 @@
## Overview
Plugin to run regular database cleanup tasks. It is strongly recommended to have an hourly or at least daily schedule running.
Plugin to run regular Internet connectivity and IP checks.
### Usage

View File

@@ -24,7 +24,7 @@ import multiprocessing
import conf
from const import *
from logger import mylog
from helper import filePermissions, isNewVersion, timeNowTZ, updateState, get_setting_value
from helper import filePermissions, timeNowTZ, updateState, get_setting_value
from api import update_api
from networkscan import process_scan
from initialise import importConfigs
@@ -61,10 +61,6 @@ def main ():
mylog('none', [f'[conf.tz] Setting up ...{conf.tz}'])
# indicates, if a new version is available
conf.newVersionAvailable = False
# check file permissions and fix if required
filePermissions()
@@ -83,6 +79,9 @@ def main ():
mylog('debug', '[MAIN] Starting loop')
# Header + init app state
updateState("Initializing")
while True:
# re-load user configuration and plugins
@@ -91,16 +90,7 @@ def main ():
# update time started
conf.loop_start_time = timeNowTZ()
# TODO fix these
loop_start_time = conf.loop_start_time # TODO fix
last_version_check = conf.last_version_check
# check if new version is available / only check once an hour
if conf.last_version_check + datetime.timedelta(hours=1) < conf.loop_start_time :
# if newVersionAvailable is already true the function does nothing and returns true again
mylog('debug', [f"[Version check] Last version check timestamp: {conf.last_version_check}"])
conf.last_version_check = conf.loop_start_time
conf.newVersionAvailable = isNewVersion(conf.newVersionAvailable)
# Handle plugins executed ONCE
if conf.plugins_once_run == False:

View File

@@ -3,12 +3,12 @@
import io
import sys
import datetime
# from datetime import strptime
import os
import re
import subprocess
import pytz
from pytz import timezone
from datetime import timedelta
import json
import time
from pathlib import Path
@@ -43,6 +43,9 @@ class app_state_class:
# json file containing the state to communicate with the frontend
stateFile = apiPath + '/app_state.json'
# if currentState == 'Initializing':
# checkNewVersion(False)
# Update self
self.currentState = currentState
self.lastUpdated = str(timeNowTZ())
@@ -54,12 +57,16 @@ class app_state_class:
self.settingsSaved = previousState.get("settingsSaved", 0)
self.settingsImported = previousState.get("settingsImported", 0)
self.showSpinner = previousState.get("showSpinner", False)
self.isNewVersion = previousState.get("isNewVersion", False)
self.isNewVersionChecked = previousState.get("isNewVersionChecked", 0)
else:
self.settingsSaved = 0
self.settingsImported = 0
self.showSpinner = False
self.isNewVersion = checkNewVersion()
self.isNewVersionChecked = int(timeNow().timestamp())
# Overwrite with provided parameters if not None
# Overwrite with provided parameters if supplied
if settingsSaved is not None:
self.settingsSaved = settingsSaved
if settingsImported is not None:
@@ -67,6 +74,11 @@ class app_state_class:
if showSpinner is not None:
self.showSpinner = showSpinner
# 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()
self.isNewVersionChecked = int(timeNow().timestamp())
# Update .json file
with open(stateFile, 'w') as json_file:
json.dump(self, json_file, cls=AppStateEncoder, indent=4)
@@ -547,11 +559,11 @@ def collect_lang_strings(json, pref, stringSqlParams):
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
def isNewVersion(newVersion: bool):
def checkNewVersion():
mylog('debug', [f"[Version check] New version available? {newVersion}"])
mylog('debug', [f"[Version check] Checking if new version available"])
if newVersion == False:
newVersion = False
f = open(pialertPath + '/front/buildtimestamp.txt', 'r')
buildTimestamp = int(f.read().strip())
@@ -564,7 +576,7 @@ def isNewVersion(newVersion: bool):
text = url.text
data = json.loads(text)
except requests.exceptions.ConnectionError as e:
mylog('minimal', [" Couldn't check for new release."])
mylog('minimal', ["[Version check] Error: Couldn't check for new release."])
data = ""
# make sure we received a valid response and not an API rate limit exceeded message
@@ -577,6 +589,8 @@ def isNewVersion(newVersion: bool):
if realeaseTimestamp > buildTimestamp + 600:
mylog('none', ["[Version check] New version of the container available!"])
newVersion = True
else:
mylog('none', ["[Version check] Running the latest version."])
return newVersion