backups: Fix showing not-installed apps in create backup page

- Also minor styling.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
Sunil Mohan Adapa 2019-01-25 17:56:36 -08:00
parent f32239d32b
commit 983f4d13e8
No known key found for this signature in database
GPG Key ID: 43EA1CFF0AA7C5F2
5 changed files with 22 additions and 14 deletions

View File

@ -169,7 +169,7 @@ def backup_apps(backup_handler, path, app_names=None,
if not app_names: if not app_names:
apps = get_all_apps_for_backup() apps = get_all_apps_for_backup()
else: else:
apps = _get_apps_in_order(app_names) apps = get_apps_in_order(app_names)
if _is_snapshot_available(): if _is_snapshot_available():
snapshot = _take_snapshot() snapshot = _take_snapshot()
@ -198,7 +198,7 @@ def restore_apps(restore_handler, app_names=None, create_subvolume=True,
if not app_names: if not app_names:
apps = get_all_apps_for_backup() apps = get_all_apps_for_backup()
else: else:
apps = _get_apps_in_order(app_names) apps = get_apps_in_order(app_names)
_install_apps_before_restore(apps) _install_apps_before_restore(apps)
@ -261,6 +261,13 @@ class BackupApp:
self.manifest == other_app.manifest and \ self.manifest == other_app.manifest and \
self.has_data == other_app.has_data self.has_data == other_app.has_data
def is_installed(self):
"""Return whether app is installed.
Return true even if the app needs update.
"""
return self.app.setup_helper.get_state() != 'needs-setup'
def run_hook(self, hook, packet): def run_hook(self, hook, packet):
"""Run a hook inside an application.""" """Run a hook inside an application."""
if not hasattr(self.app, hook): if not hasattr(self.app, hook):
@ -280,14 +287,16 @@ def get_all_apps_for_backup():
apps = [] apps = []
for module_name, module in module_loader.loaded_modules.items(): for module_name, module in module_loader.loaded_modules.items():
try: try:
apps.append(BackupApp(module_name, module)) backup_app = BackupApp(module_name, module)
if backup_app.is_installed():
apps.append(backup_app)
except TypeError: # Application not available for backup/restore except TypeError: # Application not available for backup/restore
pass pass
return apps return apps
def _get_apps_in_order(app_names): def get_apps_in_order(app_names):
"""Return a list of app modules in order of dependency.""" """Return a list of app modules in order of dependency."""
apps = [] apps = []
for module_name, module in module_loader.loaded_modules.items(): for module_name, module in module_loader.loaded_modules.items():

View File

@ -22,6 +22,8 @@
*/ */
// XXX: This is misuse of sr-only class. This is problematic for people using
// screen readers.
function swapWithLoadingButton() { function swapWithLoadingButton() {
$("#restore_btn").addClass("sr-only"); $("#restore_btn").addClass("sr-only");
$("#loading_btn").removeClass("sr-only"); $("#loading_btn").removeClass("sr-only");

View File

@ -59,6 +59,6 @@
{% endblock %} {% endblock %}
{% block page_js %} {% block page_js %}
<script type="text/javascript" src="{% static 'backups/loading_button.js' %}"></script> <script type="text/javascript"
src="{% static 'backups/loading_button.js' %}"></script>
{% endblock %} {% endblock %}

View File

@ -140,7 +140,7 @@ class TestBackupProcesses(unittest.TestCase):
@staticmethod @staticmethod
@patch('plinth.module_loader.loaded_modules.items') @patch('plinth.module_loader.loaded_modules.items')
def test__get_apps_in_order(modules): def test_get_apps_in_order(modules):
"""Test that apps are listed in correct dependency order.""" """Test that apps are listed in correct dependency order."""
apps = [ apps = [
('names', MagicMock(backup=_get_test_manifest('names'))), ('names', MagicMock(backup=_get_test_manifest('names'))),
@ -150,7 +150,7 @@ class TestBackupProcesses(unittest.TestCase):
module_loader.load_modules() module_loader.load_modules()
app_names = ['config', 'names'] app_names = ['config', 'names']
apps = api._get_apps_in_order(app_names) apps = api.get_apps_in_order(app_names)
assert apps[0].name == 'names' assert apps[0].name == 'names'
assert apps[1].name == 'config' assert apps[1].name == 'config'

View File

@ -179,10 +179,7 @@ class BaseRestoreView(SuccessMessageMixin, FormView):
"""Pass additional keyword args for instantiating the form.""" """Pass additional keyword args for instantiating the form."""
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
included_apps = self._get_included_apps() included_apps = self._get_included_apps()
installed_apps = api.get_all_apps_for_backup() kwargs['apps'] = api.get_apps_in_order(included_apps)
kwargs['apps'] = [
app for app in installed_apps if app.name in included_apps
]
return kwargs return kwargs
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -202,8 +199,8 @@ class RestoreFromUploadView(BaseRestoreView):
if not os.path.isfile(path): if not os.path.isfile(path):
messages.error(self.request, _('No backup file found.')) messages.error(self.request, _('No backup file found.'))
return redirect(reverse_lazy('backups:index')) return redirect(reverse_lazy('backups:index'))
else:
return super().get(*args, **kwargs) return super().get(*args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
"""Return additional context for rendering the template.""" """Return additional context for rendering the template."""