Fix handling of unicode filename downloads

Add photo attribute dot_extension

Fix bug using unnormalized offset in calculations
This commit is contained in:
voussoir 2016-12-24 18:34:34 -08:00
parent 0d0431edff
commit a305350f5f
5 changed files with 24 additions and 16 deletions

View file

@ -4,6 +4,7 @@ import json
import mimetypes import mimetypes
import os import os
import random import random
import urllib.parse
import warnings import warnings
import zipstream import zipstream
@ -303,10 +304,10 @@ def get_album_zip(albumid):
download_as = '%s - %s.zip' % (album.id, album.title) download_as = '%s - %s.zip' % (album.id, album.title)
else: else:
download_as = '%s.zip' % album.id download_as = '%s.zip' % album.id
download_as = download_as.replace('"', '\\"') download_as = urllib.parse.quote(download_as)
outgoing_headers = { outgoing_headers = {
'Content-Type': 'application/octet-stream', 'Content-Type': 'application/octet-stream',
'Content-Disposition': 'attachment; filename=%s' % download_as, 'Content-Disposition': 'attachment; filename*=UTF-8\'\'%s' % download_as,
} }
return flask.Response(streamed_zip, headers=outgoing_headers) return flask.Response(streamed_zip, headers=outgoing_headers)
@ -354,13 +355,11 @@ def get_file(photoid):
if use_original_filename: if use_original_filename:
download_as = photo.basename download_as = photo.basename
else: else:
download_as = photo.id download_as = photo.id + photo.dot_extension
if photo.extension:
download_as += photo.extension
download_as = download_as.replace('"', '\\"') download_as = urllib.parse.quote(download_as)
response = flask.make_response(send_file(photo.real_filepath)) response = flask.make_response(send_file(photo.real_filepath))
response.headers['Content-Disposition'] = 'attachment; filename="%s"' % download_as response.headers['Content-Disposition'] = 'attachment; filename*=UTF-8\'\'%s' % download_as
return response return response
else: else:
return send_file(photo.real_filepath) return send_file(photo.real_filepath)
@ -485,7 +484,7 @@ def get_search_core():
total_tags = sorted(total_tags) total_tags = sorted(total_tags)
# PREV-NEXT PAGE URLS # PREV-NEXT PAGE URLS
offset = offset or 0 offset = search_kwargs['offset'] or 0
original_params = request.args.to_dict() original_params = request.args.to_dict()
if len(photos) == limit: if len(photos) == limit:
next_params = helpers.edit_params(original_params, {'offset': offset + limit}) next_params = helpers.edit_params(original_params, {'offset': offset + limit})

View file

@ -191,9 +191,6 @@ def is_xor(*args):
''' '''
return [bool(a) for a in args].count(True) == 1 return [bool(a) for a in args].count(True) == 1
def normalize_extension(extension):
pass
def normalize_filepath(filepath, allowed=''): def normalize_filepath(filepath, allowed=''):
''' '''
Remove some bad characters. Remove some bad characters.

View file

@ -292,6 +292,11 @@ class Photo(ObjectBase):
self.extension = row_tuple['extension'] self.extension = row_tuple['extension']
self.tagged_at = row_tuple['tagged_at'] self.tagged_at = row_tuple['tagged_at']
if self.extension == '':
self.dot_extension = ''
else:
self.dot_extension = '.' + self.extension
self.area = row_tuple['area'] self.area = row_tuple['area']
self.bytes = row_tuple['bytes'] self.bytes = row_tuple['bytes']
self.duration = row_tuple['duration'] self.duration = row_tuple['duration']

View file

@ -567,6 +567,7 @@ class PDBPhotoMixin:
extension_not: extension_not:
A string or list of strings of unacceptable file extensions. A string or list of strings of unacceptable file extensions.
Including '*' will forbid all extensions
filename: filename:
A string or list of strings which will be split into words. The file's basename A string or list of strings which will be split into words. The file's basename
@ -722,7 +723,14 @@ class PDBPhotoMixin:
#print('Failed extension') #print('Failed extension')
continue continue
if extension_not and photo.extension in extension_not: ext_fail = (
extension_not and
(
('*' in extension_not and photo.extension) or
(photo.extension in extension_not)
)
)
if (ext_fail):
#print('Failed extension_not') #print('Failed extension_not')
continue continue

View file

@ -6,7 +6,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="stylesheet" href="/static/common.css"> <link rel="stylesheet" href="/static/common.css">
<script src="/static/common.js"></script> <script src="/static/common.js"></script>
{% set filename = photo.id + "." + photo.extension %} {% set filename = photo.id + photo.dot_extension %}
{% set link = "/file/" + filename %} {% set link = "/file/" + filename %}
<style> <style>
@ -122,9 +122,8 @@
{% if photo.duration %} {% if photo.duration %}
<li>Duration: {{photo.duration_string()}}</li> <li>Duration: {{photo.duration_string()}}</li>
{% endif %} {% endif %}
{% set extension= "." + photo.extension if photo.extension != "" else "" %} <li><a href="/file/{{photo.id}}{{photo.dot_extension}}?download=1">Download as {{photo.id}}.{{photo.extension}}</a></li>
<li><a href="/file/{{photo.id}}{{extension}}?download=1">Download as {{photo.id}}.{{photo.extension}}</a></li> <li><a href="/file/{{photo.id}}{{photo.dot_extension}}?download=1&original_filename=1">Download as "{{photo.basename}}"</a></li>
<li><a href="/file/{{photo.id}}{{extension}}?download=1&original_filename=1">Download as "{{photo.basename}}"</a></li>
</ul> </ul>
<!-- CONTAINING ALBUMS --> <!-- CONTAINING ALBUMS -->