From 3eb7dd914ae520e6f937c3e1b405a2ed6da82a7d Mon Sep 17 00:00:00 2001 From: James Valleroy Date: Mon, 29 Aug 2016 22:46:26 -0400 Subject: [PATCH] Add basic front page with shortcuts to web apps --- plinth/frontpage.py | 42 +++++++++++ plinth/modules/deluge/__init__.py | 11 +++ plinth/modules/ikiwiki/__init__.py | 11 +++ plinth/modules/roundcube/__init__.py | 12 ++++ plinth/modules/shaarli/__init__.py | 11 +++ plinth/modules/transmission/__init__.py | 12 ++++ plinth/modules/ttrss/__init__.py | 11 +++ plinth/modules/xmpp/__init__.py | 11 +++ plinth/templates/base.html | 8 ++- plinth/templates/index.html | 96 +++++++++++++++++++++++++ plinth/views.py | 11 +-- 11 files changed, 229 insertions(+), 7 deletions(-) create mode 100644 plinth/frontpage.py create mode 100644 plinth/templates/index.html diff --git a/plinth/frontpage.py b/plinth/frontpage.py new file mode 100644 index 000000000..7e149dbb8 --- /dev/null +++ b/plinth/frontpage.py @@ -0,0 +1,42 @@ +# +# 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 . +# + +""" +Manage application shortcuts on front page. +""" + +shortcuts = {} + + +def get_shortcuts(): + """Return menu items in sorted order according to current locale.""" + return sorted(shortcuts.values(), key=lambda x: x['label']) + + +def add_shortcut(app, label, url, icon): + """Add shortcut to front page.""" + shortcuts[app] = { + 'label': label, + 'url': url, + 'icon': icon, + } + + +def remove_shortcut(app): + """Remove shortcut from front page.""" + if app in shortcuts: + del shortcuts[app] diff --git a/plinth/modules/deluge/__init__.py b/plinth/modules/deluge/__init__.py index 620617c5e..dcda57808 100644 --- a/plinth/modules/deluge/__init__.py +++ b/plinth/modules/deluge/__init__.py @@ -24,6 +24,7 @@ from django.utils.translation import ugettext_lazy as _ from plinth import actions from plinth import action_utils from plinth import cfg +from plinth import frontpage from plinth import service as service_module @@ -59,12 +60,20 @@ def init(): managed_services[0], title, ports=['http', 'https'], is_external=True, is_enabled=is_enabled, enable=enable, disable=disable) + if is_enabled(): + add_shortcut() + def setup(helper, old_version=None): """Install and configure the module.""" helper.install(managed_packages) helper.call('post', actions.superuser_run, 'deluge', ['enable']) helper.call('post', service.notify_enabled, None, True) + helper.call('post', add_shortcut) + + +def add_shortcut(): + frontpage.add_shortcut('deluge', title, '/deluge', 'glyphicon-magnet') def is_enabled(): @@ -76,11 +85,13 @@ def is_enabled(): def enable(): """Enable the module.""" actions.superuser_run('deluge', ['enable']) + add_shortcut() def disable(): """Disable the module.""" actions.superuser_run('deluge', ['disable']) + frontpage.remove_shortcut('deluge') def diagnose(): diff --git a/plinth/modules/ikiwiki/__init__.py b/plinth/modules/ikiwiki/__init__.py index 9e65c961a..1c9b6c3ed 100644 --- a/plinth/modules/ikiwiki/__init__.py +++ b/plinth/modules/ikiwiki/__init__.py @@ -24,6 +24,7 @@ from django.utils.translation import ugettext_lazy as _ from plinth import actions from plinth import action_utils from plinth import cfg +from plinth import frontpage from plinth import service as service_module @@ -58,12 +59,20 @@ def init(): 'ikiwiki', title, ports=['http', 'https'], is_external=True, is_enabled=is_enabled, enable=enable, disable=disable) + if is_enabled(): + add_shortcut() + def setup(helper, old_version=None): """Install and configure the module.""" helper.install(managed_packages) helper.call('post', actions.superuser_run, 'ikiwiki', ['setup']) helper.call('post', service.notify_enabled, None, True) + helper.call('post', add_shortcut) + + +def add_shortcut(): + frontpage.add_shortcut('ikiwiki', title, '/ikiwiki', 'glyphicon-edit') def is_enabled(): @@ -74,11 +83,13 @@ def is_enabled(): def enable(): """Enable the module.""" actions.superuser_run('ikiwiki', ['enable']) + add_shortcut() def disable(): """Enable the module.""" actions.superuser_run('ikiwiki', ['disable']) + frontpage.remove_shortcut('ikiwiki') def diagnose(): diff --git a/plinth/modules/roundcube/__init__.py b/plinth/modules/roundcube/__init__.py index d924cf1b0..7c0886483 100644 --- a/plinth/modules/roundcube/__init__.py +++ b/plinth/modules/roundcube/__init__.py @@ -24,6 +24,7 @@ from django.utils.translation import ugettext_lazy as _ from plinth import actions from plinth import action_utils from plinth import cfg +from plinth import frontpage from plinth import service as service_module @@ -70,12 +71,21 @@ def init(): 'roundcube', title, ports=['http', 'https'], is_external=True, is_enabled=is_enabled, enable=enable, disable=disable) + if is_enabled(): + add_shortcut() + def setup(helper, old_version=None): """Install and configure the module.""" helper.call('pre', actions.superuser_run, 'roundcube', ['pre-install']) helper.install(managed_packages) helper.call('post', actions.superuser_run, 'roundcube', ['setup']) + helper.call('post', add_shortcut) + + +def add_shortcut(): + frontpage.add_shortcut( + 'roundcube', title, '/roundcube', 'glyphicon-envelope') def is_enabled(): @@ -86,11 +96,13 @@ def is_enabled(): def enable(): """Enable the module.""" actions.superuser_run('roundcube', ['enable']) + add_shortcut() def disable(): """Enable the module.""" actions.superuser_run('roundcube', ['disable']) + frontpage.remove_shortcut('roundcube') def diagnose(): diff --git a/plinth/modules/shaarli/__init__.py b/plinth/modules/shaarli/__init__.py index 70f182410..2c1f51112 100644 --- a/plinth/modules/shaarli/__init__.py +++ b/plinth/modules/shaarli/__init__.py @@ -24,6 +24,7 @@ from django.utils.translation import ugettext_lazy as _ from plinth import actions from plinth import action_utils from plinth import cfg +from plinth import frontpage from plinth import service as service_module @@ -57,11 +58,19 @@ def init(): 'shaarli', title, ports=['http', 'https'], is_external=True, is_enabled=is_enabled, enable=enable, disable=disable) + if is_enabled(): + add_shortcut() + def setup(helper, old_version=None): """Install and configure the module.""" helper.install(managed_packages) helper.call('post', service.notify_enabled, None, True) + helper.call('post', add_shortcut) + + +def add_shortcut(): + frontpage.add_shortcut('shaarli', title, '/shaarli', 'glyphicon-bookmark') def is_enabled(): @@ -72,8 +81,10 @@ def is_enabled(): def enable(): """Enable the module.""" actions.superuser_run('shaarli', ['enable']) + add_shortcut() def disable(): """Enable the module.""" actions.superuser_run('shaarli', ['disable']) + frontpage.remove_shortcut('shaarli') diff --git a/plinth/modules/transmission/__init__.py b/plinth/modules/transmission/__init__.py index 3a5a02a0c..fa9e9f34a 100644 --- a/plinth/modules/transmission/__init__.py +++ b/plinth/modules/transmission/__init__.py @@ -25,6 +25,7 @@ import json from plinth import actions from plinth import action_utils from plinth import cfg +from plinth import frontpage from plinth import service as service_module @@ -58,6 +59,9 @@ def init(): managed_services[0], title, ports=['http', 'https'], is_external=True, is_enabled=is_enabled, enable=enable, disable=disable) + if is_enabled(): + add_shortcut() + def setup(helper, old_version=None): """Install and configure the module.""" @@ -70,6 +74,12 @@ def setup(helper, old_version=None): helper.call('post', actions.superuser_run, 'transmission', ['enable']) helper.call('post', service.notify_enabled, None, True) + helper.call('post', add_shortcut) + + +def add_shortcut(): + frontpage.add_shortcut( + 'transmission', title, '/transmission', 'glyphicon-save') def is_enabled(): @@ -81,11 +91,13 @@ def is_enabled(): def enable(): """Enable the module.""" actions.superuser_run('transmission', ['enable']) + add_shortcut() def disable(): """Enable the module.""" actions.superuser_run('transmission', ['disable']) + frontpage.remove_shortcut('transmission') def diagnose(): diff --git a/plinth/modules/ttrss/__init__.py b/plinth/modules/ttrss/__init__.py index 1bcda91c5..98a8b9007 100644 --- a/plinth/modules/ttrss/__init__.py +++ b/plinth/modules/ttrss/__init__.py @@ -24,6 +24,7 @@ from django.utils.translation import ugettext_lazy as _ from plinth import actions from plinth import action_utils from plinth import cfg +from plinth import frontpage from plinth import service as service_module @@ -59,6 +60,9 @@ def init(): managed_services[0], title, ports=['http', 'https'], is_external=True, is_enabled=is_enabled, enable=enable, disable=disable) + if is_enabled(): + add_shortcut() + def setup(helper, old_version=None): """Install and configure the module.""" @@ -66,6 +70,11 @@ def setup(helper, old_version=None): helper.install(managed_packages) helper.call('post', actions.superuser_run, 'ttrss', ['setup']) helper.call('post', service.notify_enabled, None, True) + helper.call('post', add_shortcut) + + +def add_shortcut(): + frontpage.add_shortcut('ttrss', title, '/tt-rss', 'glyphicon-envelope') def is_enabled(): @@ -77,11 +86,13 @@ def is_enabled(): def enable(): """Enable the module.""" actions.superuser_run('ttrss', ['enable']) + add_shortcut() def disable(): """Enable the module.""" actions.superuser_run('ttrss', ['disable']) + frontpage.remove_shortcut('ttrss') def diagnose(): diff --git a/plinth/modules/xmpp/__init__.py b/plinth/modules/xmpp/__init__.py index cb36ea49a..9fa650509 100644 --- a/plinth/modules/xmpp/__init__.py +++ b/plinth/modules/xmpp/__init__.py @@ -26,6 +26,7 @@ import socket from plinth import actions from plinth import action_utils from plinth import cfg +from plinth import frontpage from plinth import service as service_module from plinth.views import ServiceView from plinth.signals import pre_hostname_change, post_hostname_change @@ -72,6 +73,9 @@ def init(): post_hostname_change.connect(on_post_hostname_change) domainname_change.connect(on_domainname_change) + if is_enabled(): + add_shortcut() + def setup(helper, old_version=None): """Install and configure the module.""" @@ -83,6 +87,11 @@ def setup(helper, old_version=None): helper.install(managed_packages) helper.call('post', actions.superuser_run, 'xmpp', ['setup']) helper.call('post', service.notify_enabled, None, True) + helper.call('post', add_shortcut) + + +def add_shortcut(): + frontpage.add_shortcut('xmpp', title, '/jwchat', 'glyphicon-comment') class EjabberdServiceView(ServiceView): @@ -112,11 +121,13 @@ def get_domainname(): def enable(): """Enable the module.""" actions.superuser_run('xmpp', ['enable']) + add_shortcut() def disable(): """Enable the module.""" actions.superuser_run('xmpp', ['disable']) + frontpage.remove_shortcut('xmpp') def on_pre_hostname_change(sender, old_hostname, new_hostname, **kwargs): diff --git a/plinth/templates/base.html b/plinth/templates/base.html index d3f76308d..57ac20e5c 100644 --- a/plinth/templates/base.html +++ b/plinth/templates/base.html @@ -86,11 +86,13 @@ {% block mainmenu_left %} - + {{ box_name }} - - + + {% endblock %} diff --git a/plinth/templates/index.html b/plinth/templates/index.html new file mode 100644 index 000000000..ac11b978d --- /dev/null +++ b/plinth/templates/index.html @@ -0,0 +1,96 @@ +{% 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 i18n %} + +{% block content %} + + {% if shortcuts %} + + {% for shortcut in shortcuts %} + + {% endfor %} + + {% else %} + +

