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>
7
.style.yapf
Normal 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
|
||||
11
LICENSES
@ -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]]
|
||||
|
||||
@ -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',
|
||||
}]
|
||||
}]
|
||||
|
||||
@ -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'
|
||||
}]
|
||||
}]
|
||||
|
||||
@ -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'
|
||||
}]
|
||||
}]
|
||||
|
||||
@ -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 '
|
||||
}]
|
||||
}]
|
||||
|
||||
@ -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']
|
||||
|
||||
@ -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'
|
||||
}]
|
||||
}]
|
||||
|
||||
@ -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 %}
|
||||
|
||||
@ -75,3 +75,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
<!-- TODO Must get a handle to the clients here somehow -->
|
||||
{% include "clients.html" with clients=service.clients %}
|
||||
|
||||
|
||||
@ -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'])
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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."""
|
||||
|
||||
@ -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";
|
||||
}
|
||||
|
||||
|
||||
BIN
static/themes/default/icons/app-store.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
BIN
static/themes/default/icons/gnu-linux.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |