From 20ecdbf08819ce0f1283329ef0dd7c23206dfd52 Mon Sep 17 00:00:00 2001 From: Rahul De Date: Tue, 7 Mar 2017 14:38:54 +0530 Subject: [PATCH] matrixsynapse: Add new plinth module Signed-off-by: Sunil Mohan Adapa --- actions/matrixsynapse | 81 ++++++++++ plinth/modules/matrixsynapse/__init__.py | 149 ++++++++++++++++++ plinth/modules/matrixsynapse/forms.py | 37 +++++ .../templates/matrix-post-setup.html | 39 +++++ .../templates/matrix-pre-setup.html | 62 ++++++++ .../modules/matrixsynapse/tests/__init__.py | 0 plinth/modules/matrixsynapse/urls.py | 31 ++++ plinth/modules/matrixsynapse/views.py | 71 +++++++++ 8 files changed, 470 insertions(+) create mode 100755 actions/matrixsynapse create mode 100644 plinth/modules/matrixsynapse/__init__.py create mode 100644 plinth/modules/matrixsynapse/forms.py create mode 100644 plinth/modules/matrixsynapse/templates/matrix-post-setup.html create mode 100644 plinth/modules/matrixsynapse/templates/matrix-pre-setup.html create mode 100644 plinth/modules/matrixsynapse/tests/__init__.py create mode 100644 plinth/modules/matrixsynapse/urls.py create mode 100644 plinth/modules/matrixsynapse/views.py diff --git a/actions/matrixsynapse b/actions/matrixsynapse new file mode 100755 index 000000000..8df75b3fb --- /dev/null +++ b/actions/matrixsynapse @@ -0,0 +1,81 @@ +#!/usr/bin/python3 +# -*- mode: python -*- +# +# 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 . +# + +""" +Configuration helper for Matrix-Synapse server. +""" +import argparse +import subprocess + +from plinth import action_utils + + +def parse_arguments(): + """Return parsed command line arguments as dictionary""" + parser = argparse.ArgumentParser() + subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') + + # Preseed debconf values before packages are installed. + pre_install = subparsers.add_parser( + 'pre-install', + help='Preseed debconf values before packages are installed.') + + subparsers.add_parser('enable', help='Enable matrix-synapse service') + subparsers.add_parser('disable', help='Disable matrix-synapse service') + setup = subparsers.add_parser('setup', help='Set Domain name for Matrix') + setup.add_argument( + '--domain-name', + help='The domain name that will be used by Matrix Synapse') + + return parser.parse_args() + + +def subcommand_pre_install(_): + subprocess.check_output( + ['debconf-set-selections'], + input=b'matrix-synapse matrix-synapse/report-stats boolean ' + + b'false') + + +def subcommand_setup(arguments): + domain_name = arguments.domain_name + action_utils.dpkg_reconfigure('matrix-synapse', + {'server-name': domain_name}) + + +def subcommand_enable(_): + """Enable service""" + action_utils.service_enable('matrix-synapse') + + +def subcommand_disable(_): + """Disable service""" + action_utils.service_disable('matrix-synapse') + + +def main(): + arguments = parse_arguments() + + sub_command = arguments.subcommand.replace('-', '_') + sub_command_method = globals()['subcommand_' + sub_command] + sub_command_method(arguments) + + +if __name__ == '__main__': + main() diff --git a/plinth/modules/matrixsynapse/__init__.py b/plinth/modules/matrixsynapse/__init__.py new file mode 100644 index 000000000..71682b3c2 --- /dev/null +++ b/plinth/modules/matrixsynapse/__init__.py @@ -0,0 +1,149 @@ +# +# 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 matrix-synapse server +""" + +import logging +import os + +from django.urls import reverse_lazy +from django.utils.translation import ugettext_lazy as _ +from ruamel.yaml.util import load_yaml_guess_indent + +from plinth import action_utils +from plinth import actions +from plinth import cfg +from plinth import frontpage +from plinth import service as service_module +from plinth.modules import names + +version = 1 + +depends = ['apps'] + +managed_services = ['matrix-synapse'] + +managed_packages = ['matrix-synapse'] + +title = _('Federated IM, VoIP and Video server \n (matrix-synapse)') + +description = [ + _('Matrix is an new ecosystem for open federated Instant Messaging ' + 'and VoIP. Synapse is a reference Matrix server implementation.'), + + _('To communicate, you can use the ' + 'Riot client.'), + + _('Changing the FreedomBox domain name needs a reinstall of ' + 'Matrix-Synapse and you WILL LOSE DATA.') +] + +service = None + +logger = logging.getLogger(__name__) + +SERVER_NAME_PATH = "/etc/matrix-synapse/conf.d/server_name.yaml" + + +def init(): + """Initialize the matrix-synapse module""" + menu = cfg.main_menu.get('apps:index') + menu.add_urlname(title, 'glyphicon-comment', 'matrixsynapse:index') + + global service + setup_helper = globals()['setup_helper'] + if setup_helper.get_state() != 'needs-setup': + service = service_module.Service( + 'matrix-synapse', title, + ports=['matrix-synapse'], + 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, 'matrixsynapse', + ['pre-install']) + helper.install(managed_packages) + global service + if service is None: + service = service_module.Service( + 'matrix-synapse', title, + ports=['matrix-synapse'], + is_external=True, is_enabled=is_enabled, enable=enable, + disable=disable) + helper.call('post', service.notify_enabled, None, True) + helper.call('post', add_shortcut) + + +def add_shortcut(): + frontpage.add_shortcut('matrix-synapse', title, details=description, + configure_url=reverse_lazy('matrix-synapse:index'), + login_required=True) + + +def is_setup(): + return os.path.exists(SERVER_NAME_PATH) + + +def is_enabled(): + """Return whether the module is enabled.""" + return action_utils.service_is_enabled('matrix-synapse') + + +def get_domain_names(): + """Return the domain name(s)""" + results = [] + + for domain_type, domains in names.domains.items(): + if domain_type == 'hiddenservice': + continue + for domain in domains: + results.append((domain, domain)) + + return results + + +def get_configured_domain_name(): + if not is_setup(): + return "" + + with open(SERVER_NAME_PATH) as config_file: + config, _, _ = load_yaml_guess_indent(config_file) + + return config["server_name"] + + +def enable(): + """Enable the module.""" + actions.superuser_run('matrixsynapse', ['enable']) + add_shortcut() + + +def disable(): + """Enable the module.""" + actions.superuser_run('matrixsynapse', ['disable']) + frontpage.remove_shortcut('matrixsynapse') + + +def diagnose(): + """Run diagnostics and return the results.""" + return [action_utils.diagnose_port_listening(8008, 'tcp4')] diff --git a/plinth/modules/matrixsynapse/forms.py b/plinth/modules/matrixsynapse/forms.py new file mode 100644 index 000000000..6bb382fd3 --- /dev/null +++ b/plinth/modules/matrixsynapse/forms.py @@ -0,0 +1,37 @@ +# +# 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 matrix-synapse +""" + +from django import forms +from django.utils.translation import ugettext_lazy as _ + +from plinth.modules import matrixsynapse + + +class MatrixSynapseForm(forms.Form): + """Form to do initial configuration of matrix-synapse""" + domain_name = forms.ChoiceField( + label=_('Select the domain name to be used for Matrix'), + choices=[] + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['domain_name'].choices = matrixsynapse.get_domain_names() diff --git a/plinth/modules/matrixsynapse/templates/matrix-post-setup.html b/plinth/modules/matrixsynapse/templates/matrix-post-setup.html new file mode 100644 index 000000000..a7cf46d44 --- /dev/null +++ b/plinth/modules/matrixsynapse/templates/matrix-post-setup.html @@ -0,0 +1,39 @@ +{% extends "service.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 description %} + +{% for paragraph in description %} +

