From f1f84a2509078687da659515a152b45084b62261 Mon Sep 17 00:00:00 2001 From: Fioddor Superconcentrado Date: Wed, 7 Oct 2020 19:28:10 +0200 Subject: [PATCH] upgrades: Add status section showing version and upgrade status Closes: #1939. - Force a delay before returning the upgrade result to allow upgrade to kick in. Otherwise when the flow returns, get_context_data() creates the context too early and finds the upgrade not yet busy, causing the refresh loop to miss it. The page renders static and the user gets no clue to the upgrade executing in the background. Signed-off-by: Fioddor Superconcentrado [sunil: Retain the styling for the remainder of the page] [sunil: Re-style the status section as a simple web-page] [sunil: Drop unused running-status CSS styles] [sunil: Rename CSS variables, minor changes to color values] Signed-off-by: Sunil Mohan Adapa Reviewed-by: Sunil Mohan Adapa Signed-off-by: Sunil Mohan Adapa --- plinth/modules/help/views.py | 15 +----- .../templates/upgrades_configure.html | 48 +++++++++++++++++ plinth/modules/upgrades/views.py | 30 ++++++++++- static/themes/default/css/main.css | 51 ++++++++++--------- 4 files changed, 106 insertions(+), 38 deletions(-) diff --git a/plinth/modules/help/views.py b/plinth/modules/help/views.py index 3a0127bdc..eaa5c756c 100644 --- a/plinth/modules/help/views.py +++ b/plinth/modules/help/views.py @@ -16,6 +16,7 @@ from django.utils.translation import get_language_from_request from django.utils.translation import ugettext as _ from plinth import __version__, actions, cfg +from plinth.modules.upgrades.views import get_os_release def index(request): @@ -50,7 +51,7 @@ def about(request): 'title': _('About {box_name}').format(box_name=_(cfg.box_name)), 'version': __version__, 'new_version': not freedombox.candidate.is_installed, - 'os_release': get_os_release(), + 'os_release': get_os_release() } return TemplateResponse(request, 'help_about.html', context) @@ -120,15 +121,3 @@ def status_log(request): output = actions.superuser_run('help', ['get-logs']) context = {'num_lines': 100, 'data': output} return TemplateResponse(request, 'statuslog.html', context) - - -def get_os_release(): - """Returns the Debian release number and name""" - output = 'Error: Cannot read PRETTY_NAME in /etc/os-release.' - with open('/etc/os-release', 'r') as release_file: - for line in release_file: - if 'PRETTY_NAME=' in line: - line = line.replace('"', '').strip() - line = line.split('=') - output = line[1] - return output diff --git a/plinth/modules/upgrades/templates/upgrades_configure.html b/plinth/modules/upgrades/templates/upgrades_configure.html index 5878a7d45..bd3dd69f7 100644 --- a/plinth/modules/upgrades/templates/upgrades_configure.html +++ b/plinth/modules/upgrades/templates/upgrades_configure.html @@ -7,6 +7,54 @@ {% load i18n %} {% load static %} +{% block page_head %} + +{% endblock %} + +{% block status %} + {{ block.super}} {% comment %} To extend instead of overwrite {% endcomment %} + +

{% trans "Status" %}

+
+
+ {% if is_busy %} + + {% elif new_version %} + + {% else %} + + {% endif %} +
+

+ {% blocktrans trimmed %} + You are running {{ os_release }} and {{ box_name }} version {{ version }}. + {% endblocktrans %} + {% if is_busy %} + {% trans "Updating..." %} + {% elif new_version %} + {% blocktrans trimmed %} + There is a new {{ box_name }} version available. + {% endblocktrans %} + {% trans "Your Freedombox needs an update!" %} + {% else %} + {% blocktrans %}{{ box_name }} is up to date.{% endblocktrans %} + {% endif %} +

+
+{% endblock %} + {% block extra_content %}

{% trans "Frequent Feature Updates" %}

