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/tahoe.png :: [[https://github.com/thekishanraval/Logos][GPLv3+]]
- static/themes/default/icons/transmission.png :: [[https://transmissionbt.com/][GPL]] - 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/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/icons/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/icons/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/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/img/apple.png :: [[https://thenounproject.com/icon/1203053/download/color/000000/png][CC BY 3.0 US]] - static/themes/default/icons/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/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 _ from django.utils.translation import ugettext_lazy as _
clients = [ clients = [{
{ 'name':
'name': _('Deluge'), _('Deluge'),
'description': _('Bittorrent client written in Python/PyGTK '), 'description':
'platforms': [ _('Bittorrent client written in Python/PyGTK '),
{ 'platforms': [{
'type': 'web', 'type': 'web',
'relative_path': '/deluge' 'relative_path': '/deluge'
}, }, {
{ 'type': 'package',
'type': 'apt', 'format': 'deb',
'os': 'Debian', 'name': 'deluge',
'package_name': 'deluge'
}]
}] }]
}]

View File

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

View File

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

View File

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

View File

@ -67,7 +67,8 @@ service = None
def init(): def init():
"""Intialize the module.""" """Intialize the module."""
menu = main_menu.get('apps') 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 global service
setup_helper = globals()['setup_helper'] setup_helper = globals()['setup_helper']

View File

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

View File

@ -18,12 +18,21 @@
{% endcomment %} {% endcomment %}
{% load i18n %} {% load i18n %}
{% load plinth_extras %}
{% if module.clients %} {% 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"> <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 module.clients %}
{% if client|has_web_clients %}
{% for platform in client.platforms %} {% for platform in client.platforms %}
{% if platform.type == 'web' %} {% if platform.type == 'web' %}
<li> <li>
@ -31,15 +40,19 @@
</li> </li>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% endif %}
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
{% endif %}
{% if module.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 module.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">
{% for platform in client.platforms %} {% for platform in client.platforms %}
@ -47,26 +60,30 @@
<div class="col-md-1 col-xs-2"> <div class="col-md-1 col-xs-2">
<a href="{{ platform.url }}"> <a href="{{ platform.url }}">
{% if platform.os == 'Windows' %} {% 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' %} {% elif platform.os == 'macOS' %}
<img class="os-icon" src="{% static 'theme/img/apple.png' %}" /> <img class="os-icon" src="{% static 'theme/icons/apple.png' %}" />
{% elif platform.os == 'Debian' %} {% elif platform.os == 'GNU/Linux' %}
<img class="os-icon" src="{% static 'theme/img/debian.png' %}" /> <img class="os-icon" src="{% static 'theme/icons/gnu-linux.png' %}" />
{% endif %} {% endif %}
</a> </a>
</div> </div>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</div> </div>
{% endif %}
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
{% endif %}
{% if module.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 module.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">
{% for platform in client.platforms %} {% for platform in client.platforms %}
@ -74,21 +91,25 @@
{% if platform.store_name == 'fdroid_store' %} {% if platform.store_name == 'fdroid_store' %}
<div class="col-md-2 col-xs-4"> <div class="col-md-2 col-xs-4">
<a href="{{ platform.url }}"> <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> </a>
</div> </div>
{% endif %} {% endif %}
{% if platform.store_name == 'google_play_store' %} {% if platform.store_name == 'google_play_store' %}
<div class="col-md-2 col-xs-4"> <div class="col-md-2 col-xs-4">
<a href="{{ platform.url }}"> <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> </a>
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</div> </div>
{% endif %}
{% endfor %} {% endfor %}
</ul> </ul>
</div>
{% endif %}
</div> </div>
{% endif %} {% endif %}

View File

@ -75,3 +75,7 @@
{% endblock %} {% endblock %}
{% 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""" """Mark the active menu item and display the subsubmenu"""
menu = mark_active_menuitem(menu, context['request'].path) menu = mark_active_menuitem(menu, context['request'].path)
return {'subsubmenu': menu} 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 # 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/>.
# #
""" """
Test module for custom Django template tags. Test module for custom Django template tags.
""" """
import unittest 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): class TestShowSubSubMenu(unittest.TestCase):
"""Verify that the highlighting of the subsubmenu is working correctly""" """Verify that the highlighting of the subsubmenu is working correctly"""
def assert_active_url(self, menu, url): def assert_active_url(self, menu, url):
"""Verify that only the given url is set as 'active' in the menu""" """Verify that only the given url is set as 'active' in the menu"""
for item in menu: for item in menu:
@ -41,19 +45,45 @@ class TestShowSubSubMenu(unittest.TestCase):
def test_highlighting(self): def test_highlighting(self):
"""Test detection of active subsubmenu items using request.path""" """Test detection of active subsubmenu items using request.path"""
menu = [{'url': '/abc/123/abc/', 'text': 'abc'}, menu = [{
{'url': '/abc/123/', 'text': 'overview'}, 'url': '/abc/123/abc/',
{'url': '/abc/123/crunch/', 'text': 'crunch'}, 'text': 'abc'
{'url': '/abc/123/create/', 'text': 'create'}] }, {
'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/'], tests = [['/abc/123/crunch/new/', '/abc/123/crunch/'], [
['/abc/123/create/', '/abc/123/create/'], '/abc/123/create/', '/abc/123/create/'
['/abc/123/nolink/', '/abc/123/'], ], ['/abc/123/nolink/', '/abc/123/'], ['/abc/123/abx/', '/abc/123/'],
['/abc/123/abx/', '/abc/123/'], ['/abc/123/ab/', '/abc/123/'], ['/abc/123/', '/abc/123/']]
['/abc/123/ab/', '/abc/123/'],
['/abc/123/', '/abc/123/']]
for check_path, expected_active_path in tests: 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.assert_active_url(menu, expected_active_path)
self.assertTrue(self._verify_active_menuitems(menu)) 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 # 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/>.
# #
""" """
Main Plinth views Main Plinth views
""" """
@ -48,13 +47,14 @@ def index(request):
disk_views.warn_about_low_disk_space(request) disk_views.warn_about_low_disk_space(request)
return TemplateResponse(request, 'index.html', return TemplateResponse(request, 'index.html', {
{'title': _('FreedomBox'), 'title': _('FreedomBox'),
'shortcuts': shortcuts, 'shortcuts': shortcuts,
'selected_id': selection, 'selected_id': selection,
'details': details, 'details': details,
'details_label': details_label, 'details_label': details_label,
'configure_url': configure_url}) 'configure_url': configure_url
})
def system_index(request): def system_index(request):
@ -97,8 +97,10 @@ class ServiceView(FormView):
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 {'is_enabled': self.service.is_enabled(), return {
'is_running': self.service.is_running()} 'is_enabled': self.service.is_enabled(),
'is_running': self.service.is_running()
}
def form_valid(self, form): def form_valid(self, form):
"""Enable/disable a service and set messages.""" """Enable/disable a service and set messages."""

View File

@ -150,3 +150,17 @@ footer license-info p{
.shortcut-label { .shortcut-label {
min-height:50px; 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