Fix handling of unicode filename downloads
Add photo attribute dot_extension Fix bug using unnormalized offset in calculations
This commit is contained in:
parent
0d0431edff
commit
a305350f5f
5 changed files with 24 additions and 16 deletions
15
etiquette.py
15
etiquette.py
|
@ -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})
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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']
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 -->
|
||||||
|
|
Loading…
Reference in a new issue