Download ZIP-Archiv

Beispiel: Download einer Menge von Bildern aus der "Lightbox" einer Bilddatenbank als ZIP-Archiv

Die Erzeugung und der Download eines komprimierten ZIP Archivs wird mit folgenden Schritten bewerkstelligt:

  1. Temporäres Verzeichnis im lokalen Dateisystem anlegen
  2. Dateien dort anlegen bzw. hinkopieren
  3. ZIP Archivdatei zusammenstellen
  4. Temporäres Verzeichnis löschen
  5. ZIP Archivdatei herunterladen

Im folgenden Python-Script wird diese exemplarisch angewendet. Die Ausgangs-Dateien sind in diesem Falle BLOBs aus einer SQL-Datenquelle (Tabelle "media", Column "mediafile") und damit bereits im lokalen Dateisystem vorhanden, d.h. diese müssen nicht erzeugt sondern nur ins ZIP verschoben werden.

# Python Script "zmExportLightbox" #

request = container.REQUEST
RESPONSE =  request.RESPONSE
session = context.REQUEST.SESSION

# get DB row ids from SESSION
mediaidList=session.get('myMediaidList',[])

# get the path from the SQL datasource where BLOBs are stored
datasource = zms.e9319.e8833
mediafilePath = datasource.getEntityColumn('media','mediafile')['blob']['path']

# 1. create temp_folder
tempfolder=context.localfs_tempfile()
try:
  context.localfs_command('mkdir %s'%tempfolder)
except:
  context.localfs_command('md %s'%tempfolder)

# 2. copy each mediafile into temp_folder
# The Z-SQL method 'zmsql_getMedia()' works as follows:
# SELECT mediafile FROM media WHERE idmedia IN mediaidList
for m in context.zmsql_getMedia(mediaid=mediaidList):
  context.localfs_command('cp %s %s'%(mediafilePath + m['mediafile'], tempfolder))

# 3. build ZIP archive
exportfile = context.buildZipArchive( '%s/*.*'%tempfolder)

# 4. clean up temp_folder
try:
  context.localfs_command('rm -rf %s'%tempfolder)
except:
  context.localfs_command('rmdir /q /s %s'%tempfolder)

# 5. trigger download ZIP archive
RESPONSE.setHeader('Expires','-1')
RESPONSE.setHeader('Cache-Control','no-cache')
RESPONSE.setHeader('Pragma','no-cache')
RESPONSE.setHeader('Content-Type','application/zip')
RESPONSE.setHeader('Content-Length', len(exportfile) )
RESPONSE.setHeader('Content-Disposition','inline;filename=%s.zip'%('lightbox'))
return exportfile

Liegen die Ausgangsdateien als Objekte in Zope/ZMS, so muss der 2. Schritt modifiziert werden, und zunächst aus den Objekten Dateien im lokalen Dateisystem erzeugt werden. Das folgende Snippet zeigt exemplarisch, wie alle Dateien des Typs "ZMSFile" im lokalen Dateisystem angelegt werden.

# DTML-Snippet: Alle Dateien in Objekten vom Typ "ZMSFile" als lokale Datei anlegen #

...
<dtml-comment>
 # 2. write each ZMSFile into the temp_folder
</dtml-comment>
<dtml-in "filteredTreeNodes(REQUEST,PAGES)">
 <dtml-in "filteredChildNodes(REQUEST,'ZMSFile')">
  <dtml-let file="getObjProperty('file',REQUEST)">
   <dtml-call "localfs_write('%s/%s'%(tempfolder,file.getFilename()),file.getData())">
  </dtml-let>
 </dtml-in>
</dtml-in>
....

Erstellt von: Dr. Thorsten Fox , erstellt am:  02.07.2010 , zuletzt geändert: 21.03.2011