[Zope3-checkins] CVS: Zope3/src/zope/app/browser/content - fssync.py:1.1 configure.zcml:1.20
Guido van Rossum
guido@python.org
Wed, 7 May 2003 21:08:43 -0400
Update of /cvs-repository/Zope3/src/zope/app/browser/content
In directory cvs.zope.org:/tmp/cvs-serv18105
Modified Files:
configure.zcml
Added Files:
fssync.py
Log Message:
A new view, (potentially) applying to all object types, that returns a
zipfile containing the output of toFS() for that object. The view name
is appropriately "@@toFS.zop". The Content-type is application/zip.
=== Added File Zope3/src/zope/app/browser/content/fssync.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Code for the toFS.zip view.
$Id: fssync.py,v 1.1 2003/05/08 01:08:42 gvanrossum Exp $
"""
import os
import shutil
import tempfile
from zope.publisher.browser import BrowserView
from zope.app.fssync.syncer import toFS
from zope.app.traversing import objectName
class ZipFile(BrowserView):
"""View returning a zipped filesystem representation of an object tree.
This applies to any object (for="zope.interface.Interface").
Steps in the operation:
- use toFS() to render the object tree to a temporary directory
- cd into the directory and zip it up using the command line zip program
- return the contents of the zipfile with content-type application/zip
"""
def show(self):
"""Return the zipfile response."""
zipfilename = writeZipFile(self.context,
self.request.get("pruneOriginals"))
f = open(zipfilename, "rb")
data = f.read()
f.close()
os.unlink(zipfilename)
response = self.request.response
response.setHeader("Content-Type", "application/zip")
# XXX This can return a lot of data; should figure out how to
# do chunked writes
response.setHeader("Content-Length", len(data))
return data
def writeZipFile(obj, pruneOriginals=None):
"""Helper to render the object tree to the filesystem and zip it.
Return the name of the zipfile.
"""
dirname = tempfile.mktemp()
os.mkdir(dirname)
# XXX toFS prints to stdout; it shouldn't
toFS(obj, objectName(obj) or "root", dirname)
if pruneOriginals:
os.path.walk(dirname, pruneOriginalsCallback, None)
zipfilename = tempfile.mktemp(".zip")
# XXX This is Unix specific and requires that you have the zip
# program installed; should use the zipfile module instead
cmd = "(cd %s; zip -q -r %s .) 2>&1" % (dirname, zipfilename)
pipe = os.popen(cmd, "r")
output = pipe.read()
sts = pipe.close()
if sts:
raise RuntimeError("zip status %#x; output:\n%s" % (sts, output))
shutil.rmtree(dirname)
return zipfilename
normcase = os.path.normcase
ZOPEDIR = normcase("@@Zope")
ORIGINAL = normcase("Original")
def pruneOriginalsCallback(arg, dirname, fnames):
"""Callback for os.path.walk() to remove 'Originals' directories."""
# XXX toFS should be changed to omit the 'Original' directories,
# then this function wouldn't be needed
base = normcase(os.path.basename(dirname))
if base == ZOPEDIR:
originals = filter(lambda n: normcase(n) == ORIGINAL, fnames)
if originals:
filter(fnames.remove, originals)
fullname = os.path.join(dirname, ORIGINAL)
shutil.rmtree(fullname)
# XXX Still to do: the reverse operation, fromFS. This should
# probably be an HTML form with the zipfile as an uploaded file
=== Zope3/src/zope/app/browser/content/configure.zcml 1.19 => 1.20 ===
--- Zope3/src/zope/app/browser/content/configure.zcml:1.19 Wed Apr 9 07:47:52 2003
+++ Zope3/src/zope/app/browser/content/configure.zcml Wed May 7 21:08:42 2003
@@ -424,4 +424,14 @@
description="An object storing XML text."
/>
+ <!-- toFS.zip view, for new fssync tools -->
+
+ <browser:page
+ for="zope.interface.Interface"
+ name="toFS.zip"
+ permission="zope.ManageServices"
+ class="zope.app.browser.content.fssync.ZipFile"
+ attribute="show"
+ />
+
</zopeConfigure>