diff --git a/plinth/package.py b/plinth/package.py index 5a5f2ae3c..562aa0236 100644 --- a/plinth/package.py +++ b/plinth/package.py @@ -19,13 +19,9 @@ Framework for installing and updating distribution packages """ -from django.contrib import messages from django.utils.translation import ugettext as _ -import functools import logging -import threading -import plinth from plinth.utils import import_from_gi glib = import_from_gi('GLib', '2.0') packagekit = import_from_gi('PackageKitGlib', '1.0') @@ -55,15 +51,12 @@ class PackageException(Exception): class Transaction(object): """Information about an ongoing transaction.""" - def __init__(self, package_names, before_install=None, on_install=None): + def __init__(self, package_names): """Initialize transaction object. Set most values to None until they are sent as progress update. """ self.package_names = package_names - # XXX: This is hack, remove after implementing proper setup mechanism. - self.before_install = before_install - self.on_install = on_install # Progress self.allow_cancel = None @@ -79,10 +72,6 @@ class Transaction(object): self.download_size_remaining = None self.speed = None - # Completion - self.is_finished = False - self.exception = None - def get_id(self): """Return a identifier to use as a key in a map of transactions.""" return frozenset(self.package_names) @@ -94,43 +83,12 @@ class Transaction(object): self.package_names, self.allow_cancel, self.status_string, self.percentage, self.package, self.item_progress) - def start_install_in_thread(self): - """Start a PackageKit transaction to install given list of packages. - - This operation is non-blocking at it spawns a new thread. - """ - thread = threading.Thread(target=self.install) - thread.start() - def install(self): """Run a PackageKit transaction to install given packages.""" - try: - if self.before_install: - self.before_install() - except Exception as exception: - logger.exception('Error during setup before install - %s', - exception) - self.finish(exception) - return - try: self._do_install() - except PackageException as exception: - self.finish(exception) - return except glib.Error as exception: - self.finish(PackageException(exception.message)) - return - - try: - if self.on_install: - self.on_install() - except Exception as exception: - logger.exception('Error during setup - %s', exception) - self.finish(exception) - return - - self.finish() + raise PackageException(exception.message) def _do_install(self): """Run a PackageKit transaction to install given packages. @@ -208,115 +166,3 @@ class Transaction(object): else: logger.info('Unhandle packagekit progress callback - %s, %s', progress, progress_type) - - def finish(self, exception=None): - """Mark transaction as complected and store exception if any.""" - self.is_finished = True - self.exception = exception - - def collect_result(self): - """Retrieve the result of this transaction. - - Also remove self from global transactions list. - """ - assert self.is_finished - - del transactions[self.get_id()] - return self.exception - - -def required(package_names, before_install=None, on_install=None): - """Decorate a view to check and install required packages.""" - - def wrapper2(func): - """Return a function to check and install packages.""" - - @functools.wraps(func) - def wrapper(request, *args, **kwargs): - """Check and install packages required by a view.""" - if not _should_show_install_view(request, package_names): - return func(request, *args, **kwargs) - - view = plinth.views.PackageInstallView.as_view() - return view(request, package_names=package_names, - before_install=before_install, on_install=on_install, - *args, **kwargs) - - return wrapper - - return wrapper2 - - -def _should_show_install_view(request, package_names): - """Return whether the installation view should be shown.""" - transaction_id = frozenset(package_names) - - # No transaction in progress - if transaction_id not in transactions: - is_installed = check_installed(package_names) - return not is_installed - - # Installing - transaction = transactions[transaction_id] - if not transaction.is_finished: - return True - - # Transaction finished, waiting to show the result - exception = transaction.collect_result() - if not exception: - messages.success(request, - _('Installed and configured packages successfully.')) - return False - else: - error_string = getattr(exception, 'error_string', str(exception)) - error_details = getattr(exception, 'error_details', '') - messages.error(request, _('Error installing packages: {string} {details}') - .format(string=error_string, details=error_details)) - return True - - -def check_installed(package_names): - """Return a boolean installed status of package. - - This operation is blocking and waits until the check is finished. - """ - def _callback(progress, progress_type, user_data): - """Process progress updates on package resolve operation.""" - pass - - client = packagekit.Client() - response = client.resolve(packagekit.FilterEnum.INSTALLED, - tuple(package_names) + (None, ), None, - _callback, None) - - installed_package_names = [] - for package in response.get_package_array(): - if package.get_info() == packagekit.InfoEnum.INSTALLED: - installed_package_names.append(package.get_name()) - - packages_resolved[package.get_name()] = package - - # When package names could not be resolved - for package_name in package_names: - if package_name not in packages_resolved: - packages_resolved[package_name] = None - - return set(installed_package_names) == set(package_names) - - -def is_installing(package_names): - """Return whether a set of packages are currently being installed.""" - return frozenset(package_names) in transactions - - -def start_install(package_names, before_install=None, on_install=None): - """Start a PackageKit transaction to install given list of packages. - - This operation is non-blocking at it spawns a new thread. - """ - transaction = Transaction(package_names, - before_install=before_install, - on_install=on_install) - transactions[frozenset(package_names)] = transaction - - transaction.start_install_in_thread() diff --git a/plinth/setup.py b/plinth/setup.py index 2ade51021..c8fd747d2 100644 --- a/plinth/setup.py +++ b/plinth/setup.py @@ -98,9 +98,6 @@ class Helper(object): } transaction.install() - if transaction.exception: - logger.error('Error running install - %s', transaction.exception) - raise transaction.exception def call(self, step, method, *args, **kwargs): """Call an arbitrary method during setup and note down its stage.""" diff --git a/plinth/templates/package_install.html b/plinth/templates/package_install.html deleted file mode 100644 index 7df7bb8c6..000000000 --- a/plinth/templates/package_install.html +++ /dev/null @@ -1,94 +0,0 @@ -{% extends "base.html" %} -{% comment %} -# -# This file is part of Plinth. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -{% endcomment %} - -{% load bootstrap %} -{% load i18n %} - -{% block page_head %} - - {% if is_installing %} - - {% endif %} - -{% endblock %} - - -{% block content %} - -

