diff --git a/actions/xmpp b/actions/xmpp
index 15bac053e..996dc7762 100755
--- a/actions/xmpp
+++ b/actions/xmpp
@@ -53,6 +53,9 @@ def parse_arguments():
# Setup jwchat apache conf
subparsers.add_parser('setup', help='Setup jwchat apache conf')
+ subparsers.add_parser('enable', help='Enable XMPP service')
+ subparsers.add_parser('disable', help='Disable XMPP service')
+
# Prepare ejabberd for hostname change
pre_hostname_change = subparsers.add_parser(
'pre-change-hostname',
@@ -123,6 +126,18 @@ def subcommand_setup(_):
webserver_change.enable('jwchat-plinth')
+def subcommand_enable(_):
+ """Enable XMPP service"""
+ action_utils.service_enable('ejabberd')
+ action_utils.webserver_enable('jwchat-plinth')
+
+
+def subcommand_disable(_):
+ """Disable XMPP service"""
+ action_utils.webserver_disable('jwchat-plinth')
+ action_utils.service_disable('ejabberd')
+
+
def subcommand_pre_change_hostname(arguments):
"""Prepare ejabberd for hostname change"""
old_hostname = arguments.old_hostname
diff --git a/plinth/modules/xmpp/__init__.py b/plinth/modules/xmpp/__init__.py
index fdf2c24df..7415e0071 100644
--- a/plinth/modules/xmpp/__init__.py
+++ b/plinth/modules/xmpp/__init__.py
@@ -19,9 +19,85 @@
Plinth module to configure XMPP server
"""
-from . import xmpp
-from .xmpp import init
+from gettext import gettext as _
+
+from plinth import actions
+from plinth import action_utils
+from plinth import cfg
+from plinth import service as service_module
+from plinth.signals import pre_hostname_change, post_hostname_change
+from plinth.signals import domainname_change
-__all__ = ['xmpp', 'init']
depends = ['plinth.modules.apps']
+
+service = None
+
+
+def init():
+ """Initialize the XMPP module"""
+ menu = cfg.main_menu.get('apps:index')
+ menu.add_urlname(_('Chat Server (XMPP)'), 'glyphicon-comment',
+ 'xmpp:index', 40)
+
+ global service
+ service = service_module.Service(
+ 'xmpp', _('Chat Server (XMPP)'),
+ ['xmpp-client', 'xmpp-server', 'xmpp-bosh'],
+ is_external=True, enabled=is_enabled())
+
+ pre_hostname_change.connect(on_pre_hostname_change)
+ post_hostname_change.connect(on_post_hostname_change)
+ domainname_change.connect(on_domainname_change)
+
+
+def is_enabled():
+ """Return whether the module is enabled."""
+ return (action_utils.service_is_enabled('ejabberd') and
+ action_utils.webserver_is_enabled('jwchat-plinth'))
+
+
+def is_running():
+ """Return whether the service is running."""
+ return action_utils.service_is_running('ejabberd')
+
+
+def on_pre_hostname_change(sender, old_hostname, new_hostname, **kwargs):
+ """
+ Backup ejabberd database before hostname is changed.
+ """
+ del sender # Unused
+ del kwargs # Unused
+
+ actions.superuser_run('xmpp',
+ ['pre-change-hostname',
+ '--old-hostname', old_hostname,
+ '--new-hostname', new_hostname])
+
+
+def on_post_hostname_change(sender, old_hostname, new_hostname, **kwargs):
+ """
+ Update ejabberd and jwchat config after hostname is changed.
+ """
+ del sender # Unused
+ del kwargs # Unused
+
+ actions.superuser_run('xmpp',
+ ['change-hostname',
+ '--old-hostname', old_hostname,
+ '--new-hostname', new_hostname],
+ async=True)
+
+
+def on_domainname_change(sender, old_domainname, new_domainname, **kwargs):
+ """
+ Update ejabberd and jwchat config after domain name is changed.
+ """
+ del sender # Unused
+ del old_domainname # Unused
+ del kwargs # Unused
+
+ actions.superuser_run('xmpp',
+ ['change-domainname',
+ '--domainname', new_domainname],
+ async=True)
diff --git a/plinth/modules/xmpp/forms.py b/plinth/modules/xmpp/forms.py
new file mode 100644
index 000000000..d5e223b8c
--- /dev/null
+++ b/plinth/modules/xmpp/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 .
+#
+
+"""
+Forms for configuring XMPP service.
+"""
+
+from django import forms
+from gettext import gettext as _
+
+
+class XmppForm(forms.Form): # pylint: disable=W0232
+ """XMPP configuration form."""
+ enabled = forms.BooleanField(
+ label=_('Enable XMPP'),
+ required=False)
diff --git a/plinth/modules/xmpp/templates/xmpp.html b/plinth/modules/xmpp/templates/xmpp.html
index 7a81d9b8a..112236b0f 100644
--- a/plinth/modules/xmpp/templates/xmpp.html
+++ b/plinth/modules/xmpp/templates/xmpp.html
@@ -22,13 +22,36 @@
{% block content %}
-
XMPP is an open and standardized communication protocol. Here you
- can run and configure your XMPP server, called ejabberd. To actually
- communicate, you can use the web client or any
- other XMPP client .
+Chat Server (XMPP)
+
+XMPP is an open and standardized communication protocol. Here you
+ can run and configure your XMPP server, called ejabberd.
+
+To actually communicate, you can use the web client or
+ any other
+ XMPP client .
Launch web
client
+Status
+
+
+ {% if status.is_running %}
+ ejabberd is running
+ {% else %}
+ ejabberd is not running
+ {% endif %}
+
+
+Configuration
+
+
+
{% endblock %}
diff --git a/plinth/modules/xmpp/urls.py b/plinth/modules/xmpp/urls.py
index b8f0fb608..3a6d5aa1f 100644
--- a/plinth/modules/xmpp/urls.py
+++ b/plinth/modules/xmpp/urls.py
@@ -23,6 +23,6 @@ from django.conf.urls import patterns, url
urlpatterns = patterns( # pylint: disable-msg=C0103
- 'plinth.modules.xmpp.xmpp',
+ 'plinth.modules.xmpp.views',
url(r'^apps/xmpp/$', 'index', name='index'),
)
diff --git a/plinth/modules/xmpp/views.py b/plinth/modules/xmpp/views.py
new file mode 100644
index 000000000..c4d7f2f3b
--- /dev/null
+++ b/plinth/modules/xmpp/views.py
@@ -0,0 +1,95 @@
+#
+# 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 .
+#
+
+"""
+Plinth module to configure XMPP server
+"""
+
+from django.contrib import messages
+from django.template.response import TemplateResponse
+from gettext import gettext as _
+import logging
+import socket
+
+from .forms import XmppForm
+from plinth import actions
+from plinth import package
+from plinth.modules import xmpp
+
+
+logger = logging.getLogger(__name__)
+
+
+def before_install():
+ """Preseed debconf values before the packages are installed."""
+ fqdn = socket.getfqdn()
+ domainname = '.'.join(fqdn.split('.')[1:])
+ logger.info('XMPP service domainname - %s', domainname)
+ actions.superuser_run('xmpp', ['pre-install', '--domainname', domainname])
+
+
+def on_install():
+ """Setup jwchat apache conf"""
+ actions.superuser_run('xmpp', ['setup'])
+
+
+@package.required(['jwchat', 'ejabberd'],
+ before_install=before_install,
+ on_install=on_install)
+def index(request):
+ """Serve configuration page"""
+ status = get_status()
+
+ form = None
+
+ if request.method == 'POST':
+ form = XmppForm(request.POST, prefix='xmpp')
+ if form.is_valid():
+ _apply_changes(request, status, form.cleaned_data)
+ status = get_status()
+ form = XmppForm(initial=status, prefix='xmpp')
+ else:
+ form = XmppForm(initial=status, prefix='xmpp')
+
+ return TemplateResponse(request, 'xmpp.html',
+ {'title': _('Chat Server (XMPP)'),
+ 'status': status,
+ 'form': form})
+
+
+def get_status():
+ """Get the current settings."""
+ status = {'enabled': xmpp.is_enabled(),
+ 'is_running': xmpp.is_running()}
+
+ return status
+
+
+def _apply_changes(request, old_status, new_status):
+ """Apply the changes."""
+ modified = False
+
+ if old_status['enabled'] != new_status['enabled']:
+ sub_command = 'enable' if new_status['enabled'] else 'disable'
+ actions.superuser_run('xmpp', [sub_command])
+ xmpp.service.notify_enabled(None, new_status['enabled'])
+ modified = True
+
+ if modified:
+ messages.success(request, _('Configuration updated'))
+ else:
+ messages.info(request, _('Setting unchanged'))
diff --git a/plinth/modules/xmpp/xmpp.py b/plinth/modules/xmpp/xmpp.py
deleted file mode 100644
index 77bc5d215..000000000
--- a/plinth/modules/xmpp/xmpp.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#
-# 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 .
-#
-
-from django import forms
-from django.contrib import messages
-from django.template.response import TemplateResponse
-from gettext import gettext as _
-import logging
-import socket
-
-from plinth import actions
-from plinth import cfg
-from plinth import package
-from plinth import service
-from plinth.signals import pre_hostname_change, post_hostname_change
-from plinth.signals import domainname_change
-
-
-logger = logging.getLogger(__name__)
-
-
-def init():
- """Initialize the XMPP module"""
- menu = cfg.main_menu.get('apps:index')
- menu.add_urlname('XMPP', 'glyphicon-comment', 'xmpp:index', 40)
-
- service.Service(
- 'xmpp-client', _('Chat Server - client connections'),
- is_external=True, enabled=True)
- service.Service(
- 'xmpp-server', _('Chat Server - server connections'),
- is_external=True, enabled=True)
- service.Service(
- 'xmpp-bosh', _('Chat Server - web interface'), is_external=True,
- enabled=True)
-
- pre_hostname_change.connect(on_pre_hostname_change)
- post_hostname_change.connect(on_post_hostname_change)
- domainname_change.connect(on_domainname_change)
-
-
-def before_install():
- """Preseed debconf values before the packages are installed."""
- fqdn = socket.getfqdn()
- domainname = '.'.join(fqdn.split('.')[1:])
- logger.info('XMPP service domainname - %s', domainname)
- actions.superuser_run('xmpp', ['pre-install', '--domainname', domainname])
-
-
-def on_install():
- """Setup jwchat apache conf"""
- actions.superuser_run('xmpp', ['setup'])
-
-
-@package.required(['jwchat', 'ejabberd'],
- before_install=before_install,
- on_install=on_install)
-def index(request):
- """Serve XMPP page"""
- return TemplateResponse(request, 'xmpp.html',
- {'title': _('XMPP Server')})
-
-
-def on_pre_hostname_change(sender, old_hostname, new_hostname, **kwargs):
- """
- Backup ejabberd database before hostname is changed.
- """
- del sender # Unused
- del kwargs # Unused
-
- actions.superuser_run('xmpp',
- ['pre-change-hostname',
- '--old-hostname', old_hostname,
- '--new-hostname', new_hostname])
-
-
-def on_post_hostname_change(sender, old_hostname, new_hostname, **kwargs):
- """
- Update ejabberd and jwchat config after hostname is changed.
- """
- del sender # Unused
- del kwargs # Unused
-
- actions.superuser_run('xmpp',
- ['change-hostname',
- '--old-hostname', old_hostname,
- '--new-hostname', new_hostname],
- async=True)
-
-
-def on_domainname_change(sender, old_domainname, new_domainname, **kwargs):
- """
- Update ejabberd and jwchat config after domain name is changed.
- """
- del sender # Unused
- del old_domainname # Unused
- del kwargs # Unused
-
- actions.superuser_run('xmpp',
- ['change-domainname',
- '--domainname', new_domainname],
- async=True)