Add icons for desktop applications and Apple App store.

- Add yapf style file for consistency of formatting
- Some minor changes and renaming
- Add template tag filters for checking conditions
- Move icons from img directory to icons directory

Currently the client listing is in both the SetupView and ServceView for ease of
development. Have to remove from 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 12:09:46 +05:30 committed by James Valleroy
parent defcb37472
commit d3cddfa68c
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
21 changed files with 382 additions and 272 deletions

7
.style.yapf Normal file
View File

@ -0,0 +1,7 @@
[style]
based_on_style = pep8
spaces_before_comment = 2
split_before_logical_operator = true
each_dict_entry_on_separate_line = true
coalesce_brackets = false
indent_dictionary_value = true

View File

@ -63,8 +63,9 @@ otherwise.
- static/themes/default/icons/tahoe.png :: [[https://github.com/thekishanraval/Logos][GPLv3+]]
- static/themes/default/icons/transmission.png :: [[https://transmissionbt.com/][GPL]]
- static/themes/default/icons/ttrss.png :: [[https://tt-rss.org/gitlab/fox/tt-rss][GPL]]
- static/themes/default/img/f-droid.png :: [[https://commons.wikimedia.org/wiki/File%3AGet_it_on_F-Droid_(material_design).svg][GPLv3]]
- static/themes/default/img/google-play.png :: [[https://upload.wikimedia.org/wikipedia/commons/c/cd/Get_it_on_Google_play.svg][Public Domain]]
- static/themes/default/img/debian.png :: [[https://commons.wikimedia.org/wiki/File:Debian_logo-black.png][GPL3+/CC-BY-SA]]
- static/themes/default/img/apple.png :: [[https://thenounproject.com/icon/1203053/download/color/000000/png][CC BY 3.0 US]]
- static/themes/default/img/windows.png :: [[https://thenounproject.com/icon/1206946/download/color/000000/png][CC BY 3.0 US]]
- static/themes/default/icons/f-droid.png :: [[https://commons.wikimedia.org/wiki/File%3AGet_it_on_F-Droid_(material_design).svg][GPLv3]]
- static/themes/default/icons/google-play.png :: [[https://upload.wikimedia.org/wikipedia/commons/c/cd/Get_it_on_Google_play.svg][Public Domain]]
- static/themes/default/icons/app-store.png :: [[https://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/Download_on_the_App_Store_Badge.svg/500px-Download_on_the_App_Store_Badge.svg.png][Public Domain]]
- static/themes/default/icons/apple.png :: [[https://thenounproject.com/icon/1203053/download/color/000000/png][CC BY 3.0 US]]
- static/themes/default/icons/windows.png :: [[https://thenounproject.com/icon/1206946/download/color/000000/png][CC BY 3.0 US]]
- static/themes/default/icons/gnu-linux.png :: [[https://upload.wikimedia.org/wikipedia/commons/9/95/Tux-icon-mono.svg][Public Domain]]

View File

@ -17,18 +17,17 @@
from django.utils.translation import ugettext_lazy as _
clients = [
{
'name': _('Deluge'),
'description': _('Bittorrent client written in Python/PyGTK '),
'platforms': [
{
'type': 'web',
'relative_path': '/deluge'
},
{
'type': 'apt',
'os': 'Debian',
'package_name': 'deluge'
}]
clients = [{
'name':
_('Deluge'),
'description':
_('Bittorrent client written in Python/PyGTK '),
'platforms': [{
'type': 'web',
'relative_path': '/deluge'
}, {
'type': 'package',
'format': 'deb',
'name': 'deluge',
}]
}]

View File

@ -17,37 +17,32 @@
from django.utils.translation import ugettext_lazy as _
clients = [
{
'name': _('Minetest'),
'platforms': [
{
'type': 'download',
'os': 'Windows(64-bit)',
'os_version': 'XP, Vista, >=7',
'url': 'https://github.com/minetest/minetest/releases'
'/download/0.4.16/minetest-0.4.16-win64.zip '
},
{
'type': 'store',
'os': 'Android',
'store_name': 'google_play_store',
'fully_qualified_name': 'net.minetest.minetest',
'url': 'https://play.google.com/store/apps/details?id=net'
'.minetest.minetest '
},
{
'type': 'store',
'os': 'Android',
'store_name': 'fdroid_store',
'fully_qualified_name': 'net.minetest.minetest',
'url': 'https://f-droid.org/packages/net.minetest.minetest/ '
},
{
'type': 'apt',
'os': 'Debian',
'package_name': 'minetest'
}
]
}
]
clients = [{
'name':
_('Minetest'),
'platforms': [{
'type': 'download',
'os': 'Windows',
'arch': 'amd64',
'os_version': 'XP, Vista, >=7',
'url': 'https://github.com/minetest/minetest/releases'
'/download/0.4.16/minetest-0.4.16-win64.zip '
}, {
'type': 'store',
'os': 'Android',
'store_name': 'google_play_store',
'fully_qualified_name': 'net.minetest.minetest',
'url': 'https://play.google.com/store/apps/details?id=net'
'.minetest.minetest '
}, {
'type': 'store',
'os': 'Android',
'store_name': 'fdroid_store',
'fully_qualified_name': 'net.minetest.minetest',
'url': 'https://f-droid.org/packages/net.minetest.minetest/ '
}, {
'type': 'package',
'format': 'deb',
'name': 'minetest'
}]
}]

View File

@ -17,73 +17,63 @@
from django.utils.translation import ugettext_lazy as _
clients = [
{
'name': _('Mumble'),
'platforms': [
{
'type': 'download',
'os': 'Windows(32-bit)',
'url': 'https://github.com/mumble-voip/mumble/releases'
'/download/1.2.19/mumble-1.2.19.msi '
},
{
'type': 'download',
'os': 'Windows(64-bit)',
'url': 'https://dl.mumble.info/mumble-1.3.0~2569~gd196a4b'
'~snapshot.winx64.msi '
},
{
'type': 'download',
'os': 'macOS',
'url': 'https://github.com/mumble-voip/mumble/releases'
'/download/1.2.19/Mumble-1.2.19.dmg '
},
{
'type': 'apt',
'os': 'Debian',
'package_name': 'mumble'
},
{
'type': 'store',
'os': 'iOS',
'os_version': '>=8.0',
'store_name': 'apple_store',
'url': 'https://itunes.apple.com/us/app/mumble/id443472808'
}
]
},
{
'name': _('Plumble'),
'platforms': [
{
'type': 'store',
'os': 'Android',
'store_name': 'google_play_store',
'url': 'https://play.google.com/store/apps/details?id=com'
'.morlunk.mumbleclient.free ',
'fully_qualified_name': 'com.morlunk.mumbleclient'
},
{
'type': 'store',
'os': 'Android',
'store_name': 'fdroid_store',
'url': 'https://play.google.com/store/apps/details?id=com'
'.morlunk.mumbleclient.free ',
'fully_qualified_name': 'com.morlunk.mumbleclient'
}
]
},
{
'name': _('Mumblefly'),
'platforms': [
{
'type': 'store',
'os': 'iOS',
'os_version': '>=7.0',
'store_name': 'apple_store',
'url': 'https://itunes.apple.com/dk/app/mumblefy/id858752232'
}
]
}
]
clients = [{
'name':
_('Mumble'),
'platforms': [{
'type': 'download',
'os': 'Windows',
'arch': 'i386',
'url': 'https://github.com/mumble-voip/mumble/releases'
'/download/1.2.19/mumble-1.2.19.msi '
}, {
'type': 'download',
'os': 'Windows(64-bit)',
'arch': 'amd64',
'url': 'https://dl.mumble.info/mumble-1.3.0~2569~gd196a4b'
'~snapshot.winx64.msi '
}, {
'type': 'download',
'os': 'macOS',
'url': 'https://github.com/mumble-voip/mumble/releases'
'/download/1.2.19/Mumble-1.2.19.dmg '
}, {
'type': 'package',
'format': 'deb',
'name': 'mumble'
}, {
'type': 'store',
'os': 'iOS',
'os_version': '>=8.0',
'store_name': 'apple_store',
'url': 'https://itunes.apple.com/us/app/mumble/id443472808'
}]
}, {
'name':
_('Plumble'),
'platforms': [{
'type': 'store',
'os': 'Android',
'store_name': 'google_play_store',
'url': 'https://play.google.com/store/apps/details?id=com'
'.morlunk.mumbleclient.free ',
'fully_qualified_name': 'com.morlunk.mumbleclient'
}, {
'type': 'store',
'os': 'Android',
'store_name': 'fdroid_store',
'url': 'https://play.google.com/store/apps/details?id=com'
'.morlunk.mumbleclient.free ',
'fully_qualified_name': 'com.morlunk.mumbleclient'
}]
}, {
'name':
_('Mumblefly'),
'platforms': [{
'type': 'store',
'os': 'iOS',
'os_version': '>=7.0',
'store_name': 'apple_store',
'url': 'https://itunes.apple.com/dk/app/mumblefy/id858752232'
}]
}]

View File

@ -17,73 +17,58 @@
from django.utils.translation import ugettext_lazy as _
clients = [
{
'name': _('Jitsi Meet'),
'description': _('Jitsi is a set of open-source projects that allows '
'you to easily build and deploy secure '
'videoconferencing solutions. At the heart of Jitsi '
'are Jitsi Videobridge and Jitsi Meet, which let you '
'have conferences on the internet, while other '
'projects in the community enable other features '
'such as audio, dial-in, recording, '
'and simulcasting.'),
'platforms': [
{
'type': 'store',
'os': 'Android',
'store_name': 'google_play_store',
'fully_qualified_name': 'org.jitsi.meet',
'url': 'https://play.google.com/store/apps/details?id=org'
'.jitsi.meet '
},
{
'type': 'store',
'os': 'iOS',
'store_name': 'apple_store',
'url': 'https://itunes.apple.com/in/app/jitsi-meet/id1165103905'
},
{
'type': 'download',
'os': 'Linux',
'url': 'https://download.jitsi.org/jitsi/debian/'
},
{
'type': 'dnf',
'os': 'Linux',
'package_name': 'jitsi'
},
{
'type': 'download',
'os': 'macOS',
'url': 'https://download.jitsi.org/jitsi/macosx/jitsi-latest'
'.dmg '
},
{
'type': 'download',
'os': 'Windows',
'url': 'https://download.jitsi.org/jitsi/windows/jitsi-latest'
'-x86.exe '
},
{
'type': 'download',
'os': 'macOS',
'url': 'https://download.jitsi.org/jitsi/macosx/jitsi-latest'
'.dmg '
}
]
},
{
'name': _('CSipSimple'),
'platforms': [
{
'type': 'store',
'os': 'Android',
'store_name': 'google_play_store',
'fully_qualified_name': 'com.csipsimple',
'url': 'https://play.google.com/store/apps/details?id=com'
'.csipsimple '
}
]
}
]
clients = [{
'name':
_('Jitsi Meet'),
'description':
_('Jitsi is a set of open-source projects that allows '
'you to easily build and deploy secure '
'videoconferencing solutions. At the heart of Jitsi '
'are Jitsi Videobridge and Jitsi Meet, which let you '
'have conferences on the internet, while other '
'projects in the community enable other features '
'such as audio, dial-in, recording, '
'and simulcasting.'),
'platforms': [{
'type': 'store',
'os': 'Android',
'store_name': 'google_play_store',
'fully_qualified_name': 'org.jitsi.meet',
'url': 'https://play.google.com/store/apps/details?id=org'
'.jitsi.meet '
}, {
'type': 'store',
'os': 'iOS',
'store_name': 'apple_store',
'url': 'https://itunes.apple.com/in/app/jitsi-meet/id1165103905'
}, {
'type': 'download',
'os': 'GNU/Linux',
'url': 'https://download.jitsi.org/jitsi/debian/'
}, {
'type': 'package',
'format': 'deb',
'name': 'jitsi'
}, {
'type': 'download',
'os': 'macOS',
'url': 'https://download.jitsi.org/jitsi/macosx/jitsi-latest'
'.dmg '
}, {
'type': 'download',
'os': 'Windows',
'url': 'https://download.jitsi.org/jitsi/windows/jitsi-latest'
'-x86.exe '
}]
}, {
'name':
_('CSipSimple'),
'platforms': [{
'type': 'store',
'os': 'Android',
'store_name': 'google_play_store',
'fully_qualified_name': 'com.csipsimple',
'url': 'https://play.google.com/store/apps/details?id=com'
'.csipsimple '
}]
}]

View File

@ -67,7 +67,8 @@ service = None
def init():
"""Intialize the module."""
menu = main_menu.get('apps')
menu.add_urlname(name, 'glyphicon-refresh', 'syncthing:index', short_description)
menu.add_urlname(name, 'glyphicon-refresh',
'syncthing:index', short_description)
global service
setup_helper = globals()['setup_helper']

View File

@ -17,45 +17,79 @@
from django.utils.translation import ugettext_lazy as _
clients = [
{
'name': _('Syncthing'),
'platforms': [
{
'type': 'download',
'os': 'Debian',
'url': 'https://apt.syncthing.net/',
},
{
'type': 'download',
'os': 'macOS',
'url': 'https://github.com/syncthing/syncthing/releases'
},
{
'type': 'download',
'os': 'Windows',
'url': 'https://github.com/syncthing/syncthing/releases'
},
{
'type': 'store',
'os': 'Android',
'store_name': 'google_play_store',
'fully_qualified_name': 'com.nutomic.syncthingandroid',
'url': 'https://play.google.com/store/apps/details?id=com'
'.nutomic.syncthingandroid '
},
{
'type': 'store',
'os': 'Android',
'store_name': 'fdroid_store',
'fully_qualified_name': 'com.nutomic.syncthingandroid',
'url': 'https://f-droid.org/packages/com.nutomic'
'.syncthingandroid/ '
},
{
'type': 'web',
'relative_url': '/syncthing'
}
]
}
]
metadata = {
'syncthing': {
'version': '0.14.39',
'android-package-id': 'com.nutomic.syncthingandroid',
},
}
clients = [{
'name':
_('Syncthing'),
'platforms': [{
'type': 'package',
'format': 'deb',
'name': 'syncthing',
}, {
'type': 'package',
'format': 'homebrew',
'name': 'syncthing',
}, {
'type':
'download',
'os':
'all',
'url':
'https://github.com/syncthing/syncthing/releases/tag/v{}'
.format(metadata['syncthing']['version'])
}, {
'type': 'download',
'os': 'GNU/Linux',
'arch': 'amd64',
'url': 'https://github.com/syncthing/syncthing/releases/'
'download/v{0}/syncthing-linux-amd64-v{0}.tar.gz'
.format(metadata['syncthing']['version']),
}, {
'type': 'download',
'os': 'macOS',
'arch': 'amd64',
'url': 'https://github.com/syncthing/syncthing/releases/'
'download/v{0}/syncthing-macosx-amd64-v{0}.tar.gz'
.format(metadata['syncthing']['version']),
}, {
'type': 'download',
'os': 'Windows',
'arch': 'amd64',
'url': 'https://github.com/syncthing/syncthing/releases/'
'download/v{0}/syncthing-windows-amd64-v{0}.zip'
.format(metadata['syncthing']['version']),
}, {
'type':
'store',
'os':
'Android',
'store_name':
'google_play_store',
'fully_qualified_name':
'com.nutomic.syncthingandroid',
'url':
'https://play.google.com/store/apps/details?id={}'
.format(metadata['syncthing']['android-package-id'])
}, {
'type':
'store',
'os':
'Android',
'store_name':
'fdroid_store',
'fully_qualified_name':
'com.nutomic.syncthingandroid',
'url':
'https://f-droid.org/packages/{}'
.format(metadata['syncthing']['android-package-id'])
}, {
'type': 'web',
'relative_url': '/syncthing'
}]
}]

View File

@ -18,28 +18,41 @@
{% endcomment %}
{% load i18n %}
{% load plinth_extras %}
{% if module.clients %}
<button type="button" class="btn btn-primary collapsed"
data-toggle="collapse" data-target="#clients">
Client Apps
</button>
<div id="clients" class="collapse">
{% if module.clients|has_web_clients %}
<div class="clients-info">
<p class="heading">{% trans "Web Clients" %}:
<ul>
{% for client in module.clients %}
{% for platform in client.platforms %}
{% if platform.type == 'web' %}
<li>
<span><a href="{{ platform.relative_url }}">{{ client.name}}</a></span>
</li>
{% endif %}
{% endfor %}
{% if client|has_web_clients %}
{% for platform in client.platforms %}
{% if platform.type == 'web' %}
<li>
<span><a href="{{ platform.relative_url }}">{{ client.name}}</a></span>
</li>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
{% if module.clients|has_desktop_clients %}
<div class="clients-info">
{% load static %}
<p class="heading">{% trans "Desktop Clients" %}:
<ul>
{% for client in module.clients %}
{% if client|has_desktop_clients %}
<li class="col-md-12 col-xs-12"> <span> {{ client.name }} </span> </li>
<div class ="row">
{% for platform in client.platforms %}
@ -47,26 +60,30 @@
<div class="col-md-1 col-xs-2">
<a href="{{ platform.url }}">
{% if platform.os == 'Windows' %}
<img class="os-icon" src="{% static 'theme/img/windows.png' %}" />
<img class="os-icon" src="{% static 'theme/icons/windows.png' %}" />
{% elif platform.os == 'macOS' %}
<img class="os-icon" src="{% static 'theme/img/apple.png' %}" />
{% elif platform.os == 'Debian' %}
<img class="os-icon" src="{% static 'theme/img/debian.png' %}" />
<img class="os-icon" src="{% static 'theme/icons/apple.png' %}" />
{% elif platform.os == 'GNU/Linux' %}
<img class="os-icon" src="{% static 'theme/icons/gnu-linux.png' %}" />
{% endif %}
</a>
</div>
{% endif %}
{% endfor %}
</div>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
{% if module.clients|has_mobile_clients %}
<div class="clients-info">
{% load static %}
<p class="heading">{% trans "Mobile Clients" %}:</p>
<ul>
{% for client in module.clients %}
{% if client|has_mobile_clients %}
<li class="col-md-12 col-xs-12"><span>{{ client.name }}</span></li>
<div class="row">
{% for platform in client.platforms %}
@ -74,21 +91,25 @@
{% if platform.store_name == 'fdroid_store' %}
<div class="col-md-2 col-xs-4">
<a href="{{ platform.url }}">
<img class="store-icon" src="{% static 'theme/img/f-droid.png' %}"/>
<img class="store-icon" src="{% static 'theme/icons/f-droid.png' %}"/>
</a>
</div>
{% endif %}
{% if platform.store_name == 'google_play_store' %}
<div class="col-md-2 col-xs-4">
<a href="{{ platform.url }}">
<img class="store-icon" src="{% static 'theme/img/google-play.png' %}"/>
<img class="store-icon" src="{% static 'theme/icons/google-play.png' %}"/>
</a>
</div>
{% endif %}
{% endif %}
{% endfor %}
</div>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
</div>
{% endif %}

View File

@ -75,3 +75,7 @@
{% endblock %}
{% endblock %}
<!-- TODO Must get a handle to the clients here somehow -->
{% include "clients.html" with clients=service.clients %}

View File

@ -58,3 +58,30 @@ def show_subsubmenu(context, menu):
"""Mark the active menu item and display the subsubmenu"""
menu = mark_active_menuitem(menu, context['request'].path)
return {'subsubmenu': menu}
def __check(clients, cond):
"""Check if any of a list of clients satisfies the given condition"""
clients = clients if isinstance(clients, list) else [clients]
return any(pf for client in clients for pf in client['platforms']
if cond(pf))
@register.filter(name='has_web_clients')
def has_web_clients(clients):
"""Filter to find out whether an application has web clients"""
return __check(clients, lambda x: x['type'] == 'web')
@register.filter(name='has_mobile_clients')
def has_mobile_clients(clients):
"""Filter to find out whether an application has mobile clients"""
return __check(clients, lambda x: x.get('os', '') == 'Android')
@register.filter(name='has_desktop_clients')
def has_desktop_clients(clients):
"""Filter to find out whether an application has desktop clients"""
return __check(
clients,
lambda x: x.get('os', '') in ['Windows', 'macOS', 'GNU/Linux'])

View File

@ -14,18 +14,22 @@
# 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/>.
#
"""
Test module for custom Django template tags.
"""
import unittest
from plinth.templatetags.plinth_extras import mark_active_menuitem
from plinth.modules.syncthing.manifest import clients as syncthing_clients
from plinth.modules.infinoted.manifest import clients as infinoted_clients
from plinth.modules.deluge.manifest import clients as deluge_clients
from plinth.modules.quassel.manifest import clients as quassel_clients
from plinth.templatetags import plinth_extras
class TestShowSubSubMenu(unittest.TestCase):
"""Verify that the highlighting of the subsubmenu is working correctly"""
def assert_active_url(self, menu, url):
"""Verify that only the given url is set as 'active' in the menu"""
for item in menu:
@ -41,19 +45,45 @@ class TestShowSubSubMenu(unittest.TestCase):
def test_highlighting(self):
"""Test detection of active subsubmenu items using request.path"""
menu = [{'url': '/abc/123/abc/', 'text': 'abc'},
{'url': '/abc/123/', 'text': 'overview'},
{'url': '/abc/123/crunch/', 'text': 'crunch'},
{'url': '/abc/123/create/', 'text': 'create'}]
menu = [{
'url': '/abc/123/abc/',
'text': 'abc'
}, {
'url': '/abc/123/',
'text': 'overview'
}, {
'url': '/abc/123/crunch/',
'text': 'crunch'
}, {
'url': '/abc/123/create/',
'text': 'create'
}]
tests = [['/abc/123/crunch/new/', '/abc/123/crunch/'],
['/abc/123/create/', '/abc/123/create/'],
['/abc/123/nolink/', '/abc/123/'],
['/abc/123/abx/', '/abc/123/'],
['/abc/123/ab/', '/abc/123/'],
['/abc/123/', '/abc/123/']]
tests = [['/abc/123/crunch/new/', '/abc/123/crunch/'], [
'/abc/123/create/', '/abc/123/create/'
], ['/abc/123/nolink/', '/abc/123/'], ['/abc/123/abx/', '/abc/123/'],
['/abc/123/ab/', '/abc/123/'], ['/abc/123/', '/abc/123/']]
for check_path, expected_active_path in tests:
menu = mark_active_menuitem(menu, check_path)
menu = plinth_extras.mark_active_menuitem(menu, check_path)
self.assert_active_url(menu, expected_active_path)
self.assertTrue(self._verify_active_menuitems(menu))
def test_has_web_clients(self):
"""Test for a utility function that returns
whether an application has web clients"""
self.assertTrue(plinth_extras.has_web_clients(syncthing_clients))
self.assertFalse(plinth_extras.has_web_clients(quassel_clients))
def test_has_mobile_clients(self):
"""Test for a utility function that returns
whether an application has mobile clients"""
self.assertTrue(plinth_extras.has_mobile_clients(syncthing_clients))
self.assertFalse(plinth_extras.has_mobile_clients(infinoted_clients))
def test_has_desktop_clients(self):
"""Test for a utility function that returns
whether an application has desktop clients"""
self.assertTrue(
plinth_extras.has_desktop_clients(syncthing_clients[0]))
self.assertFalse(plinth_extras.has_desktop_clients(deluge_clients))

View File

@ -14,7 +14,6 @@
# 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/>.
#
"""
Main Plinth views
"""
@ -48,13 +47,14 @@ def index(request):
disk_views.warn_about_low_disk_space(request)
return TemplateResponse(request, 'index.html',
{'title': _('FreedomBox'),
'shortcuts': shortcuts,
'selected_id': selection,
'details': details,
'details_label': details_label,
'configure_url': configure_url})
return TemplateResponse(request, 'index.html', {
'title': _('FreedomBox'),
'shortcuts': shortcuts,
'selected_id': selection,
'details': details,
'details_label': details_label,
'configure_url': configure_url
})
def system_index(request):
@ -97,8 +97,10 @@ class ServiceView(FormView):
def get_initial(self):
"""Return the status of the service to fill in the form."""
return {'is_enabled': self.service.is_enabled(),
'is_running': self.service.is_running()}
return {
'is_enabled': self.service.is_enabled(),
'is_running': self.service.is_running()
}
def form_valid(self, form):
"""Enable/disable a service and set messages."""

View File

@ -150,3 +150,17 @@ footer license-info p{
.shortcut-label {
min-height:50px;
}
/* Icon when collapsible content is shown */
.btn:after {
font-family: "Glyphicons Halflings";
content: "\e114";
margin-left: 5px;
}
/* Icon when collapsible content is hidden */
.btn.collapsed:after {
content: "\e080";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB