Add clients to ServiceView

Signed-off-by: Joseph Nuthalapati <njoseph@thoughtworks.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Joseph Nuthalapati 2017-11-03 18:11:38 +05:30 committed by James Valleroy
parent d3cddfa68c
commit efa575b204
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
22 changed files with 224 additions and 177 deletions

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
URLs for the Deluge module. URLs for the Deluge module.
""" """
@ -24,11 +23,12 @@ from django.conf.urls import url
from plinth.modules import deluge from plinth.modules import deluge
from plinth.views import ServiceView from plinth.views import ServiceView
urlpatterns = [ urlpatterns = [
url(r'^apps/deluge/$', ServiceView.as_view( url(r'^apps/deluge/$',
ServiceView.as_view(
description=deluge.description, description=deluge.description,
diagnostics_module_name="deluge", diagnostics_module_name="deluge",
service_id=deluge.managed_services[0] clients=deluge.clients,
), name='index'), service_id=deluge.managed_services[0]),
name='index'),
] ]

View File

@ -70,17 +70,18 @@ class DiasporaServiceView(ServiceView):
def get_context_data(self, *args, **kwargs): def get_context_data(self, *args, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['domain_name'] = diaspora.get_configured_domain_name() context['domain_name'] = diaspora.get_configured_domain_name()
context['clients'] = diaspora.clients
return context return context
def get_initial(self): def get_initial(self):
"""Return the status of the service to fill in the form.""" """Return the status of the service to fill in the form."""
return { return {
'is_enabled': 'is_enabled':
self.service.is_enabled(), self.service.is_enabled(),
'is_user_registrations_enabled': 'is_user_registrations_enabled':
diaspora.is_user_registrations_enabled(), diaspora.is_user_registrations_enabled(),
'is_running': 'is_running':
self.service.is_running() self.service.is_running()
} }
def form_valid(self, form): def form_valid(self, form):

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
Plinth module for configuring ikiwiki Plinth module for configuring ikiwiki
""" """
@ -32,13 +31,16 @@ from plinth.modules import ikiwiki
from .forms import IkiwikiCreateForm from .forms import IkiwikiCreateForm
subsubmenu = [{
subsubmenu = [{'url': reverse_lazy('ikiwiki:index'), 'url': reverse_lazy('ikiwiki:index'),
'text': ugettext_lazy('Configure')}, 'text': ugettext_lazy('Configure')
{'url': reverse_lazy('ikiwiki:manage'), }, {
'text': ugettext_lazy('Manage')}, 'url': reverse_lazy('ikiwiki:manage'),
{'url': reverse_lazy('ikiwiki:create'), 'text': ugettext_lazy('Manage')
'text': ugettext_lazy('Create')}] }, {
'url': reverse_lazy('ikiwiki:create'),
'text': ugettext_lazy('Create')
}]
class IkiwikiServiceView(views.ServiceView): class IkiwikiServiceView(views.ServiceView):
@ -52,6 +54,7 @@ class IkiwikiServiceView(views.ServiceView):
"""Return the context data for rendering the template view.""" """Return the context data for rendering the template view."""
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['subsubmenu'] = subsubmenu context['subsubmenu'] = subsubmenu
context['clients'] = ikiwiki.clients
return context return context
@ -60,10 +63,11 @@ def manage(request):
sites = actions.run('ikiwiki', ['get-sites']).split('\n') sites = actions.run('ikiwiki', ['get-sites']).split('\n')
sites = [name for name in sites if name != ''] sites = [name for name in sites if name != '']
return TemplateResponse(request, 'ikiwiki_manage.html', return TemplateResponse(request, 'ikiwiki_manage.html', {
{'title': _('Manage Wikis and Blogs'), 'title': _('Manage Wikis and Blogs'),
'subsubmenu': subsubmenu, 'subsubmenu': subsubmenu,
'sites': sites}) 'sites': sites
})
def create(request): def create(request):
@ -84,17 +88,21 @@ def create(request):
site = form.cleaned_data['name'].replace(' ', '') site = form.cleaned_data['name'].replace(' ', '')
frontpage.add_shortcut( frontpage.add_shortcut(
'ikiwiki_' + site, site, url='/ikiwiki/' + site, 'ikiwiki_' + site,
login_required=False, icon='ikiwiki') site,
url='/ikiwiki/' + site,
login_required=False,
icon='ikiwiki')
return redirect(reverse_lazy('ikiwiki:manage')) return redirect(reverse_lazy('ikiwiki:manage'))
else: else:
form = IkiwikiCreateForm(prefix='ikiwiki') form = IkiwikiCreateForm(prefix='ikiwiki')
return TemplateResponse(request, 'ikiwiki_create.html', return TemplateResponse(request, 'ikiwiki_create.html', {
{'title': _('Create Wiki or Blog'), 'title': _('Create Wiki or Blog'),
'form': form, 'form': form,
'subsubmenu': subsubmenu}) 'subsubmenu': subsubmenu
})
def _create_wiki(request, name, admin_name, admin_password): def _create_wiki(request, name, admin_name, admin_password):
@ -102,13 +110,12 @@ def _create_wiki(request, name, admin_name, admin_password):
try: try:
actions.superuser_run( actions.superuser_run(
'ikiwiki', 'ikiwiki',
['create-wiki', '--wiki_name', name, ['create-wiki', '--wiki_name', name, '--admin_name', admin_name],
'--admin_name', admin_name],
input=admin_password.encode()) input=admin_password.encode())
messages.success(request, _('Created wiki {name}.').format(name=name)) messages.success(request, _('Created wiki {name}.').format(name=name))
except actions.ActionError as error: except actions.ActionError as error:
messages.error(request, _('Could not create wiki: {error}') messages.error(
.format(error=error)) request, _('Could not create wiki: {error}').format(error=error))
def _create_blog(request, name, admin_name, admin_password): def _create_blog(request, name, admin_name, admin_password):
@ -116,13 +123,12 @@ def _create_blog(request, name, admin_name, admin_password):
try: try:
actions.superuser_run( actions.superuser_run(
'ikiwiki', 'ikiwiki',
['create-blog', '--blog_name', name, ['create-blog', '--blog_name', name, '--admin_name', admin_name],
'--admin_name', admin_name],
input=admin_password.encode()) input=admin_password.encode())
messages.success(request, _('Created blog {name}.').format(name=name)) messages.success(request, _('Created blog {name}.').format(name=name))
except actions.ActionError as error: except actions.ActionError as error:
messages.error(request, _('Could not create blog: {error}') messages.error(
.format(error=error)) request, _('Could not create blog: {error}').format(error=error))
def delete(request, name): def delete(request, name):
@ -137,12 +143,14 @@ def delete(request, name):
messages.success(request, _('{name} deleted.').format(name=name)) messages.success(request, _('{name} deleted.').format(name=name))
frontpage.remove_shortcut('ikiwiki_' + name) frontpage.remove_shortcut('ikiwiki_' + name)
except actions.ActionError as error: except actions.ActionError as error:
messages.error(request, _('Could not delete {name}: {error}') messages.error(request,
.format(name=name, error=error)) _('Could not delete {name}: {error}').format(
name=name, error=error))
return redirect(reverse_lazy('ikiwiki:manage')) return redirect(reverse_lazy('ikiwiki:manage'))
return TemplateResponse(request, 'ikiwiki_delete.html', return TemplateResponse(request, 'ikiwiki_delete.html', {
{'title': _('Delete Wiki or Blog'), 'title': _('Delete Wiki or Blog'),
'subsubmenu': subsubmenu, 'subsubmenu': subsubmenu,
'name': name}) 'name': name
})

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
Plinth module for infinoted. Plinth module for infinoted.
""" """
@ -32,7 +31,6 @@ from plinth.utils import format_lazy
from plinth.views import ServiceView from plinth.views import ServiceView
from .manifest import clients from .manifest import clients
version = 1 version = 1
service = None service = None
@ -47,7 +45,6 @@ short_description = _('Gobby Server')
description = [ description = [
_('infinoted is a server for Gobby, a collaborative text editor.'), _('infinoted is a server for Gobby, a collaborative text editor.'),
format_lazy( format_lazy(
_('To use it, <a href="https://gobby.github.io/">download Gobby</a>, ' _('To use it, <a href="https://gobby.github.io/">download Gobby</a>, '
'desktop client and install it. Then start Gobby and select ' 'desktop client and install it. Then start Gobby and select '
@ -55,21 +52,25 @@ description = [
box_name=_(cfg.box_name)), box_name=_(cfg.box_name)),
] ]
clients = clients clients = clients
def init(): def init():
"""Initialize the infinoted module.""" """Initialize the infinoted module."""
menu = main_menu.get('apps') menu = main_menu.get('apps')
menu.add_urlname(name, 'glyphicon-pencil', 'infinoted:index', short_description) menu.add_urlname(name, 'glyphicon-pencil', 'infinoted:index',
short_description)
global service global service
setup_helper = globals()['setup_helper'] setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup': if setup_helper.get_state() != 'needs-setup':
service = service_module.Service( service = service_module.Service(
managed_services[0], name, ports=['infinoted-plinth'], managed_services[0],
is_external=True, enable=enable, disable=disable) name,
ports=['infinoted-plinth'],
is_external=True,
enable=enable,
disable=disable)
if service.is_enabled(): if service.is_enabled():
add_shortcut() add_shortcut()
@ -79,6 +80,7 @@ class InfinotedServiceView(ServiceView):
service_id = managed_services[0] service_id = managed_services[0]
diagnostics_module_name = "infinoted" diagnostics_module_name = "infinoted"
description = description description = description
clients = clients
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -88,19 +90,26 @@ def setup(helper, old_version=None):
global service global service
if service is None: if service is None:
service = service_module.Service( service = service_module.Service(
managed_services[0], name, ports=['infinoted-plinth'], managed_services[0],
is_external=True, enable=enable, disable=disable) name,
ports=['infinoted-plinth'],
is_external=True,
enable=enable,
disable=disable)
helper.call('post', service.notify_enabled, None, True) helper.call('post', service.notify_enabled, None, True)
helper.call('post', add_shortcut) helper.call('post', add_shortcut)
def add_shortcut(): def add_shortcut():
frontpage.add_shortcut('infinoted', name, frontpage.add_shortcut(
short_description=short_description, url=None, 'infinoted',
details=description, name,
configure_url=reverse_lazy('infinoted:index'), short_description=short_description,
login_required=False) url=None,
details=description,
configure_url=reverse_lazy('infinoted:index'),
login_required=False)
def enable(): def enable():

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
Views for the JSXC module Views for the JSXC module
""" """
@ -33,6 +32,7 @@ class JSXCServiceView(ServiceView):
template_name = 'jsxc.html' template_name = 'jsxc.html'
description = jsxc.description description = jsxc.description
show_status_block = False show_status_block = False
clients = jsxc.clients
class JsxcView(TemplateView): class JsxcView(TemplateView):

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
Views for the Matrix Synapse module. Views for the Matrix Synapse module.
""" """
@ -79,13 +78,15 @@ class MatrixSynapseServiceView(ServiceView):
"""Add additional context data for template.""" """Add additional context data for template."""
context = super().get_context_data(*args, **kwargs) context = super().get_context_data(*args, **kwargs)
context['domain_name'] = matrixsynapse.get_configured_domain_name() context['domain_name'] = matrixsynapse.get_configured_domain_name()
context['clients'] = matrixsynapse.clients
return context return context
def get_initial(self): def get_initial(self):
"""Return the values to fill in the form.""" """Return the values to fill in the form."""
initial = super().get_initial() initial = super().get_initial()
initial.update({ initial.update({
'enable_public_registration': get_public_registration_status()}) 'enable_public_registration': get_public_registration_status()
})
return initial return initial
def form_valid(self, form): def form_valid(self, form):
@ -112,13 +113,13 @@ class MatrixSynapseServiceView(ServiceView):
if not pubreg_same: if not pubreg_same:
# note action public_registration restarts, if running now # note action public_registration restarts, if running now
if new_config['enable_public_registration']: if new_config['enable_public_registration']:
actions.superuser_run('matrixsynapse', ['public_registration', actions.superuser_run('matrixsynapse',
'enable']) ['public_registration', 'enable'])
messages.success(self.request, messages.success(self.request,
_('Public registration enabled')) _('Public registration enabled'))
else: else:
actions.superuser_run('matrixsynapse', ['public_registration', actions.superuser_run('matrixsynapse',
'disable']) ['public_registration', 'disable'])
messages.success(self.request, messages.success(self.request,
_('Public registration disabled')) _('Public registration disabled'))

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
Views for minetest module. Views for minetest module.
""" """
@ -23,20 +22,21 @@ from django.contrib import messages
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from plinth import actions from plinth import actions
from plinth.modules import minetest
from plinth.views import ServiceView from plinth.views import ServiceView
from . import description, managed_services, get_configuration from . import description, managed_services, get_configuration
from .forms import MinetestForm from .forms import MinetestForm
class MinetestServiceView(ServiceView): # pylint: disable=too-many-ancestors class MinetestServiceView(ServiceView): # pylint: disable=too-many-ancestors
"""A specialized view for configuring minetest.""" """A specialized view for configuring minetest."""
service_id = managed_services[0] service_id = managed_services[0]
diagnostics_module_name = "minetest" diagnostics_module_name = "minetest"
description = description description = description
show_status_block = True show_status_block = True
form_class = MinetestForm form_class = MinetestForm
clients = minetest.clients
def get_initial(self): def get_initial(self):
"""Return the values to fill in the form.""" """Return the values to fill in the form."""
@ -51,34 +51,30 @@ class MinetestServiceView(ServiceView): # pylint: disable=too-many-ancestors
if old_config['max_players'] != data['max_players'] \ if old_config['max_players'] != data['max_players'] \
and data['max_players'] != None: and data['max_players'] != None:
actions.superuser_run( actions.superuser_run('minetest', [
'minetest', 'configure', '--max_players',
['configure', '--max_players', str(data['max_players'])]) str(data['max_players'])
])
messages.success(self.request, messages.success(self.request,
_('Maximum players configuration updated')) _('Maximum players configuration updated'))
if old_config['creative_mode'] != data['creative_mode']: if old_config['creative_mode'] != data['creative_mode']:
value = 'true' if data['creative_mode'] else 'false' value = 'true' if data['creative_mode'] else 'false'
actions.superuser_run( actions.superuser_run('minetest',
'minetest', ['configure', '--creative_mode', value])
['configure', '--creative_mode', value])
messages.success(self.request, messages.success(self.request,
_('Creative mode configuration updated')) _('Creative mode configuration updated'))
if old_config['enable_pvp'] != data['enable_pvp']: if old_config['enable_pvp'] != data['enable_pvp']:
value = 'true' if data['enable_pvp'] else 'false' value = 'true' if data['enable_pvp'] else 'false'
actions.superuser_run( actions.superuser_run('minetest',
'minetest', ['configure', '--enable_pvp', value])
['configure', '--enable_pvp', value]) messages.success(self.request, _('PVP configuration updated'))
messages.success(self.request,
_('PVP configuration updated'))
if old_config['enable_damage'] != data['enable_damage']: if old_config['enable_damage'] != data['enable_damage']:
value = 'true' if data['enable_damage'] else 'false' value = 'true' if data['enable_damage'] else 'false'
actions.superuser_run( actions.superuser_run('minetest',
'minetest', ['configure', '--enable_damage', value])
['configure', '--enable_damage', value]) messages.success(self.request, _('Damage configuration updated'))
messages.success(self.request,
_('Damage configuration updated'))
return super().form_valid(form) return super().form_valid(form)

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
Plinth module to configure Mumble server Plinth module to configure Mumble server
""" """
@ -30,7 +29,6 @@ from plinth.menu import main_menu
from plinth.views import ServiceView from plinth.views import ServiceView
from .manifest import clients from .manifest import clients
version = 1 version = 1
name = _('Mumble') name = _('Mumble')
@ -46,7 +44,6 @@ managed_packages = ['mumble-server']
description = [ description = [
_('Mumble is an open source, low-latency, encrypted, high quality ' _('Mumble is an open source, low-latency, encrypted, high quality '
'voice chat software.'), 'voice chat software.'),
_('You can connect to your Mumble server on the regular Mumble port ' _('You can connect to your Mumble server on the regular Mumble port '
'64738. <a href="http://mumble.info">Clients</a> to connect to Mumble ' '64738. <a href="http://mumble.info">Clients</a> to connect to Mumble '
'from your desktop and Android devices are available.') 'from your desktop and Android devices are available.')
@ -60,15 +57,19 @@ reserved_usernames = ['mumble-server']
def init(): def init():
"""Intialize the Mumble module.""" """Intialize the Mumble module."""
menu = main_menu.get('apps') menu = main_menu.get('apps')
menu.add_urlname(name, 'glyphicon-headphones', 'mumble:index', short_description) menu.add_urlname(name, 'glyphicon-headphones', 'mumble:index',
short_description)
global service global service
setup_helper = globals()['setup_helper'] setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup': if setup_helper.get_state() != 'needs-setup':
service = service_module.Service( service = service_module.Service(
managed_services[0], name, ports=['mumble-plinth'], managed_services[0],
name,
ports=['mumble-plinth'],
is_external=True, is_external=True,
enable=enable, disable=disable) enable=enable,
disable=disable)
if service.is_enabled(): if service.is_enabled():
add_shortcut() add_shortcut()
@ -78,6 +79,7 @@ class MumbleServiceView(ServiceView):
service_id = managed_services[0] service_id = managed_services[0]
diagnostics_module_name = "mumble" diagnostics_module_name = "mumble"
description = description description = description
clients = clients
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -86,19 +88,24 @@ def setup(helper, old_version=None):
global service global service
if service is None: if service is None:
service = service_module.Service( service = service_module.Service(
managed_services[0], name, ports=['mumble-plinth'], managed_services[0],
name,
ports=['mumble-plinth'],
is_external=True, is_external=True,
enable=enable, disable=disable) enable=enable,
disable=disable)
helper.call('post', service.notify_enabled, None, True) helper.call('post', service.notify_enabled, None, True)
helper.call('post', add_shortcut) helper.call('post', add_shortcut)
def add_shortcut(): def add_shortcut():
frontpage.add_shortcut('mumble', name, frontpage.add_shortcut(
short_description=short_description, 'mumble',
details=description, name,
configure_url=reverse_lazy('mumble:index'), short_description=short_description,
login_required=False) details=description,
configure_url=reverse_lazy('mumble:index'),
login_required=False)
def enable(): def enable():

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
Plinth module for Quassel. Plinth module for Quassel.
""" """
@ -52,8 +51,8 @@ description = [
'the client is disconnected. {box_name} can run the Quassel ' 'the client is disconnected. {box_name} can run the Quassel '
'core service keeping you always online and one or more Quassel ' 'core service keeping you always online and one or more Quassel '
'clients from a desktop or a mobile can be used to connect and ' 'clients from a desktop or a mobile can be used to connect and '
'disconnect from it.'), box_name=_(cfg.box_name)), 'disconnect from it.'),
box_name=_(cfg.box_name)),
_('You can connect to your Quassel core on the default Quassel port ' _('You can connect to your Quassel core on the default Quassel port '
'4242. Clients to connect to Quassel from your ' '4242. Clients to connect to Quassel from your '
'<a href="http://quassel-irc.org/downloads">desktop</a> and ' '<a href="http://quassel-irc.org/downloads">desktop</a> and '
@ -69,14 +68,19 @@ reserved_usernames = ['quasselcore']
def init(): def init():
"""Initialize the quassel module.""" """Initialize the quassel module."""
menu = main_menu.get('apps') menu = main_menu.get('apps')
menu.add_urlname(name, 'glyphicon-retweet', 'quassel:index', short_description) menu.add_urlname(name, 'glyphicon-retweet', 'quassel:index',
short_description)
global service global service
setup_helper = globals()['setup_helper'] setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup': if setup_helper.get_state() != 'needs-setup':
service = service_module.Service( service = service_module.Service(
managed_services[0], name, ports=['quassel-plinth'], managed_services[0],
is_external=True, enable=enable, disable=disable) name,
ports=['quassel-plinth'],
is_external=True,
enable=enable,
disable=disable)
if service.is_enabled(): if service.is_enabled():
add_shortcut() add_shortcut()
@ -86,6 +90,7 @@ class QuasselServiceView(ServiceView):
service_id = managed_services[0] service_id = managed_services[0]
diagnostics_module_name = "quassel" diagnostics_module_name = "quassel"
description = description description = description
clients = clients
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -94,18 +99,24 @@ def setup(helper, old_version=None):
global service global service
if service is None: if service is None:
service = service_module.Service( service = service_module.Service(
managed_services[0], name, ports=['quassel-plinth'], managed_services[0],
is_external=True, enable=enable, disable=disable) name,
ports=['quassel-plinth'],
is_external=True,
enable=enable,
disable=disable)
helper.call('post', service.notify_enabled, None, True) helper.call('post', service.notify_enabled, None, True)
helper.call('post', add_shortcut) helper.call('post', add_shortcut)
def add_shortcut(): def add_shortcut():
frontpage.add_shortcut('quassel', name, frontpage.add_shortcut(
short_description=short_description, 'quassel',
details=description, name,
configure_url=reverse_lazy('quassel:index'), short_description=short_description,
login_required=True) details=description,
configure_url=reverse_lazy('quassel:index'),
login_required=True)
def enable(): def enable():

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
Views for radicale module. Views for radicale module.
""" """
@ -23,6 +22,7 @@ from django.contrib import messages
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from plinth import actions from plinth import actions
from plinth.modules import radicale
from plinth.views import ServiceView from plinth.views import ServiceView
from . import description, get_rights_value, managed_services from . import description, get_rights_value, managed_services
@ -31,10 +31,11 @@ from .forms import RadicaleForm
class RadicaleServiceView(ServiceView): class RadicaleServiceView(ServiceView):
"""A specialized view for configuring radicale service.""" """A specialized view for configuring radicale service."""
service_id = managed_services[0] clients = radicale.clients
form_class = RadicaleForm
diagnostics_module_name = 'radicale'
description = description description = description
diagnostics_module_name = 'radicale'
form_class = RadicaleForm
service_id = managed_services[0]
def get_initial(self): def get_initial(self):
"""Return the values to fill in the form.""" """Return the values to fill in the form."""
@ -46,9 +47,9 @@ class RadicaleServiceView(ServiceView):
"""Change the access control of Radicale service.""" """Change the access control of Radicale service."""
data = form.cleaned_data data = form.cleaned_data
if get_rights_value() != data['access_rights']: if get_rights_value() != data['access_rights']:
actions.superuser_run( actions.superuser_run('radicale', [
'radicale', 'configure', '--rights_type', data['access_rights']
['configure', '--rights_type', data['access_rights']]) ])
messages.success(self.request, messages.success(self.request,
_('Access rights configuration updated')) _('Access rights configuration updated'))
return super().form_valid(form) return super().form_valid(form)

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
Plinth module for repro. Plinth module for repro.
""" """
@ -47,12 +46,10 @@ description = [
'can use to let their presence known. It also acts as a proxy to ' 'can use to let their presence known. It also acts as a proxy to '
'federate SIP communications to other servers on the Internet similar ' 'federate SIP communications to other servers on the Internet similar '
'to email.'), 'to email.'),
_('To make SIP calls, a client application is needed. Available clients ' _('To make SIP calls, a client application is needed. Available clients '
'include <a href="https://jitsi.org/">Jitsi</a> (for computers) and ' 'include <a href="https://jitsi.org/">Jitsi</a> (for computers) and '
'<a href="https://f-droid.org/repository/browse/?fdid=com.csipsimple"> ' '<a href="https://f-droid.org/repository/browse/?fdid=com.csipsimple"> '
'CSipSimple</a> (for Android phones).'), 'CSipSimple</a> (for Android phones).'),
_('<strong>Note:</strong> Before using repro, domains and users will ' _('<strong>Note:</strong> Before using repro, domains and users will '
'need to be configured using the <a href="/repro/domains.html">' 'need to be configured using the <a href="/repro/domains.html">'
'web-based configuration panel</a>. Users in the <em>admin</em> group ' 'web-based configuration panel</a>. Users in the <em>admin</em> group '
@ -71,24 +68,29 @@ service = None
def init(): def init():
"""Initialize the repro module.""" """Initialize the repro module."""
menu = main_menu.get('apps') menu = main_menu.get('apps')
menu.add_urlname(name, 'glyphicon-phone-alt', 'repro:index', short_description) menu.add_urlname(name, 'glyphicon-phone-alt', 'repro:index',
short_description)
global service global service
setup_helper = globals()['setup_helper'] setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup': if setup_helper.get_state() != 'needs-setup':
service = service_module.Service( service = service_module.Service(
managed_services[0], name, managed_services[0],
name,
ports=['sip', 'sips', 'rtp-plinth'], ports=['sip', 'sips', 'rtp-plinth'],
is_external=True, enable=enable, disable=disable) is_external=True,
enable=enable,
disable=disable)
if service.is_enabled(): if service.is_enabled():
add_shortcut() add_shortcut()
class ReproServiceView(ServiceView): class ReproServiceView(ServiceView):
service_id = managed_services[0] clients = clients
diagnostics_module_name = "repro"
description = description description = description
diagnostics_module_name = "repro"
service_id = managed_services[0]
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -98,19 +100,24 @@ def setup(helper, old_version=None):
global service global service
if service is None: if service is None:
service = service_module.Service( service = service_module.Service(
managed_services[0], name, managed_services[0],
name,
ports=['sip', 'sips', 'rtp-plinth'], ports=['sip', 'sips', 'rtp-plinth'],
is_external=True, enable=enable, disable=disable) is_external=True,
enable=enable,
disable=disable)
helper.call('post', service.notify_enabled, None, True) helper.call('post', service.notify_enabled, None, True)
helper.call('post', add_shortcut) helper.call('post', add_shortcut)
def add_shortcut(): def add_shortcut():
frontpage.add_shortcut('repro', name, frontpage.add_shortcut(
short_description=short_description, 'repro',
details=description, name,
configure_url=reverse_lazy('repro:index'), short_description=short_description,
login_required=True) details=description,
configure_url=reverse_lazy('repro:index'),
login_required=True)
def enable(): def enable():

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
URLs for the reStore module. URLs for the reStore module.
""" """
@ -24,10 +23,11 @@ from django.conf.urls import url
from plinth.views import ServiceView from plinth.views import ServiceView
from plinth.modules import restore from plinth.modules import restore
urlpatterns = [ urlpatterns = [
url(r'^apps/restore/$', ServiceView.as_view( url(r'^apps/restore/$',
ServiceView.as_view(
service_id=restore.managed_services[0], service_id=restore.managed_services[0],
description=restore.description description=restore.description,
), name='index'), clients=restore.clients),
name='index'),
] ]

View File

@ -29,6 +29,7 @@ urlpatterns = [
service_id=syncthing.managed_services[0], service_id=syncthing.managed_services[0],
diagnostics_module_name='syncthing', diagnostics_module_name='syncthing',
description=syncthing.description, description=syncthing.description,
clients=syncthing.clients,
show_status_block=True), show_status_block=True),
name='index'), name='index'),
] ]

View File

@ -32,6 +32,8 @@
{% block configuration %} {% block configuration %}
{% include "clients.html" with clients=clients %}
<h3>{% trans "Status" %}</h3> <h3>{% trans "Status" %}</h3>
{% if config_running %} {% if config_running %}

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
Plinth module for configuring Tor. Plinth module for configuring Tor.
""" """
@ -28,7 +27,6 @@ from plinth import actions
from plinth.errors import ActionError from plinth.errors import ActionError
from plinth.modules import tor from plinth.modules import tor
config_process = None config_process = None
@ -50,12 +48,14 @@ def index(request):
else: else:
form = TorForm(initial=status, prefix='tor') form = TorForm(initial=status, prefix='tor')
return TemplateResponse(request, 'tor.html', return TemplateResponse(request, 'tor.html', {
{'title': tor.name, 'title': tor.name,
'description': tor.description, 'description': tor.description,
'status': status, 'clients': tor.clients,
'config_running': bool(config_process), 'status': status,
'form': form}) 'config_running': bool(config_process),
'form': form
})
def _apply_changes(request, old_status, new_status): def _apply_changes(request, old_status, new_status):
@ -63,8 +63,10 @@ def _apply_changes(request, old_status, new_status):
try: try:
__apply_changes(request, old_status, new_status) __apply_changes(request, old_status, new_status)
except ActionError as exception: except ActionError as exception:
messages.error(request, _('Action error: {0} [{1}] [{2}]').format( messages.error(request,
exception.args[0], exception.args[1], exception.args[2])) _('Action error: {0} [{1}] [{2}]').format(
exception.args[0], exception.args[1],
exception.args[2]))
def __apply_changes(request, old_status, new_status): def __apply_changes(request, old_status, new_status):
@ -111,8 +113,8 @@ def __apply_changes(request, old_status, new_status):
needs_restart = True needs_restart = True
if old_status['upstream_bridges'] != new_status['upstream_bridges']: if old_status['upstream_bridges'] != new_status['upstream_bridges']:
arguments.extend(['--upstream-bridges', arguments.extend(
new_status['upstream_bridges']]) ['--upstream-bridges', new_status['upstream_bridges']])
needs_restart = True needs_restart = True
if old_status['enabled'] != new_status['enabled']: if old_status['enabled'] != new_status['enabled']:

View File

@ -34,6 +34,7 @@ logger = logging.getLogger(__name__)
class TransmissionServiceView(views.ServiceView): class TransmissionServiceView(views.ServiceView):
"""Serve configuration page.""" """Serve configuration page."""
clients = transmission.clients
description = transmission.description description = transmission.description
diagnostics_module_name = 'transmission' diagnostics_module_name = 'transmission'
form_class = TransmissionForm form_class = TransmissionForm

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
""" """
URLs for the Tiny Tiny RSS module. URLs for the Tiny Tiny RSS module.
""" """
@ -24,12 +23,13 @@ from django.conf.urls import url
from plinth.views import ServiceView from plinth.views import ServiceView
from plinth.modules import ttrss from plinth.modules import ttrss
urlpatterns = [ urlpatterns = [
url(r'^apps/ttrss/$', ServiceView.as_view( url(r'^apps/ttrss/$',
service_id=ttrss.managed_services[0], ServiceView.as_view(
diagnostics_module_name="ttrss", service_id=ttrss.managed_services[0],
description=ttrss.description, diagnostics_module_name="ttrss",
show_status_block=True description=ttrss.description,
), name='index'), clients=ttrss.clients,
show_status_block=True),
name='index'),
] ]

View File

@ -20,18 +20,20 @@
{% load i18n %} {% load i18n %}
{% load plinth_extras %} {% load plinth_extras %}
{% if module.clients %} {% if clients %}
<button type="button" class="btn btn-primary collapsed" <p>
data-toggle="collapse" data-target="#clients"> <button type="button" class="btn btn-default collapsed"
Client Apps data-toggle="collapse" data-target="#clients">
</button> Client Apps
</button>
</p>
<div id="clients" class="collapse"> <div id="clients" class="collapse">
{% if module.clients|has_web_clients %} {% if clients|has_web_clients %}
<div class="clients-info"> <div class="clients-info">
<p class="heading">{% trans "Web Clients" %}: <p class="heading">{% trans "Web Clients" %}:
<ul> <ul>
{% for client in module.clients %} {% for client in clients %}
{% if client|has_web_clients %} {% if client|has_web_clients %}
{% for platform in client.platforms %} {% for platform in client.platforms %}
{% if platform.type == 'web' %} {% if platform.type == 'web' %}
@ -46,12 +48,12 @@
</div> </div>
{% endif %} {% endif %}
{% if module.clients|has_desktop_clients %} {% if clients|has_desktop_clients %}
<div class="clients-info"> <div class="clients-info">
{% load static %} {% load static %}
<p class="heading">{% trans "Desktop Clients" %}: <p class="heading">{% trans "Desktop Clients" %}:
<ul> <ul>
{% for client in module.clients %} {% for client in clients %}
{% if client|has_desktop_clients %} {% if client|has_desktop_clients %}
<li class="col-md-12 col-xs-12"> <span> {{ client.name }} </span> </li> <li class="col-md-12 col-xs-12"> <span> {{ client.name }} </span> </li>
<div class ="row"> <div class ="row">
@ -77,12 +79,12 @@
</div> </div>
{% endif %} {% endif %}
{% if module.clients|has_mobile_clients %} {% if clients|has_mobile_clients %}
<div class="clients-info"> <div class="clients-info">
{% load static %} {% load static %}
<p class="heading">{% trans "Mobile Clients" %}:</p> <p class="heading">{% trans "Mobile Clients" %}:</p>
<ul> <ul>
{% for client in module.clients %} {% for client in clients %}
{% if client|has_mobile_clients %} {% if client|has_mobile_clients %}
<li class="col-md-12 col-xs-12"><span>{{ client.name }}</span></li> <li class="col-md-12 col-xs-12"><span>{{ client.name }}</span></li>
<div class="row"> <div class="row">

View File

@ -34,6 +34,8 @@
{% endfor %} {% endfor %}
{% endblock %} {% endblock %}
{% include "clients.html" with clients=clients %}
{% block status %} {% block status %}
{% if show_status_block %} {% if show_status_block %}
<h3>{% trans "Status" %}</h3> <h3>{% trans "Status" %}</h3>
@ -75,7 +77,3 @@
{% endblock %} {% endblock %}
{% endblock %} {% endblock %}
<!-- TODO Must get a handle to the clients here somehow -->
{% include "clients.html" with clients=service.clients %}

View File

@ -38,6 +38,8 @@
<p>{{ paragraph|safe }}</p> <p>{{ paragraph|safe }}</p>
{% endfor %} {% endfor %}
{% include "clients.html" with clients=setup_helper.module.clients %}
{% if not setup_helper.current_operation %} {% if not setup_helper.current_operation %}
{% if setup_helper.get_state == 'needs-setup' %} {% if setup_helper.get_state == 'needs-setup' %}
@ -119,6 +121,5 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% include "clients.html" with module=setup_helper.module %}
{% endblock %} {% endblock %}

