pluginHolder: fix plugin store cache timestamp display and stale refresh trigger.

Render next cache update in Norwegian format and mark overdue cache clearly while triggering background refresh from Installed view when cache metadata is expired.
This commit is contained in:
master3395
2026-03-26 15:22:56 +01:00
parent a8d1c0f4e9
commit b5b313090a
2 changed files with 35 additions and 12 deletions

View File

@@ -1737,7 +1737,7 @@
<strong>{% trans "Cache Information:" %}</strong>
{% trans "Plugin store data is cached for 1 hour to improve performance and reduce GitHub API rate limits. New plugins may take up to 1 hour to appear after being published." %}
{% if cache_expiry_timestamp %}
<br><strong>{% trans "Next cache update:" %}</strong> <span id="cacheExpiryTime" style="font-family: monospace;" data-timestamp="{{ cache_expiry_timestamp }}">{% trans "Calculating..." %}</span>
<br><strong>{% trans "Next cache update:" %}</strong> <span id="cacheExpiryTime" style="font-family: monospace;" data-timestamp="{{ cache_expiry_timestamp }}" data-expired="{% if cache_expired %}1{% else %}0{% endif %}" data-refresh-started="{% if cache_refresh_started %}1{% else %}0{% endif %}">{% trans "Calculating..." %}</span>
{% endif %}
</p>
<p class="warning-text">
@@ -3250,8 +3250,8 @@ function updateCacheExpiryTime() {
return;
}
// Get user's locale preferences
const locale = navigator.language || navigator.userLanguage || 'en-US';
// Always use Norwegian format for NO-facing UI: DD.MM.YYYY kl. HH:MM
const locale = 'nb-NO';
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
// Format date and time according to user's locale
@@ -3264,7 +3264,6 @@ function updateCacheExpiryTime() {
const timeOptions = {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
};
@@ -3273,11 +3272,18 @@ function updateCacheExpiryTime() {
const timeStr = expiryDate.toLocaleTimeString(locale, timeOptions);
// Combine with timezone abbreviation
const formatted = dateStr + ' ' + timeStr;
// Display with timezone info
expiryElement.textContent = formatted;
expiryElement.title = 'Local time: ' + formatted + ' | Timezone: ' + timezone;
const formatted = dateStr + ' kl. ' + timeStr;
const expired = expiryElement.getAttribute('data-expired') === '1';
const refreshStarted = expiryElement.getAttribute('data-refresh-started') === '1';
if (expired) {
expiryElement.textContent = refreshStarted
? ('Utlopt (' + formatted + ') - oppdaterer i bakgrunnen')
: ('Utlopt (' + formatted + ')');
} else {
expiryElement.textContent = formatted;
}
expiryElement.title = 'Lokal tid: ' + formatted + ' | Tidssone: ' + timezone;
} catch (e) {
console.error('Error formatting cache expiry time:', e);
expiryElement.textContent = 'Error calculating time';

View File

@@ -650,8 +650,13 @@ def installed(request):
for p in pluginList:
logging.writeToFile(f" - {p.get('plugin_dir')}: installed={p.get('installed')}, enabled={p.get('enabled')}")
# Get cache expiry timestamp for display (will be converted to local time in browser)
# Get cache expiry timestamp for display (browser formats this as nb-NO)
cache_expiry_timestamp, _ = _get_cache_expiry_time()
cache_expired = _is_cache_expired(cache_expiry_timestamp)
refresh_started = False
if cache_expired:
# If cache is stale while on Installed page, trigger best-effort background refresh.
refresh_started = _try_start_plugin_store_refresh_background()
# Sort plugins A-Å by name (case-insensitive) for Grid and Table view
pluginList.sort(key=lambda p: (p.get('name') or '').lower())
@@ -671,9 +676,11 @@ def installed(request):
pass
proc = httpProc(request, 'pluginHolder/plugins.html',
{'plugins': pluginList, 'error_plugins': errorPlugins,
{'plugins': pluginList, 'error_plugins': errorPlugins,
'installed_count': installed_count, 'active_count': active_count,
'cache_expiry_timestamp': cache_expiry_timestamp}, 'managePlugins')
'cache_expiry_timestamp': cache_expiry_timestamp,
'cache_expired': cache_expired,
'cache_refresh_started': refresh_started}, 'managePlugins')
return proc.render()
@csrf_exempt
@@ -946,6 +953,16 @@ def _get_cache_expiry_time():
logging.writeToFile(f"Error getting cache expiry time: {str(e)}")
return None, None
def _is_cache_expired(expiry_timestamp):
"""Return True if provided cache expiry timestamp is in the past."""
try:
if not expiry_timestamp:
return False
return float(expiry_timestamp) <= time.time()
except Exception:
return False
def _get_cached_plugins(allow_expired=False):
"""Get plugins from cache if available and not expired