From fa8c2cf6ff7f589334096a60cef49430d9d00c3d Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Sun, 28 Feb 2016 12:21:29 +0530 Subject: [PATCH] views: Add a common view for enabling applications - A lot of boiler plate code can be removed from Plinth if enabling and disabling an application can be done using a common base form. - This also allows to define a reusable method in an application for enabling and disabling. - This brings more structure to a application module and paves way for having a different views such as dashboard. --- plinth/forms.py | 30 ++++++++++++++++++ plinth/views.py | 84 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 plinth/forms.py diff --git a/plinth/forms.py b/plinth/forms.py new file mode 100644 index 000000000..f554bcfc8 --- /dev/null +++ b/plinth/forms.py @@ -0,0 +1,30 @@ +# +# 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 . +# + +""" +Common forms for use by modules. +""" + +from django import forms +from django.utils.translation import ugettext_lazy as _ + + +class ConfigurationForm(forms.Form): + """Generic configuration form for simple modules.""" + enabled = forms.BooleanField( + label=_('Enable application'), + required=False) diff --git a/plinth/views.py b/plinth/views.py index a5b9a7680..47f7518c8 100644 --- a/plinth/views.py +++ b/plinth/views.py @@ -19,17 +19,101 @@ Main Plinth views """ +from django.contrib import messages +from django.core.exceptions import ImproperlyConfigured from django.core.urlresolvers import reverse from django.http.response import HttpResponseRedirect from django.views.generic import TemplateView +from django.views.generic.edit import FormView +from django.utils.translation import ugettext as _ import time +from . import forms +from . import module_loader + def index(request): """Serve the main index page.""" return HttpResponseRedirect(reverse('apps:index')) +class ConfigurationView(FormView): + """A generic view for configuring simple modules.""" + form_class = forms.ConfigurationForm + module_name = None + + def __init__(self, module_name=None, *args, **kwargs): + """Set the module name on which this configuration view operates.""" + self.instance_module_name = module_name + + def get_module_name(self): + """Return the name of the module associated with the view.""" + if not self.instance_module_name and not self.module_name: + raise ImproperlyConfigured( + 'Using ConfigurationView without the "module_name" class ' + 'attribute or intialization attribute is prohibited.') + else: + return self.instance_module_name or self.module_name + + def get_module(self): + """Return the module associated with the view.""" + return module_loader.loaded_modules[self.get_module_name()] + + def get_initial(self): + """Return the status of the module to fill in the form.""" + return self.get_module().get_status() + + def get_prefix(self): + """Return prefix for form used in the view.""" + return self.get_module_name() + + def get_template_names(self): + """Return the list of template names for the view.""" + return [self.get_module_name() + '.html'] + + def get_context_data(self, **kwargs): + """Return the context data for rendering the template view.""" + if 'title' not in kwargs: + kwargs['title'] = getattr(self.get_module(), 'title', None) + + if 'description' not in kwargs: + kwargs['description'] = \ + getattr(self.get_module(), 'description', None) + + context = super().get_context_data(**kwargs) + + if 'status' not in context: + context['status'] = context['form'].initial + + return context + + def form_valid(self, form): + """Perform operation when the form submission is valid.""" + old_status = form.initial + new_status = form.cleaned_data + + modified = self.apply_changes(old_status, new_status) + if not modified: + messages.info(self.request, _('Setting unchanged')) + + context = self.get_context_data() + return self.render_to_response(context) + + def apply_changes(self, old_status, new_status): + """Apply the changes submitted in the form.""" + if old_status['enabled'] == new_status['enabled']: + return False + + should_enable = new_status['enabled'] + self.get_module().enable(should_enable) + if should_enable: + messages.success(self.request, _('Application enabled')) + else: + messages.success(self.request, _('Application disabled')) + + return True + + class SetupView(TemplateView): """View to prompt and setup applications.""" template_name = 'setup.html'