[Zope3-checkins] CVS: Zope3/src/zope/app/browser/content - configure.zcml:1.23 fssync.py:1.12
Guido van Rossum
guido@python.org
Tue, 20 May 2003 15:09:55 -0400
Update of /cvs-repository/Zope3/src/zope/app/browser/content
In directory cvs.zope.org:/tmp/cvs-serv19784
Modified Files:
configure.zcml fssync.py
Log Message:
Don't use zip/unzip -- use a home-grown protocol that can read/write
directly from/to a stream, dubbed "snarf". This only does what we need.
=== Zope3/src/zope/app/browser/content/configure.zcml 1.22 => 1.23 ===
--- Zope3/src/zope/app/browser/content/configure.zcml:1.22 Thu May 8 18:20:05 2003
+++ Zope3/src/zope/app/browser/content/configure.zcml Tue May 20 15:09:53 2003
@@ -424,29 +424,21 @@
description="An object storing XML text."
/>
- <!-- toFS.zip and fromFS.html views, for new fssync tools -->
+ <!-- toFS.snarf and fromFS.snarf views, for new fssync tools -->
<browser:page
for="zope.interface.Interface"
- name="toFS.zip"
+ name="toFS.snarf"
permission="zope.ManageServices"
- class="zope.app.browser.content.fssync.ZipFile"
+ class="zope.app.browser.content.fssync.SnarfFile"
attribute="show"
/>
<browser:page
for="zope.interface.Interface"
- name="fromFS.html"
+ name="fromFS.snarf"
permission="zope.ManageServices"
- class="zope.app.browser.content.fssync.Commit"
- template="fromFS.pt"
- />
-
- <browser:page
- for="zope.interface.Interface"
- name="fromFS.zip"
- permission="zope.ManageServices"
- class="zope.app.browser.content.fssync.Commit"
+ class="zope.app.browser.content.fssync.SnarfCommit"
attribute="commit"
/>
=== Zope3/src/zope/app/browser/content/fssync.py 1.11 => 1.12 ===
--- Zope3/src/zope/app/browser/content/fssync.py:1.11 Thu May 15 18:25:46 2003
+++ Zope3/src/zope/app/browser/content/fssync.py Tue May 20 15:09:54 2003
@@ -12,7 +12,7 @@
#
##############################################################################
-"""Code for the toFS.zip view and its inverse, fromFS.form.
+"""Code for the toFS.snarf view and its inverse, fromFS.snarf.
$Id$
"""
@@ -29,120 +29,53 @@
from zope.app.fssync.syncer import toFS, fromFS
from zope.app.traversing import objectName, getParent, getRoot
from zope.app.interfaces.exceptions import UserError
+from zope.fssync.snarf import Snarfer, Unsnarfer
-class ZipFile(BrowserView):
+class SnarfFile(BrowserView):
- """View returning a zipped filesystem representation of an object tree.
+ """View returning a snarfed 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)
- f = open(zipfilename, "rb")
- data = f.read()
- f.close()
- os.remove(zipfilename)
+ """Return the snarfed response."""
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 isset(s):
- """Helper to decide whether a string meant True or False."""
- if not s:
- return False
- s = s.strip()
- if not s:
- return False
- s = s.lower()
- istrue = isfalse = False
- for match in "true", "yes", "on", "1":
- if match.startswith(s):
- istrue = True
- break
- for match in "false", "no", "off", "0":
- if match.startswith(s):
- isfalse = True
- break
- if istrue and not isfalse:
- return True
- if isfalse and not istrue:
- return False
- raise ValueError, "invalid flag (%r)" % s
-
-def writeZipFile(obj):
- """Helper to render the object tree to the filesystem and zip it.
-
- Return the name of the zipfile.
- """
- dirname = tempfile.mktemp()
- os.mkdir(dirname)
- try:
- # XXX toFS prints to stdout; it shouldn't
- toFS(obj, objectName(obj) or "root", dirname)
- 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 not sts:
- return zipfilename
+ response.setStatus(200)
+ response.setHeader("Content-Type", "application/x-snarf")
+ dirname = tempfile.mktemp()
try:
- os.remove(zipfilename)
- except os.error:
- pass
- raise RuntimeError("zip status %#x; output:\n%s" % (sts, output))
- finally:
- shutil.rmtree(dirname)
+ os.mkdir(dirname)
+ toFS(self.context, objectName(self.context) or "root", dirname)
+ snf = Snarfer(response)
+ snf.addtree(dirname)
+ finally:
+ if os.path.isdir(dirname):
+ shutil.rmtree(dirname)
+ return ""
-# And here is the inverse operation, fromFS.html (an HTML form).
+# And here is the inverse operation, fromFS.snarf.
-class Commit(ZipFile):
+class SnarfCommit(SnarfFile):
- """View for committing changes.
-
- For now, this is an HTML form where you can upload a zipfile.
- """
-
- def update(self):
- zipfile = self.request.get("zipfile")
- if zipfile is None:
- return # Not updating -- must be presenting a blank form
- else:
- zipdata = zipfile.read()
- errors = self.do_commit(zipdata)
- if not errors:
- return "Changes committed successfully."
- else:
- errors.insert(0, "Up-to-date check failed:")
- raise UserError(*errors)
+ """View for committing changes."""
def commit(self):
- if not self.request.getHeader("Content-Type") == "application/zip":
+ if not self.request.getHeader("Content-Type") == "application/x-snarf":
self.request.response.setHeader("Content-Type", "text/plain")
- return "ERROR: Content-Type is not application/zip\n"
- zipdata = self.request.body
- errors = self.do_commit(zipdata)
+ return "ERROR: Content-Type is not application/x-snarf\n"
+ istr = self.request.bodyFile
+ istr.seek(0)
+ errors = self.do_commit(istr)
if not errors:
- return self.show() # Return the zipfile!
+ return self.show() # Return the snarfed tree!
else:
self.request.response.setHeader("Content-Type", "text/plain")
errors.insert(0, "Up-to-date check failed:")
errors.append("")
return "\n".join(errors)
- def do_commit(self, zipdata):
+ def do_commit(self, istr):
# 000) Set transaction note
note = self.request.get("note")
if not note:
@@ -154,21 +87,17 @@
note = urllib.unquote(note)
if note:
get_transaction().note(note)
- # 00) Allocate temporary names
+ # 0) Allocate temporary names
topdir = tempfile.mktemp()
- zipfilename = os.path.join(topdir, "working.zip")
working = os.path.join(topdir, "working")
current = os.path.join(topdir, "current")
try:
- # 0) Create the top directory
+ # 1) Create the top directory
os.mkdir(topdir)
- # 1) Write the zipfile data to disk
- f = open(zipfilename, "wb")
- f.write(zipdata)
- f.close()
- # 2) Unzip it into a working directory
+ # 2) Unsnarf into a working directory
os.mkdir(working)
- os.system("cd %s; unzip -q %s" % (working, zipfilename))
+ uns = Unsnarfer(istr)
+ uns.unsnarf(working)
# 3) Save the current state of the object to disk
os.mkdir(current)
toFS(self.context, objectName(self.context) or "root", current)