Python CGI - Presenting a zip file to user

jwwest jwwest at gmail.com
Thu Jan 3 00:35:17 EST 2008


On Jan 2, 8:56 pm, Justin Ezequiel <justin.mailingli... at gmail.com>
wrote:
> On Jan 3, 7:50 am, jwwest <jww... at gmail.com> wrote:
>
>
>
> > Hi all,
>
> > I'm working on a cgi script that zips up files and presents the zip
> > file to the user for download. It works fine except for the fact that
> > I have to overwrite the file using the same filename because I'm
> > unable to delete it after it's downloaded. The reason for this is
> > because after sending "Location: urlofzipfile" the script stops
> > processing and I can't call a file operation to delete the file. Thus
> > I constantly have a tmp.zip file which contains the previously
> > requested files.
>
> > Can anyone think of a way around this? Is there a better way to create
> > the zip file and present it for download "on-the-fly" than editing the
> > Location header? I thought about using Content-Type, but was unable to
> > think of a way to stream the file out.
>
> > Any help is appreciated, much thanks!
>
> > - James
>
> import sys, cgi, zipfile, os
> from StringIO import StringIO
>
> try: # Windows only
>     import msvcrt
>     msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
> except ImportError: pass
>
> HEADERS = '\r\n'.join(
>     [
>         "Content-type: %s;",
>         "Content-Disposition: attachment; filename=%s",
>         "Content-Title: %s",
>         "Content-Length: %i",
>         "\r\n", # empty line to end headers
>         ]
>     )
>
> if __name__ == '__main__':
>     os.chdir(r'C:\Documents and Settings\Justin Ezequiel\Desktop')
>     files = [
>         '4412_ADS_or_SQL_Server.pdf',
>         'Script1.py',
>         'html_files.zip',
>         'New2.html',
>         ]
>     b = StringIO()
>     z = zipfile.ZipFile(b, 'w', zipfile.ZIP_DEFLATED)
>     for n in files:
>         z.write(n, n)
>
>     z.close()
>
>     length = b.tell()
>     b.seek(0)
>     sys.stdout.write(
>         HEADERS % ('application/zip', 'test.zip', 'test.zip', length)
>         )
>     sys.stdout.write(b.read())
>     b.close()

Thanks! That worked like an absolute charm.

Just a question though. I'm curious as to why you have to use the
msvcrt bit on Windows. If I were to port my app to *NIX, would I need
to do anything similar?

- James



More information about the Python-list mailing list