Merge remote-tracking branch 'sunil/polish'

This commit is contained in:
James Valleroy 2015-07-30 18:53:23 -04:00
commit 565703270e
24 changed files with 155 additions and 478 deletions

View File

@ -1,85 +0,0 @@
#!/bin/sh
#
# 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 <http://www.gnu.org/licenses/>.
#
# Usage:
# module-manager list-available
# module-manager list-enabled <python_root>
# module-manager enable <python_root> <module_name>
# module-manager disable <python_root> <module_name>
# list of modules that may be enabled/disabled
modules="owncloud"
case "$1" in
"list-available")
# TODO: Replace this with something like "aptitude search -F %p plinth-"
echo "$modules"
;;
"list-enabled")
# TODO: Replace this with something like 'aptitude search -F %p | grep "plinth-"'
for module in "$modules"
do
if [ -e "$2"/modules/enabled/"$module" ] ; then
echo "$module"
fi
done
;;
"enable")
# TODO: Replace this with "aptitude install plinth-<module>"
for module in "$modules"
do
if [ "$3" = "$module" ] ; then
if [ ! -e "$2"/modules/enabled/"$3" ] ; then
touch "$2"/modules/enabled/"$3"
RETVAL=$?
if [ $RETVAL -eq 0 ] ; then
echo "enabled" "$3"
else
echo "failed to enable" "$3"
fi
exit $RETVAL
fi
fi
done
echo "failed to enable invalid module" "$3"
exit 1
;;
"disable")
# TODO: Replace this with "aptitude purge plinth-<module>"
for module in "$modules"
do
if [ "$3" = "$module" ] ; then
if [ -e "$2"/modules/enabled/"$3" ] ; then
rm -f "$2"/modules/enabled/"$3"
RETVAL=$?
if [ $RETVAL -eq 0 ] ; then
echo "disabled" "$3"
else
echo "failed to disable" "$3"
fi
exit $RETVAL
fi
fi
done
echo "failed to disable invalid module" "$3"
exit 1
;;
esac

View File

@ -25,7 +25,6 @@ import argparse
import augeas import augeas
import json import json
import os import os
import subprocess
from plinth import action_utils from plinth import action_utils
from plinth.modules.pagekite import utils from plinth.modules.pagekite import utils

View File

@ -22,11 +22,16 @@ Configuration helper for the Tor service
""" """
import argparse import argparse
import codecs
import os import os
import re
import socket
from plinth import action_utils from plinth import action_utils
TOR_CONFIG = '/etc/tor/torrc' TOR_CONFIG = '/etc/tor/torrc'
TOR_STATE_FILE = '/var/lib/tor/state'
TOR_AUTH_COOKIE = '/var/run/tor/control.authcookie'
def parse_arguments(): def parse_arguments():
@ -34,20 +39,12 @@ def parse_arguments():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
# Enable and start the service
subparsers.add_parser('enable', help='Enable and start Tor service') subparsers.add_parser('enable', help='Enable and start Tor service')
# Disable and stop the service
subparsers.add_parser('disable', help='Disable and stop Tor service') subparsers.add_parser('disable', help='Disable and stop Tor service')
# Get currently configured Tor hidden service information
subparsers.add_parser('get-hs', help='Get hidden service') subparsers.add_parser('get-hs', help='Get hidden service')
# Enable Tor hidden service
subparsers.add_parser('enable-hs', help='Enable hidden service') subparsers.add_parser('enable-hs', help='Enable hidden service')
# Disable Tor hidden service
subparsers.add_parser('disable-hs', help='Disable hidden service') subparsers.add_parser('disable-hs', help='Disable hidden service')
subparsers.add_parser('get-ports', help='Get list of Tor ports')
return parser.parse_args() return parser.parse_args()
@ -146,6 +143,42 @@ def get_hidden_service():
return hs_hostname + ' ' + ','.join(hs_ports) return hs_hostname + ' ' + ','.join(hs_ports)
def subcommand_get_ports(_):
"""Return a list of running Tor ports."""
try:
print('orport', _get_orport())
except Exception:
pass
with open(TOR_STATE_FILE, 'r') as state_file:
for line in state_file:
matches = re.match(r'^\s*TransportProxy\s+(\S*)\s+\S+:(\d+)\s*$',
line)
if matches:
print('{0} {1}'.format(matches.group(1), matches.group(2)))
def _get_orport():
"""Return the ORPort by querying running instance."""
cookie = open(TOR_AUTH_COOKIE, 'rb').read()
cookie = codecs.encode(cookie, 'hex').decode()
commands = '''AUTHENTICATE {cookie}
GETINFO net/listeners/or
QUIT
'''.format(cookie=cookie)
tor_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tor_socket.connect(('localhost', 9051))
tor_socket.send(commands.encode())
response = tor_socket.recv(1024)
tor_socket.close()
line = response.split(b'\r\n')[1].decode()
matches = re.match(r'.*="[^:]+:(\d+)"', line)
return matches.group(1)
def main(): def main():
"""Parse arguments and perform all duties""" """Parse arguments and perform all duties"""
arguments = parse_arguments() arguments = parse_arguments()

