4

I am a little new to Django so please bear with me.
I'm using zipstream from here and have a Django view that returns a zip file of all file attachments which are all hosted on Amazon S3. But the zip files are all coming up as corrupt when I download them, that is, I can't open them. I have tried verifying the files with unzip -t but the errors are not very helpful.

file_paths = [fa.file.url for fa in file_attachments.all()]

zf = zipstream.ZipFile(mode='w', compression=zipstream.ZIP_DEFLATED)

zip_subdir = "Attachments-%s" % (request_id)

for file_path in file_paths:
    file_dir, file_name = os.path.split(file_path)

    zf.writestr(file_name, urllib.urlopen(file_path).read())

zip_filename = "%s.zip" % (zip_subdir)

response = StreamingHttpResponse(zf, mimetype='application/zip')
response['Content-Disposition'] = \
    'attachment; filename={}'.format(zip_filename)
return response

Any ideas?

Solved it.

s = StringIO.StringIO()
with zipstream.ZipFile(s, mode='w', compression=zipstream.ZIP_DEFLATED) as zf:
    #could fail on url open.
    for file_path in file_paths:
        file_dir, file_name = os.path.split(file_path)

        try:
            file_contents = urllib.urlopen(file_path).read()
            zf.writestr(file_name, file_contents)
        except IOError: #connection cannot be made
            logging.error()

response = StreamingHttpResponse(s.getvalue(), mimetype='application/octet-stream')
response['Content-Disposition'] = \
    'attachment; filename={}'.format("%s" % (request_id))
return response
Andrew
  • 43
  • 4

1 Answers1

3

You should close the ZipFile when you're done writing to it. Otherwise, to quote the documentation, "essential records will not be written" until you do.

The cleanest way to do it is using the with statement:

with zipstream.ZipFile(mode='w', compression=zipstream.ZIP_DEFLATED) as zf:
    # ...write to zf...
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • I've tried that and got this when testing the zip that still corrupt: Archive: 22.zip End-of-central-directory signature not found. Either this file is not a zipfile, or it constitutes one disk of a multi-part archive. In the latter case the central directory and zipfile comment will be found on the last disk(s) of this archive. unzip: cannot find zipfile directory in one of 22.zip or 22.zip.zip, and cannot find 22.zip.ZIP, period. – Andrew Oct 16 '14 at 13:10
  • I have solved the problem, thanks so much! The solution has been edited in. Silly mistake... – Andrew Oct 16 '14 at 14:41