From ae8fd4b48fc76bd2f99366e6a951a3b388afedc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pasternak?= Date: Fri, 30 Jun 2017 13:41:42 +0200 Subject: [PATCH 01/10] Add Python 3.x configurations and Django 1.3-1.11 --- .travis.yml | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tox.ini | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 .travis.yml create mode 100644 tox.ini diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..4c79bdf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,78 @@ +sudo: false + +language: python + +cache: pip + +python: + - 2.7 + - 3.3 + - 3.4 + - 3.5 + - 3.6 + +env: + - DJANGO=1.3 + - DJANGO=1.4 + - DJANGO=1.5 + - DJANGO=1.6 + - DJANGO=1.7 + - DJANGO=1.8 + - DJANGO=1.9 + - DJANGO=1.10 + - DJANGO=1.11 + +install: + - pip install -q tox + +script: + - tox -e py${TRAVIS_PYTHON_VERSION//./}-django${DJANGO//./} + +matrix: + exclude: + - python: 3.3 + env: DJANGO=1.3 + - python: 3.3 + env: DJANGO=1.4 + - python: 3.3 + env: DJANGO=1.5 + - python: 3.3 + env: DJANGO=1.6 + - python: 3.3 + env: DJANGO=1.7 + - python: 3.3 + env: DJANGO=1.9 + - python: 3.3 + env: DJANGO=1.10 + - python: 3.3 + env: DJANGO=1.11 + - python: 3.4 + env: DJANGO=1.3 + - python: 3.4 + env: DJANGO=1.4 + - python: 3.4 + env: DJANGO=1.5 + - python: 3.4 + env: DJANGO=1.6 + - python: 3.4 + env: DJANGO=1.7 + - python: 3.5 + env: DJANGO=1.3 + - python: 3.5 + env: DJANGO=1.4 + - python: 3.5 + env: DJANGO=1.5 + - python: 3.5 + env: DJANGO=1.6 + - python: 3.5 + env: DJANGO=1.7 + - python: 3.6 + env: DJANGO=1.3 + - python: 3.6 + env: DJANGO=1.4 + - python: 3.6 + env: DJANGO=1.5 + - python: 3.6 + env: DJANGO=1.6 + - python: 3.6 + env: DJANGO=1.7 diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..2ce8505 --- /dev/null +++ b/tox.ini @@ -0,0 +1,76 @@ +[tox] +envlist = py{27,33,34,35,36}-django{13,14,15,16,17,18,19,110,111} + +[testenv] +usedevelop = True +deps = + django13: django>=1.3,<1.4 + django14: django>=1.4,<1.5 + django15: django>=1.5,<1.6 + django16: django>=1.6,<1.7 + django17: django>=1.7, <1.8 + django18: django>=1.8, <1.9 + django19: django>=1.9, <1.10 + django110: django>=1.10, <1.11 + django111: django>=1.11, <1.12 +commands = python examples/protected_downloads/manage.py test sendfile + +[testenv:py33-django13] +platform = nope + +[testenv:py33-django14] +platform = nope + +[testenv:py33-django15] +platform = nope + +[testenv:py33-django16] +platform = nope + +[testenv:py33-django17] +platform = nope + +[testenv:py34-django13] +platform = nope + +[testenv:py34-django14] +platform = nope + +[testenv:py34-django15] +platform = nope + +[testenv:py34-django16] +platform = nope + +[testenv:py34-django17] +platform = nope + +[testenv:py35-django13] +platform = nope + +[testenv:py35-django14] +platform = nope + +[testenv:py35-django15] +platform = nope + +[testenv:py35-django16] +platform = nope + +[testenv:py35-django17] +platform = nope + +[testenv:py36-django13] +platform = nope + +[testenv:py36-django14] +platform = nope + +[testenv:py36-django15] +platform = nope + +[testenv:py36-django16] +platform = nope + +[testenv:py36-django17] +platform = nope From e41fd4269d61ae8f6c9a46c5cf7bf0a5ff3e9b56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pasternak?= Date: Fri, 30 Jun 2017 13:41:48 +0200 Subject: [PATCH 02/10] Ignore tox directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2267b36..55e9f48 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ /lib /build .Python +.tox From 817e025ff9aa82066a978a9771f83cbc663c83d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pasternak?= Date: Fri, 30 Jun 2017 13:41:54 +0200 Subject: [PATCH 03/10] Fix manage.py --- examples/protected_downloads/manage.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/examples/protected_downloads/manage.py b/examples/protected_downloads/manage.py index 3e098b0..44eeb8c 100644 --- a/examples/protected_downloads/manage.py +++ b/examples/protected_downloads/manage.py @@ -2,13 +2,15 @@ from __future__ import absolute_import -from django.core.management import execute_manager -try: - from . import settings # Assumed to be in the same directory. -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) - sys.exit(1) +#!/usr/bin/env python +import os +import sys + +# Add ../multiseek to sys.path + +sys.path = [ os.path.join(os.path.dirname(__file__), '..', '..'), ] + sys.path if __name__ == "__main__": - execute_manager(settings) + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") + from django.core.management import execute_from_command_line + execute_from_command_line(sys.argv) From 2645e4164bcf14c237367e1d2ade9bc2ed4e6f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pasternak?= Date: Fri, 30 Jun 2017 13:42:27 +0200 Subject: [PATCH 04/10] Add build badge --- README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.rst b/README.rst index 76ccf99..c4d68f2 100644 --- a/README.rst +++ b/README.rst @@ -2,6 +2,8 @@ Django Sendfile =============== +[![Build Status](https://travis-ci.org/mpasternak/django-sendfile.svg?branch=master)](https://travis-ci.org/mpasternak/django-sendfile) + This is a wrapper around web-server specific methods for sending files to web clients. This is useful when Django needs to check permissions associated files, but does not want to serve the actual bytes of the file itself. i.e. as serving large files is not what Django is made for. Note this should not be used for regular file serving (e.g. css etc), only for cases where you need Django to do some work before serving the actual file. From 3c2a7017b9dad215f0bffffeb8959ff26b8225c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pasternak?= Date: Fri, 30 Jun 2017 17:55:35 +0200 Subject: [PATCH 05/10] TravisCI shield --- README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index c4d68f2..10a51c0 100644 --- a/README.rst +++ b/README.rst @@ -2,7 +2,8 @@ Django Sendfile =============== -[![Build Status](https://travis-ci.org/mpasternak/django-sendfile.svg?branch=master)](https://travis-ci.org/mpasternak/django-sendfile) +.. image:: https://img.shields.io/travis/mpasternak/django-sendfile.svg + :target: https://travis-ci.org/mpasternak/django-sendfile This is a wrapper around web-server specific methods for sending files to web clients. This is useful when Django needs to check permissions associated files, but does not want to serve the actual bytes of the file itself. i.e. as serving large files is not what Django is made for. From 44eec1962f6948a53196995d55e5b3bcead2ce14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pasternak?= Date: Fri, 30 Jun 2017 18:30:07 +0200 Subject: [PATCH 06/10] Fix tests for py27 and py36 --- .../protected_downloads/download/models.py | 3 +++ examples/protected_downloads/download/urls.py | 22 +++++++++++----- .../protected_downloads/download/views.py | 2 +- examples/protected_downloads/manage.py | 4 +-- examples/protected_downloads/urls.py | 21 +++++++++++---- sendfile/__init__.py | 6 ++++- sendfile/backends/xsendfile.py | 6 ++++- sendfile/tests.py | 26 +++++++++++++++---- tox.ini | 6 ++++- 9 files changed, 73 insertions(+), 23 deletions(-) diff --git a/examples/protected_downloads/download/models.py b/examples/protected_downloads/download/models.py index 0e10dbc..300f71e 100644 --- a/examples/protected_downloads/download/models.py +++ b/examples/protected_downloads/download/models.py @@ -23,3 +23,6 @@ def __unicode__(self): @models.permalink def get_absolute_url(self): return ('download', [self.pk], {}) + + class Meta: + app_label = 'download' diff --git a/examples/protected_downloads/download/urls.py b/examples/protected_downloads/download/urls.py index fd4bb28..a47e001 100644 --- a/examples/protected_downloads/download/urls.py +++ b/examples/protected_downloads/download/urls.py @@ -1,8 +1,18 @@ -from django.conf.urls.defaults import * - from .views import download, download_list -urlpatterns = patterns('', - url(r'^$', download_list), - url(r'(?P\d+)/$', download, name='download'), -) +import django + +if django.VERSION >= (1,9,0): + from django.conf.urls import * + urlpatterns = [ + url(r'^$', download_list), + url(r'(?P\d+)/$', download, name='download'), + ] +else: + from django.conf.urls.defaults import * + + urlpatterns = patterns( + '', + url(r'^$', download_list), + url(r'(?P\d+)/$', download, name='download'), + ) diff --git a/examples/protected_downloads/download/views.py b/examples/protected_downloads/download/views.py index e99b6bc..e4a57c0 100644 --- a/examples/protected_downloads/download/views.py +++ b/examples/protected_downloads/download/views.py @@ -6,7 +6,7 @@ from sendfile import sendfile -from .models import Download +from download.models import Download def download(request, download_id): diff --git a/examples/protected_downloads/manage.py b/examples/protected_downloads/manage.py index 44eeb8c..8fb4aa8 100644 --- a/examples/protected_downloads/manage.py +++ b/examples/protected_downloads/manage.py @@ -1,13 +1,11 @@ #!/usr/bin/env python -from __future__ import absolute_import +# from __future__ import absolute_import #!/usr/bin/env python import os import sys -# Add ../multiseek to sys.path - sys.path = [ os.path.join(os.path.dirname(__file__), '..', '..'), ] + sys.path if __name__ == "__main__": diff --git a/examples/protected_downloads/urls.py b/examples/protected_downloads/urls.py index 238d8c7..788d752 100644 --- a/examples/protected_downloads/urls.py +++ b/examples/protected_downloads/urls.py @@ -1,9 +1,20 @@ -from django.conf.urls.defaults import * + from django.contrib import admin admin.autodiscover() -urlpatterns = patterns('', - (r'^', include('protected_downloads.download.urls')), - (r'^admin/', include(admin.site.urls)), -) +import django +if django.VERSION >= (1,9,0): + from django.conf.urls import * + urlpatterns = [ + url(r'^', include('protected_downloads.download.urls')), + url(r'^admin/', include(admin.site.urls)), + ] + +else: + from django.conf.urls.defaults import * + urlpatterns = patterns( + '', + (r'^', include('protected_downloads.download.urls')), + (r'^admin/', include(admin.site.urls)), + ) diff --git a/sendfile/__init__.py b/sendfile/__init__.py index 1cc9809..1955142 100644 --- a/sendfile/__init__.py +++ b/sendfile/__init__.py @@ -1,6 +1,7 @@ VERSION = (0, 3, 11) __version__ = '.'.join(map(str, VERSION)) +import six import os.path from mimetypes import guess_type import unicodedata @@ -77,7 +78,10 @@ def sendfile(request, filename, attachment=False, attachment_filename=None, mime # Django 1.3 from django.utils.encoding import force_unicode as force_text attachment_filename = force_text(attachment_filename) - ascii_filename = unicodedata.normalize('NFKD', attachment_filename).encode('ascii','ignore') + ascii_filename = unicodedata.normalize('NFKD', attachment_filename) + ascii_filename = ascii_filename.encode('ascii','ignore') + if six.PY3: + ascii_filename = ascii_filename.decode() parts.append('filename="%s"' % ascii_filename) if ascii_filename != attachment_filename: from django.utils.http import urlquote diff --git a/sendfile/backends/xsendfile.py b/sendfile/backends/xsendfile.py index a87aa83..c7b0bb4 100644 --- a/sendfile/backends/xsendfile.py +++ b/sendfile/backends/xsendfile.py @@ -1,8 +1,12 @@ from django.http import HttpResponse +import six def sendfile(request, filename, **kwargs): response = HttpResponse() - response['X-Sendfile'] = unicode(filename).encode('utf-8') + if six.PY2: + response['X-Sendfile'] = unicode(filename).encode('utf-8') + else: + response['X-Sendfile'] = filename # .encode('utf-8') return response diff --git a/sendfile/tests.py b/sendfile/tests.py index 0643cae..a659320 100644 --- a/sendfile/tests.py +++ b/sendfile/tests.py @@ -1,5 +1,9 @@ # coding=utf-8 +from __future__ import unicode_literals + +import six + from django.conf import settings from django.test import TestCase from django.http import HttpResponse, Http404, HttpRequest @@ -9,6 +13,11 @@ import shutil from sendfile import sendfile as real_sendfile, _get_sendfile +try: + unicode is not None +except: + unicode = str + try: from urllib.parse import unquote except ImportError: @@ -107,7 +116,7 @@ def test_correct_file_in_xsendfile_header(self): self.assertEqual(filepath, response['X-Sendfile']) def test_xsendfile_header_containing_unicode(self): - filepath = self.ensure_file(u'péter_là_gueule.txt') + filepath = self.ensure_file('péter_là_gueule.txt') response = real_sendfile(HttpRequest(), filepath) self.assertTrue(response is not None) self.assertEqual(smart_str(filepath), response['X-Sendfile']) @@ -129,10 +138,14 @@ def test_correct_url_in_xaccelredirect_header(self): self.assertEqual('/private/readme.txt', response['X-Accel-Redirect']) def test_xaccelredirect_header_containing_unicode(self): - filepath = self.ensure_file(u'péter_là_gueule.txt') + filepath = self.ensure_file('péter_là_gueule.txt') response = real_sendfile(HttpRequest(), filepath) self.assertTrue(response is not None) - self.assertEqual(u'/private/péter_là_gueule.txt'.encode('utf-8'), unquote(response['X-Accel-Redirect'])) + s = '/private/péter_là_gueule.txt' + if six.PY2: + s = s.encode("utf-8") + self.assertEqual(s, unquote(response['X-Accel-Redirect'])) + class TestModWsgiBackend(TempFileTestCase): @@ -151,7 +164,10 @@ def test_correct_url_in_location_header(self): self.assertEqual('/private/readme.txt', response['Location']) def test_location_header_containing_unicode(self): - filepath = self.ensure_file(u'péter_là_gueule.txt') + filepath = self.ensure_file('péter_là_gueule.txt') response = real_sendfile(HttpRequest(), filepath) self.assertTrue(response is not None) - self.assertEqual(u'/private/péter_là_gueule.txt'.encode('utf-8'), unquote(response['Location'])) + s = '/private/péter_là_gueule.txt' + if six.PY2: + s = s.encode("utf-8") + self.assertEqual(s, unquote(response['Location'])) diff --git a/tox.ini b/tox.ini index 2ce8505..539e99c 100644 --- a/tox.ini +++ b/tox.ini @@ -4,6 +4,7 @@ envlist = py{27,33,34,35,36}-django{13,14,15,16,17,18,19,110,111} [testenv] usedevelop = True deps = + six django13: django>=1.3,<1.4 django14: django>=1.4,<1.5 django15: django>=1.5,<1.6 @@ -13,7 +14,10 @@ deps = django19: django>=1.9, <1.10 django110: django>=1.10, <1.11 django111: django>=1.11, <1.12 -commands = python examples/protected_downloads/manage.py test sendfile + +changedir = examples/protected_downloads + +commands = python manage.py test sendfile [testenv:py33-django13] platform = nope From 3a80c25ebe64222e69d2594dcc4a9a1754348e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pasternak?= Date: Fri, 30 Jun 2017 18:35:06 +0200 Subject: [PATCH 07/10] Disable Django 1.3 --- .travis.yml | 1 - tox.ini | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4c79bdf..ddeea21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ python: - 3.6 env: - - DJANGO=1.3 - DJANGO=1.4 - DJANGO=1.5 - DJANGO=1.6 diff --git a/tox.ini b/tox.ini index 539e99c..b9ad9cc 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,10 @@ [tox] -envlist = py{27,33,34,35,36}-django{13,14,15,16,17,18,19,110,111} +envlist = py{27,33,34,35,36}-django{14,15,16,17,18,19,110,111} [testenv] usedevelop = True deps = six - django13: django>=1.3,<1.4 django14: django>=1.4,<1.5 django15: django>=1.5,<1.6 django16: django>=1.6,<1.7 From 3e56b3bbfd44d4587f43c1a8da586fa760524610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pasternak?= Date: Thu, 6 Jul 2017 00:08:19 +0200 Subject: [PATCH 08/10] Shuffle the code to avoid ImportError, as per suggestion from @MarekBleschke --- sendfile/__init__.py | 96 ---------------------------------------- sendfile/core.py | 103 +++++++++++++++++++++++++++++++++++++++++++ sendfile/tests.py | 7 +-- 3 files changed, 104 insertions(+), 102 deletions(-) create mode 100644 sendfile/core.py diff --git a/sendfile/__init__.py b/sendfile/__init__.py index 1955142..8ef6899 100644 --- a/sendfile/__init__.py +++ b/sendfile/__init__.py @@ -1,99 +1,3 @@ VERSION = (0, 3, 11) __version__ = '.'.join(map(str, VERSION)) -import six -import os.path -from mimetypes import guess_type -import unicodedata - - -def _lazy_load(fn): - _cached = [] - def _decorated(): - if not _cached: - _cached.append(fn()) - return _cached[0] - def clear(): - while _cached: - _cached.pop() - _decorated.clear = clear - return _decorated - - -@_lazy_load -def _get_sendfile(): - try: - from importlib import import_module - except ImportError: - from django.utils.importlib import import_module - from django.conf import settings - from django.core.exceptions import ImproperlyConfigured - - backend = getattr(settings, 'SENDFILE_BACKEND', None) - if not backend: - raise ImproperlyConfigured('You must specify a value for SENDFILE_BACKEND') - module = import_module(backend) - return module.sendfile - - - -def sendfile(request, filename, attachment=False, attachment_filename=None, mimetype=None, encoding=None): - ''' - create a response to send file using backend configured in SENDFILE_BACKEND - - If attachment is True the content-disposition header will be set. - This will typically prompt the user to download the file, rather - than view it. The content-disposition filename depends on the - value of attachment_filename: - - None (default): Same as filename - False: No content-disposition filename - String: Value used as filename - - If no mimetype or encoding are specified, then they will be guessed via the - filename (using the standard python mimetypes module) - ''' - _sendfile = _get_sendfile() - - if not os.path.exists(filename): - from django.http import Http404 - raise Http404('"%s" does not exist' % filename) - - guessed_mimetype, guessed_encoding = guess_type(filename) - if mimetype is None: - if guessed_mimetype: - mimetype = guessed_mimetype - else: - mimetype = 'application/octet-stream' - - response = _sendfile(request, filename, mimetype=mimetype) - if attachment: - if attachment_filename is None: - attachment_filename = os.path.basename(filename) - parts = ['attachment'] - if attachment_filename: - try: - from django.utils.encoding import force_text - except ImportError: - # Django 1.3 - from django.utils.encoding import force_unicode as force_text - attachment_filename = force_text(attachment_filename) - ascii_filename = unicodedata.normalize('NFKD', attachment_filename) - ascii_filename = ascii_filename.encode('ascii','ignore') - if six.PY3: - ascii_filename = ascii_filename.decode() - parts.append('filename="%s"' % ascii_filename) - if ascii_filename != attachment_filename: - from django.utils.http import urlquote - quoted_filename = urlquote(attachment_filename) - parts.append('filename*=UTF-8\'\'%s' % quoted_filename) - response['Content-Disposition'] = '; '.join(parts) - - response['Content-length'] = os.path.getsize(filename) - response['Content-Type'] = mimetype - if not encoding: - encoding = guessed_encoding - if encoding: - response['Content-Encoding'] = encoding - - return response diff --git a/sendfile/core.py b/sendfile/core.py new file mode 100644 index 0000000..15389ca --- /dev/null +++ b/sendfile/core.py @@ -0,0 +1,103 @@ +# -*- encoding: utf-8 -*- + + +import os.path +from mimetypes import guess_type +import unicodedata + + +def _lazy_load(fn): + _cached = [] + + def _decorated(): + if not _cached: + _cached.append(fn()) + return _cached[0] + + def clear(): + while _cached: + _cached.pop() + + _decorated.clear = clear + return _decorated + + +@_lazy_load +def _get_sendfile(): + try: + from importlib import import_module + except ImportError: + from django.utils.importlib import import_module + from django.conf import settings + from django.core.exceptions import ImproperlyConfigured + + backend = getattr(settings, 'SENDFILE_BACKEND', None) + if not backend: + raise ImproperlyConfigured( + 'You must specify a value for SENDFILE_BACKEND') + module = import_module(backend) + return module.sendfile + + +def sendfile(request, filename, attachment=False, attachment_filename=None, + mimetype=None, encoding=None): + ''' + create a response to send file using backend configured in SENDFILE_BACKEND + + If attachment is True the content-disposition header will be set. + This will typically prompt the user to download the file, rather + than view it. The content-disposition filename depends on the + value of attachment_filename: + + None (default): Same as filename + False: No content-disposition filename + String: Value used as filename + + If no mimetype or encoding are specified, then they will be guessed via the + filename (using the standard python mimetypes module) + ''' + _sendfile = _get_sendfile() + + if not os.path.exists(filename): + from django.http import Http404 + raise Http404('"%s" does not exist' % filename) + + guessed_mimetype, guessed_encoding = guess_type(filename) + if mimetype is None: + if guessed_mimetype: + mimetype = guessed_mimetype + else: + mimetype = 'application/octet-stream' + + response = _sendfile(request, filename, mimetype=mimetype) + if attachment: + if attachment_filename is None: + attachment_filename = os.path.basename(filename) + parts = ['attachment'] + if attachment_filename: + try: + from django.utils.encoding import force_text + except ImportError: + # Django 1.3 + from django.utils.encoding import force_unicode as force_text + attachment_filename = force_text(attachment_filename) + ascii_filename = unicodedata.normalize('NFKD', attachment_filename) + ascii_filename = ascii_filename.encode('ascii', 'ignore') + import six + if six.PY3: + ascii_filename = ascii_filename.decode() + parts.append('filename="%s"' % ascii_filename) + if ascii_filename != attachment_filename: + from django.utils.http import urlquote + quoted_filename = urlquote(attachment_filename) + parts.append('filename*=UTF-8\'\'%s' % quoted_filename) + response['Content-Disposition'] = '; '.join(parts) + + response['Content-length'] = os.path.getsize(filename) + response['Content-Type'] = mimetype + if not encoding: + encoding = guessed_encoding + if encoding: + response['Content-Encoding'] = encoding + + return response \ No newline at end of file diff --git a/sendfile/tests.py b/sendfile/tests.py index a659320..e64a193 100644 --- a/sendfile/tests.py +++ b/sendfile/tests.py @@ -11,12 +11,7 @@ import os.path from tempfile import mkdtemp import shutil -from sendfile import sendfile as real_sendfile, _get_sendfile - -try: - unicode is not None -except: - unicode = str +from sendfile.core import sendfile as real_sendfile, _get_sendfile try: from urllib.parse import unquote From 32b17aa0ea3b03b3879bbec8044b03ae639fed85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pasternak?= Date: Thu, 6 Jul 2017 00:08:59 +0200 Subject: [PATCH 09/10] Ignore PyCharm --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 55e9f48..eeec5cf 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ /build .Python .tox +.idea From 1015c87abb2bcf792ba4976a2e53afadd24f2725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pasternak?= Date: Thu, 6 Jul 2017 00:15:48 +0200 Subject: [PATCH 10/10] Fix test --- examples/protected_downloads/download/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/protected_downloads/download/views.py b/examples/protected_downloads/download/views.py index e4a57c0..5495773 100644 --- a/examples/protected_downloads/download/views.py +++ b/examples/protected_downloads/download/views.py @@ -4,7 +4,7 @@ from django.db.models import Q from django.template import RequestContext -from sendfile import sendfile +from sendfile.core import sendfile from download.models import Download