From ed08437d38a9bedaf95a4741d079a75b527aef69 Mon Sep 17 00:00:00 2001 From: David THENON Date: Sun, 20 Dec 2015 01:01:57 +0100 Subject: [PATCH] * Updated Manifest to add zip extensions on some systems, related to #44 and #46; * Granted 'bin' extension for roms on Atari2600 system; * Updated basic pip requirement file to fix Django version on 1.8.x for now; * Fixed Makefile action 'install' to use the right pip requirement file path; * Added a global page footer containing the manager version, close #45; * Only display supported extensions for knowed rom systems from manifest, for unknow system ddirs don't filter on file extension, close #40; * Unmount '/admin/' because it's useless and may give back some ressources; * Naive fix to avoid throwing exception on bad encoded filename in rom list view, just ignore it and continue. Related to #39; * Bump to 1.1.3; --- HISTORY.rst | 12 +++++ Makefile | 2 +- README.rst | 2 +- __init__.py | 2 +- compass/scss/_settings.scss | 1 + compass/scss/app.scss | 3 +- compass/scss/components/_footer.scss | 25 ++++++++- package.json | 2 +- pip-requirements/basic.txt | 2 +- project/MANIFEST.xml | 1 + project/manager_frontend/utils/manifest.py | 61 ---------------------- project/manager_frontend/views/roms.py | 37 ++++++++++--- project/manager_frontend/views/systems.py | 2 +- project/recalbox_manifest/__init__.py | 3 +- project/recalbox_manifest/parser.py | 2 - project/recalbox_manifest/registry.py | 2 +- project/settings.py | 5 +- project/templates/skeleton.html | 8 +++ project/urls.py | 2 +- project/utils/context_processors.py | 11 +++- project/webapp_statics/css/app.css | 35 ++++++++++++- 21 files changed, 133 insertions(+), 87 deletions(-) delete mode 100644 project/manager_frontend/utils/manifest.py diff --git a/HISTORY.rst b/HISTORY.rst index 6c7b244..b43e975 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,18 @@ History ======= +Version 1.1.3 - 2015/12/19 +-------------------------- + +* Updated Manifest to add zip extensions on some systems, related to #44 and #46; +* Granted ``bin`` extension for roms on Atari2600 system; +* Updated basic pip requirement file to fix Django version on 1.8.x for now; +* Fixed Makefile action ``install`` to use the right pip requirement file path; +* Added a global page footer containing the manager version, close #45; +* Only display supported extensions for knowed rom systems from manifest, for unknow system ddirs don't filter on file extension, close #40; +* Unmount ``/admin/`` because it's useless and may give back some ressources; +* Naive fix to avoid throwing exception on bad encoded filename in rom list view, just ignore it and continue. Related to #39; + Version 1.1.1 - 2015/11/01 -------------------------- diff --git a/Makefile b/Makefile index 0a1771c..59cba30 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ clean: delpyc install: virtualenv --no-site-packages . - bin/pip install -r requirements.txt + bin/pip install -r pip-requirements/basic.txt bin/python manage.py migrate install-dev: install diff --git a/README.rst b/README.rst index 3f71981..5c9c268 100644 --- a/README.rst +++ b/README.rst @@ -68,7 +68,7 @@ Before doing anything, ensure the Raspberry can access to the internet else conf Go where you want to install the manager directory then type the following commands: :: - wget -q -O - https://raw.githubusercontent.com/sveetch/recalbox-manager/master/deployment/install.sh | bash /dev/stdin --release=1.1.1 + wget -q -O - https://raw.githubusercontent.com/sveetch/recalbox-manager/master/deployment/install.sh | bash /dev/stdin --release=1.1.3 This will download an install script and automatically execute it to proceed to install. diff --git a/__init__.py b/__init__.py index cf59b0e..9a1af79 100644 --- a/__init__.py +++ b/__init__.py @@ -1,4 +1,4 @@ """ Django project to manage a Recalbox from a web interface """ -__version__ = '1.1.1' \ No newline at end of file +__version__ = '1.1.3' \ No newline at end of file diff --git a/compass/scss/_settings.scss b/compass/scss/_settings.scss index 99303d9..1c0c5a9 100644 --- a/compass/scss/_settings.scss +++ b/compass/scss/_settings.scss @@ -13,6 +13,7 @@ $white: #ffffff; $black: #000000; $DarkPastelBlue: #34495e; +$Azure4: #838b8b; // c. Global $base-font-size: 14px; diff --git a/compass/scss/app.scss b/compass/scss/app.scss index e5b968a..026ce6b 100644 --- a/compass/scss/app.scss +++ b/compass/scss/app.scss @@ -92,7 +92,8 @@ @import "vendor-libs/dropzone"; @import "components/header"; -//@import "components/footer"; +@import "components/footer"; + #body_content{ @import "components/contents"; } diff --git a/compass/scss/components/_footer.scss b/compass/scss/components/_footer.scss index fa270f1..b49ba07 100644 --- a/compass/scss/components/_footer.scss +++ b/compass/scss/components/_footer.scss @@ -3,4 +3,27 @@ * All stuff for footer * */ -footer{} \ No newline at end of file +footer{ + margin-top: 2rem; + color: $Azure4; + + &>.row > .columns > p{ + padding-top: 1rem; + padding-bottom: 1rem; + border-top: 1px solid $Azure4; + } + + small{ + font-size: 80%; + } + + p{ + color: inherit; + margin: 0; + line-height: 1.1; + + &+p{ + margin-top: .5rem; + } + } +} \ No newline at end of file diff --git a/package.json b/package.json index 4c52fde..ec78db4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "recalbox-manager", - "version": "0.9.0", + "version": "1.1.3", "private": true, "dependencies": { "debug": "~2.2.0", diff --git a/pip-requirements/basic.txt b/pip-requirements/basic.txt index fd9ce2d..e345823 100644 --- a/pip-requirements/basic.txt +++ b/pip-requirements/basic.txt @@ -1,3 +1,3 @@ # Basic dependancies, common to every versions and environments -django>=1.8 +django>=1.8,<1.9 autobreadcrumbs==1.1 \ No newline at end of file diff --git a/project/MANIFEST.xml b/project/MANIFEST.xml index 8476e77..6258e41 100644 --- a/project/MANIFEST.xml +++ b/project/MANIFEST.xml @@ -3,6 +3,7 @@ a26 + bin zip diff --git a/project/manager_frontend/utils/manifest.py b/project/manager_frontend/utils/manifest.py deleted file mode 100644 index bedccca..0000000 --- a/project/manager_frontend/utils/manifest.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Manifest parser -""" -import json -import xml.etree.cElementTree as ET - -class RecalboxManifestParser(object): - """ - Recalbox XML manifest parser - """ - def __init__(self, filepath): - self.filepath = filepath - - def get_system_extensions(self, node): - if node.find("extensions") is None: - return [] - return [item.text for item in node.find("extensions").findall("extension")] - - def get_system_download_links(self, node): - if node.find("download_links") is None: - return [] - return [item.text for item in node.find("download_links").findall("link")] - - def get_system_bios(self, node): - if node.find("bios") is None: - return [] - return [(item.get('md5', ''), item.text) for item in node.find("bios").findall("file")] - - def get_system_extra_comments(self, node): - if node.find("extra_comments") is None: - return [] - return [item.text for item in node.find("extra_comments").findall("comment")] - - def read(self): - """ - Return the manifest as a Python dictionnary - """ - manifest = {} - - tree = ET.parse(self.filepath) - - root = tree.getroot() - - for node in root: - system_key = node.get('key') - manifest[system_key] = { - 'name': node.get('name'), - 'extensions': self.get_system_extensions(node), - 'download_links': self.get_system_download_links(node), - 'bios': self.get_system_bios(node), - 'extra_comments': self.get_system_extra_comments(node), - } - - return manifest - - def json(self): - """ - Return the manifest as a JSON string - """ - return json.dumps(self.read(), indent=4) diff --git a/project/manager_frontend/views/roms.py b/project/manager_frontend/views/roms.py index 4b896ac..ef8fac6 100644 --- a/project/manager_frontend/views/roms.py +++ b/project/manager_frontend/views/roms.py @@ -45,14 +45,37 @@ def init_system(self): # Get the system manifest part if any, else a default dict self.system_manifest = RECALBOX_MANIFEST.get(self.system_key, default_manifest) - def get_rom_choices(self): - rom_list = [] + def get_rom_choices(self, force=False): + """ + Return rom files as a choice list for form + + Don't list hided files and directories. + + If system is a supported system in manifest, filter files so only + supported rom type is listed, else dont filter on file extension. - for item in os.listdir(self.system_path): - if os.path.isfile(os.path.join(self.system_path, item)) and not item.startswith('.'): - rom_list.append( (item, os.path.getsize(os.path.join(self.system_path, item))) ) + Use some internal memory cache to not digg the dir each time, use + force=True to bypass the cache + """ + cache_key = '_get_rom_choices_cache' + if force or not hasattr(self, cache_key): + rom_list = [] + system_extensions = ['.{}'.format(k) for k in self.system_manifest.get('extensions', [])] + + for item in os.listdir(self.system_path): + try: + if os.path.isfile(os.path.join(self.system_path, item)) and not item.startswith('.'): + if system_extensions and os.path.splitext(item)[-1] not in system_extensions: + continue + rom_list.append( (item, os.path.getsize(os.path.join(self.system_path, item))) ) + # Issue #39: Naive fix to avoid throwing exception on bad encoded + # filename, just ignore it and continue. + except UnicodeDecodeError: + continue + + setattr(self, cache_key, tuple( sorted(rom_list, key=itemgetter(0)) )) - return tuple( sorted(rom_list, key=itemgetter(0)) ) + return getattr(self, cache_key) def get_context_data(self, **kwargs): context = super(RomListView, self).get_context_data(**kwargs) @@ -107,7 +130,7 @@ def post(self, request, *args, **kwargs): class RomUploadJsonView(JsonMixin, RomListView): """ - Inherit from RomListView to be similary but gives only response in JSON + Inherit from RomListView to be similary but only response in JSON Also the delete form should not really be used here """ diff --git a/project/manager_frontend/views/systems.py b/project/manager_frontend/views/systems.py index 55e78ec..d879abf 100644 --- a/project/manager_frontend/views/systems.py +++ b/project/manager_frontend/views/systems.py @@ -26,7 +26,7 @@ def get_system_list(self): existing_sys = [] available_sys = [] - # Get systems allready existing as directories + # Get existing systems as directories for item in os.listdir(path): # Only display directories if os.path.isdir(os.path.join(path, item)) and not item.startswith('.'): diff --git a/project/recalbox_manifest/__init__.py b/project/recalbox_manifest/__init__.py index 79f80a7..b8db9fc 100644 --- a/project/recalbox_manifest/__init__.py +++ b/project/recalbox_manifest/__init__.py @@ -6,8 +6,7 @@ def autodiscover(): """ - Dummy loader actually, this should be backward compatible for futur assets - discovery per app + Simple manifest loader """ from django.conf import settings from .parser import RecalboxManifestParser diff --git a/project/recalbox_manifest/parser.py b/project/recalbox_manifest/parser.py index acd0251..bedccca 100644 --- a/project/recalbox_manifest/parser.py +++ b/project/recalbox_manifest/parser.py @@ -38,8 +38,6 @@ def read(self): """ manifest = {} - print "self.filepath:", self.filepath - tree = ET.parse(self.filepath) root = tree.getroot() diff --git a/project/recalbox_manifest/registry.py b/project/recalbox_manifest/registry.py index b1fb9a3..5bc1088 100644 --- a/project/recalbox_manifest/registry.py +++ b/project/recalbox_manifest/registry.py @@ -2,5 +2,5 @@ """ Recalbox manifest registry """ -# Just a dummy dict waiting to be filled +# Just an empty dict waiting to be filled manifest = {} diff --git a/project/settings.py b/project/settings.py index 97f9b54..1528b02 100644 --- a/project/settings.py +++ b/project/settings.py @@ -13,7 +13,7 @@ # Build paths inside the project like this: os.path.join(BASE_DIR, ...) import os -from manager_frontend.utils.manifest import RecalboxManifestParser +#from manager_frontend.utils.manifest import RecalboxManifestParser gettext = lambda s: s @@ -93,6 +93,7 @@ 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'project.utils.context_processors.site_metas', + 'project.utils.context_processors.manager_version', 'autobreadcrumbs.context_processors.AutoBreadcrumbsContext', ], }, @@ -181,7 +182,7 @@ # Path to the Recalbox manifest file (actually shipped into manager project) RECALBOX_MANIFEST_FILEPATH = os.path.join(PROJECT_DIR, 'MANIFEST.xml') -# Default empty entry for a system unknowed from Manifest +# Default empty entry for unknowed system from Manifest RECALBOX_SYSTEM_DEFAULT = { 'name': 'Unknow', 'extensions': [], diff --git a/project/templates/skeleton.html b/project/templates/skeleton.html index 7b2efeb..be79532 100644 --- a/project/templates/skeleton.html +++ b/project/templates/skeleton.html @@ -72,6 +72,14 @@ {% block base_content %}{% endblock %} {% endblock %} + {% block footer_container %}{% endblock %} + {% block page_more_js %} {% javascript_tag "js/app.min.js" %} {% endblock %} diff --git a/project/urls.py b/project/urls.py index 7536b29..a6302f2 100644 --- a/project/urls.py +++ b/project/urls.py @@ -31,7 +31,7 @@ recalbox_manifest.autodiscover() urlpatterns = [ - url(r'^admin/', include(admin.site.urls)), + #url(r'^admin/', include(admin.site.urls)), url(r'^', include('project.manager_frontend.urls', namespace='manager')), ] diff --git a/project/utils/context_processors.py b/project/utils/context_processors.py index c35dff2..299d07f 100644 --- a/project/utils/context_processors.py +++ b/project/utils/context_processors.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- -import socket +import imp, os, socket from django.conf import settings - def get_host_ipaddress(): """ Little trick to get all host ip address @@ -76,6 +75,14 @@ def get_site_metas(with_static=False, with_media=False, is_secure=False, return metas +def manager_version(request): + """ + Context processor to add the recalbox-manager version + """ + # Tricky way to know the manager version because its version lives out of project path + root = imp.load_source('__init__', os.path.join(settings.BASE_DIR, '__init__.py')) + return {'manager_version': root.__version__} + def site_metas(request): """ Context processor to add the current *Site* metas to the context diff --git a/project/webapp_statics/css/app.css b/project/webapp_statics/css/app.css index 66996bb..4cc4f57 100644 --- a/project/webapp_statics/css/app.css +++ b/project/webapp_statics/css/app.css @@ -10795,7 +10795,40 @@ html.no-flexbox .flex-grid { line-height: inherit; } -/* line 96, ../../../compass/scss/app.scss */ +/* + * + * All stuff for footer + * + */ +/* line 6, ../../../compass/scss/components/_footer.scss */ +footer { + margin-top: 2rem; + color: #838b8b; +} +/* line 10, ../../../compass/scss/components/_footer.scss */ +footer > .row > .columns > p, html.no-flexbox footer > .flex-inline-list > .columns > p, +html.no-flexbox footer > .flex-grid > .columns > p, html.no-flexbox footer > .flex-inline-list > .cell > p, +html.no-flexbox footer > .flex-grid > .cell > p { + padding-top: 1rem; + padding-bottom: 1rem; + border-top: 1px solid #838b8b; +} +/* line 16, ../../../compass/scss/components/_footer.scss */ +footer small { + font-size: 80%; +} +/* line 20, ../../../compass/scss/components/_footer.scss */ +footer p { + color: inherit; + margin: 0; + line-height: 1.1; +} +/* line 25, ../../../compass/scss/components/_footer.scss */ +footer p + p { + margin-top: .5rem; +} + +/* line 97, ../../../compass/scss/app.scss */ #body_content { /* * Breadcrumbs customize