diff --git a/.style.yapf b/.style.yapf new file mode 100644 index 000000000..03ac89877 --- /dev/null +++ b/.style.yapf @@ -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 \ No newline at end of file diff --git a/LICENSES b/LICENSES index 9888fd05b..f9652eb6b 100644 --- a/LICENSES +++ b/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]] diff --git a/plinth/modules/deluge/manifest.py b/plinth/modules/deluge/manifest.py index 3306ecb7b..cb2d542c6 100644 --- a/plinth/modules/deluge/manifest.py +++ b/plinth/modules/deluge/manifest.py @@ -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', }] +}] diff --git a/plinth/modules/minetest/manifest.py b/plinth/modules/minetest/manifest.py index 394c21461..1ef242008 100644 --- a/plinth/modules/minetest/manifest.py +++ b/plinth/modules/minetest/manifest.py @@ -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' + }] +}] diff --git a/plinth/modules/mumble/manifest.py b/plinth/modules/mumble/manifest.py index 5661773c4..3056cd9f5 100644 --- a/plinth/modules/mumble/manifest.py +++ b/plinth/modules/mumble/manifest.py @@ -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' + }] +}] diff --git a/plinth/modules/repro/manifest.py b/plinth/modules/repro/manifest.py index d3022d4cc..6f1490a13 100644 --- a/plinth/modules/repro/manifest.py +++ b/plinth/modules/repro/manifest.py @@ -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 ' + }] +}] diff --git a/plinth/modules/syncthing/__init__.py b/plinth/modules/syncthing/__init__.py index da667460e..b1aa02ce4 100644 --- a/plinth/modules/syncthing/__init__.py +++ b/plinth/modules/syncthing/__init__.py @@ -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'] diff --git a/plinth/modules/syncthing/manifest.py b/plinth/modules/syncthing/manifest.py index 15ba3d943..da00f1545 100644 --- a/plinth/modules/syncthing/manifest.py +++ b/plinth/modules/syncthing/manifest.py @@ -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' + }] +}] diff --git a/plinth/templates/clients.html b/plinth/templates/clients.html index d17b37dec..213fb4f12 100644 --- a/plinth/templates/clients.html +++ b/plinth/templates/clients.html @@ -18,28 +18,41 @@ {% endcomment %} {% load i18n %} +{% load plinth_extras %} {% if module.clients %} + + +
+{% if module.clients|has_web_clients %}

{% trans "Web Clients" %}:

+{% endif %} +{% if module.clients|has_desktop_clients %}
{% load static %}

{% trans "Desktop Clients" %}:

+{% endif %} +{% if module.clients|has_mobile_clients %}
{% load static %}

{% trans "Mobile Clients" %}:

+
+ {% endif %} +
{% endif %} diff --git a/plinth/templates/service.html b/plinth/templates/service.html index 549a8e63d..31908381e 100644 --- a/plinth/templates/service.html +++ b/plinth/templates/service.html @@ -75,3 +75,7 @@ {% endblock %} {% endblock %} + + +{% include "clients.html" with clients=service.clients %} + diff --git a/plinth/templatetags/plinth_extras.py b/plinth/templatetags/plinth_extras.py index b862887ee..14bafd2b4 100644 --- a/plinth/templatetags/plinth_extras.py +++ b/plinth/templatetags/plinth_extras.py @@ -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']) diff --git a/plinth/tests/test_templatetags.py b/plinth/tests/test_templatetags.py index b24334d9c..f47cfb9a3 100644 --- a/plinth/tests/test_templatetags.py +++ b/plinth/tests/test_templatetags.py @@ -14,18 +14,22 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ 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)) diff --git a/plinth/views.py b/plinth/views.py index 8dcc1d6a3..efb8b363f 100644 --- a/plinth/views.py +++ b/plinth/views.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ 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.""" diff --git a/static/themes/default/css/plinth.css b/static/themes/default/css/plinth.css index 5b3c49958..35e14ca92 100644 --- a/static/themes/default/css/plinth.css +++ b/static/themes/default/css/plinth.css @@ -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"; +} + diff --git a/static/themes/default/icons/app-store.png b/static/themes/default/icons/app-store.png new file mode 100644 index 000000000..1842b0fae Binary files /dev/null and b/static/themes/default/icons/app-store.png differ diff --git a/static/themes/default/img/apple.png b/static/themes/default/icons/apple.png similarity index 100% rename from static/themes/default/img/apple.png rename to static/themes/default/icons/apple.png diff --git a/static/themes/default/img/f-droid.png b/static/themes/default/icons/f-droid.png similarity index 100% rename from static/themes/default/img/f-droid.png rename to static/themes/default/icons/f-droid.png diff --git a/static/themes/default/icons/gnu-linux.png b/static/themes/default/icons/gnu-linux.png new file mode 100644 index 000000000..b02c6edb0 Binary files /dev/null and b/static/themes/default/icons/gnu-linux.png differ diff --git a/static/themes/default/img/google-play.png b/static/themes/default/icons/google-play.png similarity index 100% rename from static/themes/default/img/google-play.png rename to static/themes/default/icons/google-play.png diff --git a/static/themes/default/img/windows.png b/static/themes/default/icons/windows.png similarity index 100% rename from static/themes/default/img/windows.png rename to static/themes/default/icons/windows.png diff --git a/static/themes/default/img/debian.png b/static/themes/default/img/debian.png deleted file mode 100644 index 78db4dbfc..000000000 Binary files a/static/themes/default/img/debian.png and /dev/null differ