Home > Mobile >  How to create and download a zip file with a list of images?
How to create and download a zip file with a list of images?

Time:06-25

Here I have list of images with their url. I want to create a zip and store all the images inside zip. After extract the zip file I want the images inside folder.

What's happening with the below code is:

it creates zip and downloads but when I extract the zip file, there are so many folders like zipfoldername/home/user/my_project/img and only inside img folder there are files. I want is only zipfoldername/img.

Also inside img folder files doesn't have images it has image_url only. I want to store image from that image url in the extracted file.

image_list = ['https://example.com/media/file1.jpg', 'https://example.com/media/file2.jpg']

folder = os.path.join(settings.BASE_DIR, "imgs")
if not os.path.exists(folder):
    os.mkdir(folder)
for i, imgfile in enumerate(image_list):
    with open(os.path.join(folder, str(i)), 'wb ') as f:
        f.write(imgfile)
response = HttpResponse(content_type='application/zip')
s = StringIO.StringIO()

zip_file = zipfile.ZipFile(s, "w")
folder_files = os.listdir(folder)
for filename in folder_files:
    file = os.path.join(folder, filename)
    zip_file.write(file)

zip_file.close()

resp = HttpResponse(s.getvalue(), content_type = "application/x-zip-compressed")
resp['Content-Disposition'] = 'attachment; filename=gik.zip'
return resp

CodePudding user response:

Using os to get the filename and using writestr to write the bytes of the downloaded file to the zipfile

import os
import zipfile
import requests


images = [
    "https://via.placeholder.com/350x150.jpg",
    "https://via.placeholder.com/350x250.jpg",
]


with zipfile.ZipFile('someZipFile.zip', 'w') as img_zip:
    for image_url in images:
        img_name = os.path.basename(image_url)
        img_data = requests.get(image_url).content
        img_zip.writestr(img_name, img_data)

And if you want a folder called img inside the zip folder you could change:

img_zip.writestr(img_name, img_data)

to

img_zip.writestr(f"img/{img_name}", img_data)

If your returning the archive in a HTTP response you can save it to a buffer and then respond with the buffer

buffer = io.BytesIO()
with zipfile.ZipFile(buffer , 'w') as img_zip:
   ...

response = HttpResponse(buffer.getvalue())
response['Content-Type'] = 'application/x-zip-compressed'
response['Content-Disposition'] = 'attachment; filename=file.zip'
return response
  • Related