diff --git a/combo/apps/assets/views.py b/combo/apps/assets/views.py index b2616722..991a9e00 100644 --- a/combo/apps/assets/views.py +++ b/combo/apps/assets/views.py @@ -23,6 +23,7 @@ from django.core.exceptions import PermissionDenied from django.core.files.storage import default_storage from django.core.urlresolvers import reverse, reverse_lazy from django.http import Http404, HttpResponse +from django.shortcuts import get_object_or_404 from django.shortcuts import redirect from django.utils.six import BytesIO from django.utils.translation import ugettext_lazy as _ @@ -296,8 +297,25 @@ def assets_export(request, *args, **kwargs): def serve_asset(request, key): - try: - asset = Asset.objects.get(key=key) - return redirect(asset.asset.url) - except (Asset.DoesNotExist, AttributeError): + asset = get_object_or_404(Asset, key=key) + + if not os.path.exists(asset.asset.path): raise Http404() + + # get options for thumbnail + thumb_options = request.GET.dict() + width = thumb_options.pop('width', None) + height = thumb_options.pop('height', None) + + geometry_string = '' + if width: + geometry_string += width + if height: + geometry_string += 'x%s' % height + + # no thumbnail whithout geometry_string or for a svg file + if not geometry_string or asset.asset.name.endswith('svg'): + return redirect(asset.asset.url) + + # get or create thumbnail and return url + return redirect(get_thumbnail(asset.asset, geometry_string, **thumb_options).url) diff --git a/tests/test_manager.py b/tests/test_manager.py index 3cb0ecd1..da14d57b 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -960,6 +960,59 @@ def test_asset_slots_management(app, admin_user): assert '>CGU<' in resp.text +def test_serve_asset(settings, app, admin_user): + settings.COMBO_ASSET_SLOTS = {'collectivity:banner': {'label': 'Banner'}} + app = login(app) + + resp = app.get('/manage/assets/') + assert '>Banner<' in resp.text + assert '>Delete<' not in resp.text + resp = resp.click('Overwrite') + resp.form['upload'] = Upload( + 'test.png', + base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAgAABAADRWoApgAA\nAABJRU5ErkJggg=='), + 'image/png') + resp = resp.form.submit().follow() + assert Asset.objects.filter(key='collectivity:banner').count() == 1 + asset = Asset.objects.latest('pk') + + assert app.get('/assets/collectivity:banner', status=302)['location'].endswith('test.png') + assert app.get('/assets/collectivity:banner?width=200', status=302)['location'].startswith('/media/cache/') + assert app.get('/assets/collectivity:banner?height=200', status=302)['location'].startswith('/media/cache/') + assert app.get('/assets/collectivity:banner?crop=center', status=302)['location'].endswith('test.png') + assert app.get('/assets/collectivity:banner?width=200&crop=center', status=302)['location'].startswith('/media/cache/') + + # file is missing + os.remove(asset.asset.path) + app.get('/assets/collectivity:banner', status=404) + + # upload a SVG + resp = resp.click('Delete') + resp = resp.form.submit() + assert Asset.objects.filter(key='collectivity:banner').count() == 0 + + resp = app.get('/manage/assets/') + assert '>Banner<' in resp.text + assert '>Delete<' not in resp.text + resp = resp.click('Overwrite') + resp.form['upload'] = Upload( + 'test.svg', + base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAgAABAADRWoApgAA\nAABJRU5ErkJggg=='), + 'image/svg+xml') + resp = resp.form.submit() + assert Asset.objects.filter(key='collectivity:banner').count() == 1 + + # SVG: no thumbnail ! + assert app.get('/assets/collectivity:banner', status=302)['location'].endswith('test.svg') + assert app.get('/assets/collectivity:banner?width=200', status=302)['location'].endswith('test.svg') + assert app.get('/assets/collectivity:banner?height=200', status=302)['location'].endswith('test.svg') + assert app.get('/assets/collectivity:banner?crop=center', status=302)['location'].endswith('test.svg') + assert app.get('/assets/collectivity:banner?width=200&crop=center', status=302)['location'].endswith('test.svg') + + # unknown Asset key + app.get('/assets/foo:bar', status=404) + + def test_asset_export_import(app, admin_user): for path in ('uploads', 'assets', 'cache'): if os.path.exists(default_storage.path(path)):