View File

@ -1,28 +0,0 @@
#!/bin/sh
#
# 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 <http://www.gnu.org/licenses/>.
#
# Action to get ports used by Tor.
echo "ORPort" `tor-get-orport`
transports="obfs3 scramblesuit"
for transport in $transports
do
echo $transport `grep $transport /var/lib/tor/state | awk -F'[: ]*' '{print $4}'`
done

View File

@ -1 +0,0 @@
plinth.modules.packages

View File

@ -36,7 +36,7 @@ def init():
"""Initialize the Deluge module.""" """Initialize the Deluge module."""
menu = cfg.main_menu.get('apps:index') menu = cfg.main_menu.get('apps:index')
menu.add_urlname(_('BitTorrent (Deluge)'), 'glyphicon-magnet', menu.add_urlname(_('BitTorrent (Deluge)'), 'glyphicon-magnet',
'deluge:index', 60) 'deluge:index', 200)
global service global service
service = service_module.Service( service = service_module.Service(

View File

@ -43,7 +43,7 @@ def init():
"""Initialize the dynamicdns module""" """Initialize the dynamicdns module"""
menu = cfg.main_menu.get('apps:index') menu = cfg.main_menu.get('apps:index')
menu.add_urlname('Dynamic DNS', 'glyphicon-refresh', menu.add_urlname('Dynamic DNS', 'glyphicon-refresh',
'dynamicdns:index', 40) 'dynamicdns:index', 500)
@package.required(['ez-ipupdate']) @package.required(['ez-ipupdate'])

View File

@ -38,8 +38,15 @@ runs on must be cheap. The software it runs on must be easy to
install and administrate by anybody. It must be easy to install and administrate by anybody. It must be easy to
transition from existing services.</p> transition from existing services.</p>
<p>There are a number of projects working to realize a future of
distributed services; we aim to bring them all together in a
convenient package.</p>
<p>For more information about the FreedomBox project, see the
<a href="https://wiki.debian.org/FreedomBox">Debian Wiki</a>.</p>
<p><a class="btn btn-primary btn-lg" <p><a class="btn btn-primary btn-lg"
href="http://wiki.debian.org/FreedomBox" target="_blank">Learn more href="https://wiki.debian.org/FreedomBox" target="_blank">Learn more
&raquo;</a></p> &raquo;</a></p>
<p style='margin-top:30px'> <p style='margin-top:30px'>
@ -47,20 +54,3 @@ href="http://wiki.debian.org/FreedomBox" target="_blank">Learn more
</p> </p>
{% endblock %} {% endblock %}
{% block sidebar %}
<div class="sidebar">
<h3>Our Goal</h3>
<p>There are a number of projects working to realize a future of
distributed services; we aim to bring them all together in a
convenient package.</p>
<p>For more information about the FreedomBox project, see the
<a href="http://wiki.debian.org/FreedomBox">Debian Wiki</a>.</p>
</div>
{% endblock %}

View File

@ -36,7 +36,7 @@ def init():
"""Initialize the ikiwiki module.""" """Initialize the ikiwiki module."""
menu = cfg.main_menu.get('apps:index') menu = cfg.main_menu.get('apps:index')
menu.add_urlname(_('Wiki & Blog (Ikiwiki)'), 'glyphicon-edit', menu.add_urlname(_('Wiki & Blog (Ikiwiki)'), 'glyphicon-edit',
'ikiwiki:index', 38) 'ikiwiki:index', 1100)
global service global service
service = service_module.Service( service = service_module.Service(

View File

@ -36,7 +36,7 @@ def init():
"""Intialize the Mumble module.""" """Intialize the Mumble module."""
menu = cfg.main_menu.get('apps:index') menu = cfg.main_menu.get('apps:index')
menu.add_urlname(_('Voice Chat (Mumble)'), 'glyphicon-headphones', menu.add_urlname(_('Voice Chat (Mumble)'), 'glyphicon-headphones',
'mumble:index', 50) 'mumble:index', 900)
global service global service
service = service_module.Service( service = service_module.Service(

View File

@ -15,6 +15,10 @@
# 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 ownCloud.
"""
from django import forms from django import forms
from django.contrib import messages from django.contrib import messages
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
@ -37,7 +41,8 @@ class OwnCloudForm(forms.Form): # pylint: disable-msg=W0232
def init(): def init():
"""Initialize the ownCloud module""" """Initialize the ownCloud module"""
menu = cfg.main_menu.get('apps:index') menu = cfg.main_menu.get('apps:index')
menu.add_urlname('ownCloud', 'glyphicon-picture', 'owncloud:index', 35) menu.add_urlname(_('File Hosting (ownCloud)'), 'glyphicon-picture',
'owncloud:index', 700)
status = get_status() status = get_status()

View File

@ -22,37 +22,27 @@
{% block content %} {% block content %}
<h2>File Hosting (ownCloud)</h2>
<p>ownCloud gives you universal access to your files through a web
interface or WebDAV. It also provides a platform to easily view &
sync your contacts, calendars and bookmarks across all your devices
and enables basic editing right on the web. Installation has minimal
server requirements, doesn't need special permissions and is
quick. ownCloud is extendable via a simple but powerful API for
applications and plugins.</p>
<p>When enabled, the ownCloud installation will be available
from <a href="/owncloud">/owncloud</a> path on the web server.
Visit this URL to set up the initial administration account for
ownCloud.</p>
<form class="form" method="post"> <form class="form" method="post">
{% csrf_token %} {% csrf_token %}
<h2>ownCloud</h2>
<p>When enabled, the ownCloud installation will be available
from <a href="/owncloud">/owncloud</a> path on the web server.
Visit this URL to set up the initial administration account for
ownCloud.</p>
{{ form|bootstrap }} {{ form|bootstrap }}
<input type="submit" class="btn btn-primary btn-md" value="Apply changes"/> <input type="submit" class="btn btn-primary btn-md" value="Apply changes"/>
</form> </form>
{% endblock %} {% endblock %}
{% block sidebar %}
<div class="sidebar">
<h3>ownCloud</h3>
<p>ownCloud gives you universal access to your files through a web
interface or WebDAV. It also provides a platform to easily view
& sync your contacts, calendars and bookmarks across all your
devices and enables basic editing right on the web. Installation
has minimal server requirements, doesn't need special
permissions and is quick. ownCloud is extendable via a simple
but powerful API for applications and plugins.</p>
</div>
{% endblock %}

View File

@ -1,27 +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 <http://www.gnu.org/licenses/>.
#
"""
Plinth module to manage packages
"""
from . import packages
from .packages import init
__all__ = ['packages', 'init']
depends = ['plinth.modules.system']

View File

@ -1,130 +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 <http://www.gnu.org/licenses/>.
#
from django import forms
from django.contrib import messages
from django.template.response import TemplateResponse
from gettext import gettext as _
import os
from plinth import actions
from plinth import cfg
def get_modules_available():
"""Return list of all modules"""
output = actions.run('module-manager', ['list-available'])
return output.split()
def get_modules_enabled():
"""Return list of all modules"""
root = os.path.join(os.path.dirname(__file__), '..', '..')
output = actions.run('module-manager',
['list-enabled', root])
return output.split()
class PackagesForm(forms.Form):
"""Packages form"""
def __init__(self, *args, **kwargs):
# pylint: disable-msg=E1002, E1101
super(forms.Form, self).__init__(*args, **kwargs)
modules_available = get_modules_available()
for module in modules_available:
label = _('Enable {module}').format(module=module)
self.fields[module + '_enabled'] = forms.BooleanField(
label=label, required=False)
def init():
"""Initialize the Packages module"""
menu = cfg.main_menu.get('system:index')
menu.add_urlname('Package Manager', 'glyphicon-gift', 'packages:index', 20)
def index(request):
"""Serve the form"""
status = get_status()
form = None
if request.method == 'POST':
form = PackagesForm(request.POST, prefix='packages')
# pylint: disable-msg=E1101
if form.is_valid():
_apply_changes(request, status, form.cleaned_data)
status = get_status()
form = PackagesForm(initial=status, prefix='packages')
else:
form = PackagesForm(initial=status, prefix='packages')
return TemplateResponse(request, 'packages.html',
{'title': _('Add/Remove Plugins'),
'form': form})
def get_status():
"""Return the current status"""
modules_available = get_modules_available()
modules_enabled = get_modules_enabled()
return {module + '_enabled': module in modules_enabled
for module in modules_available}
def _apply_changes(request, old_status, new_status):
"""Apply form changes"""
root = os.path.join(os.path.dirname(__file__), '..', '..')
for field, enabled in new_status.items():
if not field.endswith('_enabled'):
continue
if old_status[field] == new_status[field]:
continue
module = field.split('_enabled')[0]
if enabled:
try:
actions.superuser_run('module-manager',
['enable', root, module])
except Exception:
# TODO: need to get plinth to load the module we just
# enabled
messages.error(
request, _('Error enabling module - {module}').format(
module=module))
else:
messages.success(
request, _('Module enabled - {module}').format(
module=module))
else:
try:
actions.superuser_run('module-manager',
['disable', root, module])
except Exception:
# TODO: need a smoother way for plinth to unload the
# module
messages.error(
request, _('Error disabling module - {module}').format(
module=module))
else:
messages.success(
request, _('Module disabled - {module}').format(
module=module))

View File

@ -1,63 +0,0 @@
{% 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 <http://www.gnu.org/licenses/>.
#
{% endcomment %}
{% load bootstrap %}
{% block content %}
<h2>{{ title }}</h2>
<p><code>aptitude purge modules</code></p>
<p><code>aptitude install modules</code></p>
<p>The modules should depend on the appropriate Debian packages.</p>
<h2>Manage Plugins</h2>
<form class="form" method="post">
{% csrf_token %}
{{ form|bootstrap }}
<p>Enabling a plugin will cause a corresponding page to appear in
Plinth.</p>
<input type="submit" class="btn btn-primary" value="Update setup"/>
</form>
{% endblock %}
{% block sidebar %}
<div class="sidebar">
<h3>Help</h3>
<p>On this page, you can add or remove {{ cfg.product_name }}
plugins to your {{ cfg.box_name }}.</p>
<p>Plugins are just Debian packages, so Debian's usual package
management features should make this job fairly easy.</p>
</div>
{% endblock %}

View File

@ -1,28 +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 <http://www.gnu.org/licenses/>.
#
"""
URLs for the Packages module
"""
from django.conf.urls import patterns, url
urlpatterns = patterns( # pylint: disable-msg=C0103
'plinth.modules.packages.packages',
url(r'^sys/packages/$', 'index', name='index')
)

View File

@ -31,4 +31,4 @@ def init():
"""Intialize the PageKite module""" """Intialize the PageKite module"""
menu = cfg.main_menu.get('apps:index') menu = cfg.main_menu.get('apps:index')
menu.add_urlname(_('Public Visibility (PageKite)'), menu.add_urlname(_('Public Visibility (PageKite)'),
'glyphicon-flag', 'pagekite:index', 50) 'glyphicon-flag', 'pagekite:index', 800)

View File

@ -36,7 +36,7 @@ def init():
"""Intialize the module.""" """Intialize the module."""
menu = cfg.main_menu.get('apps:index') menu = cfg.main_menu.get('apps:index')
menu.add_urlname(_('Web Proxy (Privoxy)'), 'glyphicon-cloud-upload', menu.add_urlname(_('Web Proxy (Privoxy)'), 'glyphicon-cloud-upload',
'privoxy:index', 50) 'privoxy:index', 1000)
global service global service
service = service_module.Service( service = service_module.Service(

View File

@ -34,7 +34,7 @@ def init():
"""Intialize the module.""" """Intialize the module."""
menu = cfg.main_menu.get('apps:index') menu = cfg.main_menu.get('apps:index')
menu.add_urlname(_('Email Client (Roundcube)'), 'glyphicon-envelope', menu.add_urlname(_('Email Client (Roundcube)'), 'glyphicon-envelope',
'roundcube:index', 50) 'roundcube:index', 600)
def is_enabled(): def is_enabled():
"""Return whether the module is enabled.""" """Return whether the module is enabled."""

View File

@ -22,35 +22,54 @@
{% block content %} {% block content %}
<h2>Tor</h2> <h2>Anonymity Network (Tor)</h2>
<p>Tor is an anonymous communication system. You can learn more about
it from the <a href="https://www.torproject.org/">Tor Project</a>
website. For best protection when web surfing, the Tor Project
recommends that you use
the <a href="https://www.torproject.org/download/download-easy.html.en">
Tor Browser</a>.</p>
<h3>Status</h3> <h3>Status</h3>
<p> <p>
{% if is_running %} {% if status.is_running %}
<div class='running-status active'></div> Tor is running <div class='running-status active'></div> Tor is running
{% else %} {% else %}
<div class='running-status inactive'></div> Tor is not running <div class='running-status inactive'></div> Tor is not running
{% endif %} {% endif %}
</p> </p>
<h3>Hidden Service</h3> {% if status.hs_enabled %}
<div class="row">
<div class="col-sm-3">
<table class="table table-bordered table-condensed table-striped">
<thead>
<tr>
<th>Hidden Service</th>
<th>Port</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ status.hs_hostname }}</td>
<td>{{ status.hs_ports }}</td>
</tr>
</tbody>
</table>
</div>
</div>
{% endif %}
<p>A hidden service will allow your {{ cfg.box_name }} to provide selected <h3>Configuration</h3>
services (such as OwnCloud or Chat) without revealing its location.
Here is the current configuration:</p>
<ul> <form class="form" method="post">
<li>Hostname: {{ tor_hs_hostname }}</li>
<li>Ports: {{ tor_hs_ports }}</li>
</ul>
<form class="form form-inline" method="post">
{% csrf_token %} {% csrf_token %}
{{ form|bootstrap }} {{ form|bootstrap }}
<input type="submit" class="btn btn-primary btn-sm" value="Update setup"/> <input type="submit" class="btn btn-primary btn-md" value="Update setup"/>
</form> </form>
<h3>Bridge</h3> <h3>Bridge</h3>
@ -62,13 +81,21 @@ port-forwarded, if necessary:</p>
<div class="row"> <div class="row">
<div class="col-sm-3"> <div class="col-sm-3">
<table class="table table-bordered table-condensed"> <table class="table table-bordered table-condensed table-striped">
{% for name, port in tor_ports.items %} <thead>
<tr>
<th>Service</th>
<th>Port</th>
</tr>
</thead>
<tbody>
{% for name, port in status.ports.items %}
<tr> <tr>
<td>{{ name }}</td> <td>{{ name }}</td>
<td>{{ port }}</td> <td>{{ port }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody>
</table> </table>
</div> </div>
</div> </div>
@ -79,20 +106,3 @@ port-forwarded, if necessary:</p>
9050.</p> 9050.</p>
{% endblock %} {% endblock %}
{% block sidebar %}
<div class="sidebar">
<h3>Tor</h3>
<p>Tor is an anonymous communication system. You can learn more about
it from the <a href="https://www.torproject.org/">Tor Project</a>
website. For best protection when web surfing, the Tor Project
recommends that you use the
<a href="https://www.torproject.org/download/download-easy.html.en">
Tor Browser</a>.</p>
</div>
{% endblock %}

View File

@ -32,15 +32,22 @@ from plinth import package
class TorForm(forms.Form): # pylint: disable=W0232 class TorForm(forms.Form): # pylint: disable=W0232
"""Tor configuration form""" """Tor configuration form"""
hs_enabled = forms.BooleanField( enabled = forms.BooleanField(
label=_('Enable Hidden Service'), label=_('Enable Tor'),
required=False) required=False)
hs_enabled = forms.BooleanField(
label=_('Enable Tor Hidden Service'),
required=False,
help_text=_('A hidden service will allow FreedomBox to provide '
'selected services (such as ownCloud or Chat) without '
'revealing its location.'))
def init(): def init():
"""Initialize the Tor module""" """Initialize the Tor module."""
menu = cfg.main_menu.get('apps:index') menu = cfg.main_menu.get('apps:index')
menu.add_urlname('Tor', 'glyphicon-eye-close', 'tor:index', 30) menu.add_urlname(_('Anonymity Network (Tor)'), 'glyphicon-eye-close',
'tor:index', 100)
@package.required(['tor']) @package.required(['tor'])
@ -62,17 +69,13 @@ def index(request):
return TemplateResponse(request, 'tor.html', return TemplateResponse(request, 'tor.html',
{'title': _('Tor Control Panel'), {'title': _('Tor Control Panel'),
'is_running': status['is_running'], 'status': status,
'tor_ports': status['ports'],
'tor_hs_enabled': status['hs_enabled'],
'tor_hs_hostname': status['hs_hostname'],
'tor_hs_ports': status['hs_ports'],
'form': form}) 'form': form})
def get_status(): def get_status():
"""Return the current status""" """Return the current status"""
output = actions.superuser_run('tor-get-ports') output = actions.superuser_run('tor', ['get-ports'])
port_info = output.split('\n') port_info = output.split('\n')
ports = {} ports = {}
for line in port_info: for line in port_info:
@ -98,7 +101,8 @@ def get_status():
hs_hostname = hs_info[0] hs_hostname = hs_info[0]
hs_ports = hs_info[1] hs_ports = hs_info[1]
return {'is_running': action_utils.service_is_running('tor'), return {'enabled': action_utils.service_is_enabled('tor'),
'is_running': action_utils.service_is_running('tor'),
'ports': ports, 'ports': ports,
'hs_enabled': hs_enabled, 'hs_enabled': hs_enabled,
'hs_hostname': hs_hostname, 'hs_hostname': hs_hostname,
@ -106,16 +110,24 @@ def get_status():
def _apply_changes(request, old_status, new_status): def _apply_changes(request, old_status, new_status):
"""Apply the changes""" """Apply the changes."""
if old_status['hs_enabled'] == new_status['hs_enabled']: if old_status['enabled'] == new_status['enabled'] and \
old_status['hs_enabled'] == new_status['hs_enabled']:
messages.info(request, _('Setting unchanged')) messages.info(request, _('Setting unchanged'))
return return
if new_status['hs_enabled']: if old_status['enabled'] != new_status['enabled']:
messages.success(request, _('Tor hidden service enabled')) if new_status['enabled']:
command = 'enable-hs' messages.success(request, _('Tor enabled'))
else: actions.superuser_run('tor', ['enable'])
messages.success(request, _('Tor hidden service disabled')) else:
command = 'disable-hs' messages.success(request, _('Tor disabled'))
actions.superuser_run('tor', ['disable'])
actions.superuser_run('tor', [command]) if old_status['hs_enabled'] != new_status['hs_enabled']:
if new_status['hs_enabled']:
messages.success(request, _('Tor hidden service enabled'))
actions.superuser_run('tor', ['enable-hs'])
else:
messages.success(request, _('Tor hidden service disabled'))
actions.superuser_run('tor', ['disable-hs'])

View File

@ -36,7 +36,7 @@ def init():
"""Intialize the Transmission module.""" """Intialize the Transmission module."""
menu = cfg.main_menu.get('apps:index') menu = cfg.main_menu.get('apps:index')
menu.add_urlname(_('BitTorrent (Transmission)'), 'glyphicon-save', menu.add_urlname(_('BitTorrent (Transmission)'), 'glyphicon-save',
'transmission:index', 100) 'transmission:index', 300)
global service global service
service = service_module.Service( service = service_module.Service(

View File

@ -38,7 +38,7 @@ def init():
"""Initialize the XMPP module""" """Initialize the XMPP module"""
menu = cfg.main_menu.get('apps:index') menu = cfg.main_menu.get('apps:index')
menu.add_urlname(_('Chat Server (XMPP)'), 'glyphicon-comment', menu.add_urlname(_('Chat Server (XMPP)'), 'glyphicon-comment',
'xmpp:index', 40) 'xmpp:index', 400)
global service global service
service = service_module.Service( service = service_module.Service(