{% trans "Installation" %}

- - {% if not is_installing %} - -

- {% blocktrans trimmed %} - This feature requires addtional packages to be installed. Do - you wish to install them? - {% endblocktrans %} -

- - - - - - - - - - {% for package_name, package in packages.items %} - - - - - {% endfor %} - -
{% trans "Package" %}{% trans "Summary" %}
{{ package_name }}{{ package.get_summary }}
- -
- {% csrf_token %} - - -
- - {% else %} - - {% for key, transaction in transactions.items %} -
- {% blocktrans trimmed with package_names=transaction.package_names|join:", " status=transaction.status_string %} - Installing {{ package_names }}: {{ status }} - {% endblocktrans %} -
-
-
- - {% blocktrans trimmed with percentage=transaction.percentage %} - {{ percentage }}% complete - {% endblocktrans %} - -
-
- {% endfor %} - - {% endif %} - -{% endblock %} diff --git a/plinth/views.py b/plinth/views.py index 8cee96adf..a5b9a7680 100644 --- a/plinth/views.py +++ b/plinth/views.py @@ -24,46 +24,12 @@ from django.http.response import HttpResponseRedirect from django.views.generic import TemplateView import time -from plinth import package as package_module - def index(request): """Serve the main index page.""" return HttpResponseRedirect(reverse('apps:index')) -class PackageInstallView(TemplateView): - """View to prompt and install packages.""" - template_name = 'package_install.html' - - def get_context_data(self, **kwargs): - """Return the context data rendering the template.""" - context = super(PackageInstallView, self).get_context_data(**kwargs) - - if 'packages_names' not in context: - context['package_names'] = self.kwargs.get('package_names', []) - context['packages'] = { - package_name: package_module.packages_resolved[package_name] - for package_name in context['package_names']} - context['is_installing'] = \ - package_module.is_installing(context['package_names']) - context['transactions'] = package_module.transactions - - return context - - def post(self, *args, **kwargs): - """Handle installing packages - - Start the package installation, and refresh the page every x seconds to - keep displaying PackageInstallView.get() with the installation status. - """ - package_module.start_install( - self.kwargs['package_names'], - before_install=self.kwargs.get('before_install'), - on_install=self.kwargs.get('on_install')) - return self.render_to_response(self.get_context_data()) - - class SetupView(TemplateView): """View to prompt and setup applications.""" template_name = 'setup.html'