mirror of
https://github.com/jazzband/django-downloadview.git
synced 2026-03-16 22:40:25 +00:00
Refs #46 -- Add Py3 support.
This commit is contained in:
parent
6232fcb736
commit
1ea2790ba9
11 changed files with 34 additions and 21 deletions
|
|
@ -1,6 +1,7 @@
|
|||
language: python
|
||||
env:
|
||||
- TOXENV=py27
|
||||
- TOXENV=py33
|
||||
- TOXENV=flake8
|
||||
- TOXENV=sphinx
|
||||
- TOXENV=readme
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from StringIO import StringIO
|
||||
from six import StringIO
|
||||
|
||||
from django.core.files.base import ContentFile
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ from django_downloadview import StringIteratorIO
|
|||
class TextDownloadView(VirtualDownloadView):
|
||||
def get_file(self):
|
||||
"""Return :class:`django.core.files.base.ContentFile` object."""
|
||||
return ContentFile(u"Hello world!\n", name='hello-world.txt')
|
||||
return ContentFile(b"Hello world!\n", name='hello-world.txt')
|
||||
|
||||
|
||||
class StringIODownloadView(VirtualDownloadView):
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from six import iteritems
|
||||
from django_downloadview.apache.response import XSendfileResponse
|
||||
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ class XSendfileValidator(object):
|
|||
|
||||
"""
|
||||
self.assert_x_sendfile_response(test_case, response)
|
||||
for key, value in assertions.iteritems():
|
||||
for key, value in iteritems(assertions):
|
||||
assert_func = getattr(self, 'assert_%s' % key)
|
||||
assert_func(test_case, response, value)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"""File wrappers for use as exchange data between views and responses."""
|
||||
from __future__ import absolute_import
|
||||
from io import BytesIO
|
||||
from urlparse import urlparse
|
||||
from six.moves.urllib.parse import urlparse
|
||||
|
||||
from django.core.files.base import File
|
||||
from django.utils.encoding import force_bytes
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from six import iteritems
|
||||
from django_downloadview.nginx.response import XAccelRedirectResponse
|
||||
|
||||
|
||||
|
|
@ -35,7 +36,7 @@ class XAccelRedirectValidator(object):
|
|||
|
||||
"""
|
||||
self.assert_x_accel_redirect_response(test_case, response)
|
||||
for key, value in assertions.iteritems():
|
||||
for key, value in iteritems(assertions):
|
||||
assert_func = getattr(self, 'assert_%s' % key)
|
||||
assert_func(test_case, response, value)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ import os
|
|||
import mimetypes
|
||||
import re
|
||||
import unicodedata
|
||||
import urllib
|
||||
import six
|
||||
from six.moves import urllib
|
||||
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponse, StreamingHttpResponse
|
||||
|
|
@ -14,28 +15,31 @@ from django.utils.encoding import force_str
|
|||
def encode_basename_ascii(value):
|
||||
"""Return US-ASCII encoded ``value`` for use in Content-Disposition header.
|
||||
|
||||
>>> encode_basename_ascii(unicode('éà', 'utf-8'))
|
||||
>>> encode_basename_ascii('éà') # doctest: +IGNORE_UNICODE
|
||||
u'ea'
|
||||
|
||||
Spaces are converted to underscores.
|
||||
|
||||
>>> encode_basename_ascii(' ')
|
||||
>>> encode_basename_ascii(' ') # doctest: +IGNORE_UNICODE
|
||||
u'_'
|
||||
|
||||
Text with non US-ASCII characters is expected to be unicode.
|
||||
|
||||
>>> encode_basename_ascii('éà') # doctest: +ELLIPSIS
|
||||
>>> from six import b
|
||||
>>> encode_basename_ascii(b('éà')) # doctest: +ELLIPSIS
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
UnicodeDecodeError: \'ascii\' codec can\'t decode byte ...
|
||||
UnicodeDecodeError: ...
|
||||
|
||||
Of course, ASCII values are not modified.
|
||||
|
||||
>>> encode_basename_ascii('ea')
|
||||
>>> encode_basename_ascii('ea') # doctest: +IGNORE_UNICODE
|
||||
u'ea'
|
||||
|
||||
"""
|
||||
ascii_basename = unicode(value)
|
||||
if isinstance(value, six.binary_type):
|
||||
value = value.decode('utf-8')
|
||||
ascii_basename = six.text_type(value)
|
||||
ascii_basename = unicodedata.normalize('NFKD', ascii_basename)
|
||||
ascii_basename = ascii_basename.encode('ascii', 'ignore')
|
||||
ascii_basename = ascii_basename.decode('ascii')
|
||||
|
|
@ -49,11 +53,11 @@ def encode_basename_utf8(value):
|
|||
>>> encode_basename_utf8(u' .txt')
|
||||
'%20.txt'
|
||||
|
||||
>>> encode_basename_utf8(unicode('éà', 'utf-8'))
|
||||
>>> encode_basename_utf8(u'éà')
|
||||
'%C3%A9%C3%A0'
|
||||
|
||||
"""
|
||||
return urllib.quote(force_str(value))
|
||||
return urllib.parse.quote(force_str(value))
|
||||
|
||||
|
||||
def content_disposition(filename):
|
||||
|
|
@ -70,7 +74,7 @@ def content_disposition(filename):
|
|||
If filename contains non US-ASCII characters, the returned value contains
|
||||
UTF-8 encoded filename and US-ASCII fallback.
|
||||
|
||||
>>> content_disposition(unicode('é.txt', 'utf-8'))
|
||||
>>> content_disposition(u'é.txt')
|
||||
"attachment; filename=e.txt; filename*=UTF-8''%C3%A9.txt"
|
||||
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""Testing utilities."""
|
||||
import shutil
|
||||
from six import iteritems
|
||||
import tempfile
|
||||
|
||||
from django.conf import settings
|
||||
|
|
@ -101,7 +102,7 @@ class DownloadResponseValidator(object):
|
|||
|
||||
"""
|
||||
self.assert_download_response(test_case, response)
|
||||
for key, value in assertions.iteritems():
|
||||
for key, value in iteritems(assertions):
|
||||
assert_func = getattr(self, 'assert_%s' % key)
|
||||
assert_func(test_case, response, value)
|
||||
|
||||
|
|
@ -138,7 +139,9 @@ class DownloadResponseValidator(object):
|
|||
test_case.assertTrue(response['Content-Type'].startswith(value))
|
||||
|
||||
def assert_content(self, test_case, response, value):
|
||||
test_case.assertEqual(''.join(response.streaming_content), value)
|
||||
test_case.assertEqual(
|
||||
''.join([s.decode('utf-8') for s in response.streaming_content]),
|
||||
value)
|
||||
|
||||
def assert_attachment(self, test_case, response, value):
|
||||
test_case.assertEqual('attachment;' in response['Content-Disposition'],
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Test suite around :mod:`django_downloadview.api` and deprecation plan."""
|
||||
import unittest
|
||||
from six.moves import reload_module as reload
|
||||
import warnings
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ def url_basename(url, content_type):
|
|||
|
||||
If URL contains extension, it is kept as-is.
|
||||
|
||||
>>> url_basename(u'/path/to/somefile.rst', 'text/plain')
|
||||
>>> url_basename(u'/path/to/somefile.rst', 'text/plain') # doctest: +IGNORE_UNICODE
|
||||
u'somefile.rst'
|
||||
|
||||
"""
|
||||
|
|
@ -43,5 +43,5 @@ def import_member(import_string):
|
|||
|
||||
"""
|
||||
module_name, factory_name = str(import_string).rsplit('.', 1)
|
||||
module = __import__(module_name, globals(), locals(), [factory_name], -1)
|
||||
module = __import__(module_name, globals(), locals(), [factory_name], 0)
|
||||
return getattr(module, factory_name)
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -35,7 +35,7 @@ KEYWORDS = ['file',
|
|||
'mod_xsendfile',
|
||||
'offload']
|
||||
PACKAGES = [NAME.replace('-', '_')]
|
||||
REQUIREMENTS = ['setuptools', 'Django>=1.5', 'requests']
|
||||
REQUIREMENTS = ['setuptools', 'Django>=1.5', 'requests', 'six']
|
||||
if IS_PYTHON2:
|
||||
REQUIREMENTS.append('mock')
|
||||
ENTRY_POINTS = {}
|
||||
|
|
|
|||
4
tox.ini
4
tox.ini
|
|
@ -1,11 +1,12 @@
|
|||
[tox]
|
||||
envlist = py27,flake8,sphinx,readme
|
||||
envlist = py27,py33,flake8,sphinx,readme
|
||||
|
||||
[testenv]
|
||||
deps =
|
||||
nose
|
||||
rednose
|
||||
coverage
|
||||
doctest-ignore-unicode
|
||||
commands =
|
||||
pip install -e ./
|
||||
pip install -e demo/
|
||||
|
|
@ -28,6 +29,7 @@ deps =
|
|||
nose
|
||||
rednose
|
||||
Sphinx
|
||||
doctest-ignore-unicode
|
||||
commands =
|
||||
make --directory=docs clean html doctest
|
||||
whitelist_externals =
|
||||
|
|
|
|||
Loading…
Reference in a new issue