diff --git a/plinth/modules/upgrades/views.py b/plinth/modules/upgrades/views.py index 443227c34..0a8f4a081 100644 --- a/plinth/modules/upgrades/views.py +++ b/plinth/modules/upgrades/views.py @@ -2,7 +2,9 @@ """ FreedomBox app for upgrades. """ +import time +from apt.cache import Cache from django.contrib import messages from django.http import HttpResponseRedirect from django.shortcuts import redirect @@ -10,7 +12,7 @@ from django.urls import reverse_lazy from django.utils.translation import ugettext as _ from django.views.generic.edit import FormView -from plinth import actions, package +from plinth import __version__, actions, package from plinth.errors import ActionError from plinth.modules import first_boot, upgrades from plinth.views import AppView @@ -29,12 +31,17 @@ class UpgradesConfigurationView(AppView): return {'auto_upgrades_enabled': upgrades.is_enabled()} def get_context_data(self, *args, **kwargs): + cache = Cache() + freedombox = cache['freedombox'] context = super().get_context_data(*args, **kwargs) context['can_activate_backports'] = upgrades.can_activate_backports() context['is_backports_requested'] = upgrades.is_backports_requested() context['is_busy'] = package.is_package_manager_busy() context['log'] = get_log() context['refresh_page_sec'] = 3 if context['is_busy'] else None + context['version'] = __version__ + context['new_version'] = not freedombox.candidate.is_installed + context['os_release'] = get_os_release() return context def form_valid(self, form): @@ -66,6 +73,21 @@ class UpgradesConfigurationView(AppView): return super().form_valid(form) +def get_os_release(): + """Returns the Debian release number and name + + Note: The Help module calls this function also. + """ + output = 'Error: Cannot read PRETTY_NAME in /etc/os-release.' + with open('/etc/os-release', 'r') as release_file: + for line in release_file: + if 'PRETTY_NAME=' in line: + line = line.replace('"', '').strip() + line = line.split('=') + output = line[1] + return output + + def get_log(): """Return the current log for unattended upgrades.""" return actions.superuser_run('upgrades', ['get-log']) @@ -73,10 +95,16 @@ def get_log(): def upgrade(request): """Serve the upgrade page.""" + secs_for_package_to_get_busy = 2 if request.method == 'POST': try: actions.superuser_run('upgrades', ['run']) messages.success(request, _('Upgrade process started.')) + # Give the Package module some time to get busy so the page enters + # the refreshing loop. XXX: Remove after changing the busy check + # implementation include activating state of + # freedombox-manual-upgrade.service. + time.sleep(secs_for_package_to_get_busy) except ActionError: messages.error(request, _('Starting upgrade failed.')) diff --git a/static/themes/default/css/main.css b/static/themes/default/css/main.css index 6808adec3..3b258e1c4 100644 --- a/static/themes/default/css/main.css +++ b/static/themes/default/css/main.css @@ -2,6 +2,17 @@ # SPDX-License-Identifier: AGPL-3.0-or-later */ +:root { + --background-color: #f1f1f1; /* Light grey */ + --neutral-light-color: #f5f5f5; /* Light grey */ + --neutral-dark-color: #d4d4d4; /* Grey */ + --info-color: #5bc0de; /* Pale blue, almost turquoise */ + --freedombox-blue-color: #4989D4; /* Blue */ + --progress-color: #3498db; /* Blue */ + --error-color: #d9534f; /* Red */ + --warning-color: #ec971f; /* Orange */ +} + @font-face { font-family: 'Lato'; src: url('../lato/Lato-Italic.woff2') format('woff2'); @@ -64,7 +75,7 @@ body { position: relative; font-family: Lato, sans-serif; font-size: 15px; - background: url('../img/noise.png') #f1f1f1; + background: url('../img/noise.png') var(--background-color); } @media (max-width: 767px) { @@ -75,7 +86,7 @@ body { body.index-page, body.apps-page, body.system-page { - background: url('../img/noise.png') #f1f1f1; + background: url('../img/noise.png') var(--background-color); } } @@ -114,17 +125,9 @@ body { display: inline-block; } -.running-status.active { - background-color: rgb(0, 167, 0); -} - -.running-status.inactive { - background-color: rgb(228, 66, 66); -} - .running-status.loading { - border: 4px solid #f3f3f3; /* Light grey */ - border-top: 4px solid #3498db; /* Blue */ + border: 4px solid var(--neutral-light-color); + border-top: 4px solid var(--progress-color); border-radius: 50%; width: 16px; height: 16px; @@ -159,7 +162,7 @@ body { .form-diagnostics-button .btn:hover, .form-diagnostics-button .btn:focus { - background-color:#f5f5f5 + background-color: var(--neutral-light-color) } /* Hide log out button if user dropdown is available */ @@ -272,7 +275,7 @@ footer { /* applying styles to header - begin */ .main-header { - background: #4989D4; + background: var(--freedombox-blue-color); box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.25); border: none; } @@ -325,7 +328,7 @@ footer { color: white; content: ''; flex: 1; - border-bottom: #d4d4d4 solid 2px; + border-bottom: var(--neutral-dark-color) solid 2px; margin: auto 1.8rem; } @@ -514,7 +517,7 @@ a.menu_link_active { } .toggle-button--toggled { - background: #4989D4; + background: var(--freedombox-blue-color); } .toggle-button--toggled::before { @@ -527,8 +530,8 @@ a.menu_link_active { */ .running-status-button-before { display: inline-block; - border: 4px solid #f3f3f3; /* Light grey */ - border-top: 4px solid #3498db; /* Blue */ + border: 4px solid var(--neutral-light-color); + border-top: 4px solid var(--progress-color); border-radius: 50%; width: 16px; height: 16px; @@ -686,27 +689,27 @@ img.notification-icon { } .badge-exception, .badge-error { - background-color: #d9534f; + background-color: var(--error-color); } .badge-warning { - background-color: #ec971f; + background-color: var(--warning-color); } .badge-info, .badge-debug { - background-color: #5bc0de; + background-color: var(--info-color); } .notification-exception, .notification-error { - border-left-color: #d9534f; + border-left-color: var(--error-color); } .notification-warning { - border-left-color: #ec971f; + border-left-color: var(--warning-color); } .notification-info, .notification-debug { - border-left-color: #5bc0de; + border-left-color: var(--info-color) } /* Don't collapse notifications on small screens */