Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use StreamingHttpResponse when downloading zip streams #1527

Merged
merged 2 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions app/api/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from django.db import transaction
from django.http import FileResponse
from django.http import HttpResponse
from django.http import StreamingHttpResponse
from app.vendor import zipfly
from rest_framework import status, serializers, viewsets, filters, exceptions, permissions, parsers
from rest_framework.decorators import action
from rest_framework.permissions import AllowAny
Expand Down Expand Up @@ -340,8 +342,13 @@ def download_file_response(request, filePath, content_disposition, download_file


def download_file_stream(request, stream, content_disposition, download_filename=None):
response = HttpResponse(FileWrapper(stream),
content_type=(mimetypes.guess_type(download_filename)[0] or "application/zip"))
if isinstance(stream, zipfly.ZipStream):
f = stream.generator()
else:
# This should never happen, but just in case..
raise exceptions.ValidationError("stream not a zipstream instance")

response = StreamingHttpResponse(f, content_type=(mimetypes.guess_type(download_filename)[0] or "application/zip"))

response['Content-Type'] = mimetypes.guess_type(download_filename)[0] or "application/zip"
response['Content-Disposition'] = "{}; filename={}".format(content_disposition, download_filename)
Expand Down
4 changes: 2 additions & 2 deletions app/tests/test_api_task_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def test_task(self):
assets_path = os.path.join(settings.MEDIA_TMP, "all.zip")

with open(assets_path, 'wb') as f:
f.write(res.content)
f.write(b''.join(res.streaming_content))

remove_perm('change_project', user, project)

Expand Down Expand Up @@ -272,7 +272,7 @@ def test_backup(self):
assets_path = os.path.join(settings.MEDIA_TMP, "backup.zip")

with open(assets_path, 'wb') as f:
f.write(res.content)
f.write(b''.join(res.streaming_content))

assets_file = open(assets_path, 'rb')

Expand Down
13 changes: 8 additions & 5 deletions app/vendor/zipfly.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ def get(self):
def size(self):
return self._size


class ZipFly:

def __init__(self,
Expand Down Expand Up @@ -280,13 +279,17 @@ def get_size(self):
class ZipStream:
def __init__(self, paths):
self.paths = paths
self.generator = None
self._generator = None

def lazy_load(self, chunksize):
if self.generator is None:
if self._generator is None:
zfly = ZipFly(paths=self.paths, mode='w', chunksize=chunksize)
self.generator = zfly.generator()
self._generator = zfly.generator()

def read(self, count):
self.lazy_load(count)
return next(self.generator)
return next(self._generator)

def generator(self):
self.lazy_load(0x8000)
return self._generator
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "WebODM",
"version": "2.5.3",
"version": "2.5.4",
"description": "User-friendly, extendable application and API for processing aerial imagery.",
"main": "index.js",
"scripts": {
Expand Down
Loading