{{ paragraph|safe }}

+{% endfor %} + +

+ {% url 'config:index' as index_url %} + {% blocktrans trimmed with domain_name=domain_name %} + The Matrix server domain is set to {{ domain_name }}. User + IDs will look like @username:{{ domain_name }} + Changing the FreedomBox domain name needs a reinstall of + Matrix-Synapse and you WILL LOSE DATA. + {% endblocktrans %} +

+{% endblock %} diff --git a/plinth/modules/matrixsynapse/templates/matrix-pre-setup.html b/plinth/modules/matrixsynapse/templates/matrix-pre-setup.html new file mode 100644 index 000000000..a7037a1dc --- /dev/null +++ b/plinth/modules/matrixsynapse/templates/matrix-pre-setup.html @@ -0,0 +1,62 @@ +{% 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 content %} + {% block pagetitle %} +

{{ title }}

+ {% endblock %} + + {% block description %} + {% for paragraph in description %} +

{{ paragraph|safe }}

+ {% endfor %} + {% endblock %} + +

+ {% url 'config:index' as index_url %} + {% if domain_names|length == 0 %} + No domain(s) are set. You can setup your domain on the system at + Configure page. + {% endif %} +

+ + {% block status %} + {% endblock %} + + {% block diagnostics %} + {% endblock %} + + {% block configuration %} + {% if domain_names|length > 0 %} +

