Psycho-rebased branch 60-virtualfile-force-bytes on top of master

This commit is contained in:
Benoît Bryon 2013-11-08 09:59:51 +01:00
commit f170c8904b
5 changed files with 34 additions and 38 deletions

View file

@ -13,16 +13,16 @@ documentation.
- Bugfix #57 - ``PathDownloadView`` opens files in binary mode (was text mode).
- 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.
@ -59,7 +59,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.

View file

@ -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')

View file

@ -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

View file

@ -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.

View file

@ -42,7 +42,6 @@ class APITestCase(unittest.TestCase):
'BaseDownloadView',
'DownloadMixin',
# File wrappers:
'File',
'StorageFile',
'HTTPFile',
'VirtualFile',