mirror of
https://github.com/jazzband/django-downloadview.git
synced 2026-03-16 22:40:25 +00:00
Refs #60 - VirtualFile uses force_bytes(). Removed (wrong) patch of File.__iter__().
This commit is contained in:
parent
c32313ca8e
commit
c141f027de
5 changed files with 34 additions and 38 deletions
|
|
@ -11,16 +11,16 @@ future releases, check `milestones`_ and :doc:`/about/vision`.
|
|||
Big refactoring around middleware configuration, API readability and
|
||||
documentation.
|
||||
|
||||
- Bugfix #44 - Introduced ``django_downloadview.File``, which patches
|
||||
``django.core.files.base.File.__iter__()`` implementation.
|
||||
See https://code.djangoproject.com/ticket/21321
|
||||
|
||||
- Bugfix #48 - Fixed ``basename`` assertion in ``assert_download_response``:
|
||||
checks ``Content-Disposition`` header.
|
||||
|
||||
- Bugfix #49 - Fixed ``content`` assertion in ``assert_download_response``:
|
||||
checks only response's ``streaming_content`` attribute.
|
||||
|
||||
- Bugfix #60 - ``VirtualFile.__iter__`` uses ``force_bytes()`` to support both
|
||||
"text-mode" and "binary-mode" content.
|
||||
See https://code.djangoproject.com/ticket/21321
|
||||
|
||||
- Feature #50 - Introduced ``django_downloadview.DownloadDispatcherMiddleware``
|
||||
that iterates over a list of configurable download middlewares. Allows to
|
||||
plug several download middlewares with different configurations.
|
||||
|
|
@ -57,7 +57,6 @@ documentation.
|
|||
- Refactoring #53 - Added base classes in ``django_downloadview.middlewares``,
|
||||
such as ``ProxiedDownloadMiddleware``.
|
||||
|
||||
|
||||
- Refactoring #54 - Expose most Python API directly in `django_downloadview`
|
||||
package. Simplifies ``import`` statements in client applications.
|
||||
Splitted nginx module in a package.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class TextDownloadView(VirtualDownloadView):
|
|||
class StringIODownloadView(VirtualDownloadView):
|
||||
def get_file(self):
|
||||
"""Return wrapper on ``StringIO`` object."""
|
||||
file_obj = StringIO(u"Hello world!\n".encode('utf-8'))
|
||||
file_obj = StringIO(u"Hello world!\n")
|
||||
return VirtualFile(file_obj, name='hello-world.txt')
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@
|
|||
from django_downloadview.io import StringIteratorIO # NoQA
|
||||
from django_downloadview.files import (StorageFile, # NoQA
|
||||
VirtualFile,
|
||||
HTTPFile,
|
||||
File)
|
||||
HTTPFile)
|
||||
from django_downloadview.response import (DownloadResponse, # NoQA
|
||||
ProxiedDownloadResponse)
|
||||
from django_downloadview.middlewares import (BaseDownloadMiddleware, # NoQA
|
||||
|
|
|
|||
|
|
@ -4,40 +4,12 @@ from __future__ import absolute_import
|
|||
from io import BytesIO
|
||||
from urlparse import urlparse
|
||||
|
||||
import django.core.files
|
||||
from django.core.files.base import File
|
||||
from django.utils.encoding import force_bytes
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
class File(django.core.files.File):
|
||||
"""Patch Django's :meth:`__iter__` implementation.
|
||||
|
||||
See https://code.djangoproject.com/ticket/21321
|
||||
|
||||
"""
|
||||
def __iter__(self):
|
||||
# Iterate over this file-like object by newlines
|
||||
buffer_ = None
|
||||
for chunk in self.chunks():
|
||||
chunk_buffer = BytesIO(force_bytes(chunk))
|
||||
|
||||
for line in chunk_buffer:
|
||||
if buffer_:
|
||||
line = buffer_ + line
|
||||
buffer_ = None
|
||||
|
||||
# If this is the end of a line, yield
|
||||
# otherwise, wait for the next round
|
||||
if line[-1] in ('\n', '\r'):
|
||||
yield line
|
||||
else:
|
||||
buffer_ = line
|
||||
|
||||
if buffer_ is not None:
|
||||
yield buffer_
|
||||
|
||||
|
||||
class StorageFile(File):
|
||||
"""A file in a Django storage.
|
||||
|
||||
|
|
@ -204,6 +176,33 @@ class VirtualFile(File):
|
|||
|
||||
size = property(_get_size, _set_size)
|
||||
|
||||
def __iter__(self):
|
||||
"""Same as ``File.__iter__()`` but using ``force_bytes()``.
|
||||
|
||||
See https://code.djangoproject.com/ticket/21321
|
||||
|
||||
"""
|
||||
# Iterate over this file-like object by newlines
|
||||
buffer_ = None
|
||||
for chunk in self.chunks():
|
||||
chunk_buffer = BytesIO(force_bytes(chunk))
|
||||
|
||||
for line in chunk_buffer:
|
||||
if buffer_:
|
||||
line = buffer_ + line
|
||||
buffer_ = None
|
||||
|
||||
# If this is the end of a line, yield
|
||||
# otherwise, wait for the next round
|
||||
if line[-1] in ('\n', '\r'):
|
||||
yield line
|
||||
else:
|
||||
buffer_ = line
|
||||
|
||||
if buffer_ is not None:
|
||||
yield buffer_
|
||||
|
||||
|
||||
|
||||
class HTTPFile(File):
|
||||
"""Wrapper for files that live on remote HTTP servers.
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ class APITestCase(unittest.TestCase):
|
|||
'BaseDownloadView',
|
||||
'DownloadMixin',
|
||||
# File wrappers:
|
||||
'File',
|
||||
'StorageFile',
|
||||
'HTTPFile',
|
||||
'VirtualFile',
|
||||
|
|
|
|||
Loading…
Reference in a new issue