Configuration

+
+ {% csrf_token %} + + {{ form|bootstrap }} + + +
+ {% endif %} + {% endblock %} +{% endblock %} diff --git a/plinth/modules/matrixsynapse/tests/__init__.py b/plinth/modules/matrixsynapse/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/plinth/modules/matrixsynapse/urls.py b/plinth/modules/matrixsynapse/urls.py new file mode 100644 index 000000000..19e41a110 --- /dev/null +++ b/plinth/modules/matrixsynapse/urls.py @@ -0,0 +1,31 @@ +# +# 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 . +# + +""" +URL for the matrix-synapse module +""" + +from django.conf.urls import url + +from .views import MatrixSynapseSetupView, MatrixSynapseServiceView + +urlpatterns = [ + url(r'^apps/matrixsynapse/setup', MatrixSynapseSetupView.as_view(), + name='setup'), + url(r'^apps/matrixsynapse/$', MatrixSynapseServiceView.as_view(), + name='index') +] diff --git a/plinth/modules/matrixsynapse/views.py b/plinth/modules/matrixsynapse/views.py new file mode 100644 index 000000000..8100d352f --- /dev/null +++ b/plinth/modules/matrixsynapse/views.py @@ -0,0 +1,71 @@ +# +# 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 . +# + +""" +Views for the Matrix Synapse module +""" +from django.shortcuts import redirect +from django.urls import reverse_lazy +from django.views.generic import FormView + +from plinth import actions +from plinth.modules import matrixsynapse +from plinth.modules.matrixsynapse.forms import MatrixSynapseForm +from plinth.views import ServiceView + + +class MatrixSynapseSetupView(FormView): + """Show matrix-synapse setup page.""" + template_name = 'matrix-pre-setup.html' + form_class = MatrixSynapseForm + description = matrixsynapse.description + title = matrixsynapse.title + success_url = reverse_lazy('matrixsynapse:index') + + def form_valid(self, form): + domain_name = form.cleaned_data['domain_name'] + actions.superuser_run('matrixsynapse', + ['setup', '--domain-name', domain_name]) + + return super().form_valid(form) + + def get_context_data(self, *args, **kwargs): + context = super().get_context_data(**kwargs) + context['description'] = self.description + context['title'] = self.title + context['domain_names'] = matrixsynapse.get_domain_names() + + return context + + +class MatrixSynapseServiceView(ServiceView): + """Show matrix-synapse service page.""" + service_id = matrixsynapse.managed_services[0] + template_name = 'matrix-post-setup.html' + diagnostics_module_name = 'matrixsynapse' + + def dispatch(self, request, *args, **kwargs): + if not matrixsynapse.is_setup(): + return redirect('matrixsynapse:setup') + + return super().dispatch(request, *args, **kwargs) + + def get_context_data(self, *args, **kwargs): + context = super().get_context_data(**kwargs) + context['domain_name'] = matrixsynapse.get_configured_domain_name() + + return context