+ {% url 'apps:index' as apps_url %} + {% blocktrans trimmed %} + + Enable some applications to add + shortcuts to this page. + + {% endblocktrans %} +

+ + {% endif %} + +{% endblock %} + + +{% block sidebar %} + +

+ {% blocktrans trimmed %} + Welcome to {{ box_name }}! + {% endblocktrans %} +

+ +

+ {% blocktrans trimmed %} + + {{ box_name }} is a 100% free software self-hosting web server + to deploy social applications on small machines. It provides + online communication tools respecting your privacy and data + ownership. + + {% endblocktrans %} +

+ +

+ {% blocktrans trimmed %} + + More info about {{ box_name }} is available on the + project homepage + and wiki. + + {% endblocktrans %} +

+ +

+ {% blocktrans trimmed %} + + This portal is a part of Plinth, the {{ box_name }} web + interface. Plinth is free software, distributed under the GNU + Affero General Public License, Version 3 or later. + + {% endblocktrans %} +

+ +{% endblock %} diff --git a/plinth/views.py b/plinth/views.py index 2c403afca..0e5d2f6cb 100644 --- a/plinth/views.py +++ b/plinth/views.py @@ -21,20 +21,23 @@ Main Plinth views from django.contrib import messages from django.core.exceptions import ImproperlyConfigured -from django.http.response import HttpResponseRedirect +from django.template.response import TemplateResponse from django.views.generic import TemplateView from django.views.generic.edit import FormView -from django.urls import reverse from django.utils.translation import ugettext as _ +from stronghold.decorators import public import time -from . import forms +from . import forms, frontpage import plinth +@public def index(request): """Serve the main index page.""" - return HttpResponseRedirect(reverse('apps:index')) + return TemplateResponse(request, 'index.html', + {'title': _('FreedomBox'), + 'shortcuts': frontpage.get_shortcuts()}) class ServiceView(FormView):