View File

@ -65,9 +65,7 @@ def system_index(request):
class ServiceView(FormView): class ServiceView(FormView):
"""A generic view for configuring simple services.""" """A generic view for configuring simple services."""
service_id = None clients = []
form_class = forms.ServiceForm
template_name = 'service.html'
# Set diagnostics_module_name to the module name to show diagnostics button # Set diagnostics_module_name to the module name to show diagnostics button
diagnostics_module_name = "" diagnostics_module_name = ""
# List of paragraphs describing the service # List of paragraphs describing the service
@ -75,7 +73,10 @@ class ServiceView(FormView):
# Display the 'status' block of the service.html template # Display the 'status' block of the service.html template
# This block uses information from service.is_running. This method is # This block uses information from service.is_running. This method is
# optional, so allow not showing this block here. # optional, so allow not showing this block here.
form_class = forms.ServiceForm
show_status_block = True show_status_block = True
service_id = None
template_name = 'service.html'
@property @property
def success_url(self): def success_url(self):
@ -126,10 +127,9 @@ class ServiceView(FormView):
"""Add service to the context data.""" """Add service to the context data."""
context = super().get_context_data(*args, **kwargs) context = super().get_context_data(*args, **kwargs)
context['service'] = self.service context['service'] = self.service
if self.diagnostics_module_name: context['clients'] = self.clients
context['diagnostics_module_name'] = self.diagnostics_module_name context['diagnostics_module_name'] = self.diagnostics_module_name
if self.description: context['description'] = self.description
context['description'] = self.description
context['show_status_block'] = self.show_status_block context['show_status_block'] = self.show_status_block
return context return context

View File

@ -125,7 +125,6 @@ footer license-info p{
} }
.clients-info li { .clients-info li {
float: left;
padding-left: 15px; padding-left: 15px;
padding-bottom: 5px; padding-bottom: 5px;
} }