[Zope3-checkins] CVS: Zope3/src/zope/app/browser/fssync -
__init__.py:1.2 configure.zcml:1.2 fromFS.pt:1.2
Philipp von Weitershausen
philikon at philikon.de
Tue Feb 24 11:49:14 EST 2004
Update of /cvs-repository/Zope3/src/zope/app/browser/fssync
In directory cvs.zope.org:/tmp/cvs-serv25869/src/zope/app/browser/fssync
Added Files:
__init__.py configure.zcml fromFS.pt
Log Message:
Created an fssync browser package for general fssync browser views,
which were formerly located in the no longer existing
zope.app.browser.content package.
=== Zope3/src/zope/app/browser/fssync/__init__.py 1.1 => 1.2 ===
--- /dev/null Tue Feb 24 11:49:14 2004
+++ Zope3/src/zope/app/browser/fssync/__init__.py Tue Feb 24 11:49:13 2004
@@ -0,0 +1,231 @@
+##############################################################################
+#
+# Copyright (c) 2003 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.snarf view and its inverse, fromFS.snarf.
+
+$Id$
+"""
+import os
+import cgi
+import shutil
+import tempfile
+
+from transaction import get_transaction
+
+from zope.app.publisher.browser import BrowserView
+from zope.app.traversing import getName, getParent, getRoot
+from zope.fssync.snarf import Snarfer, Unsnarfer
+from zope.app.fssync import syncer
+from zope.app.fssync.committer import Committer, Checker
+from zope.fssync.metadata import Metadata
+
+from zope.app.i18n import ZopeMessageIDFactory as _
+
+def snarf_dir(response, dirname):
+ """Helper to snarf a directory to the response."""
+ response.setStatus(200)
+ response.setHeader("Content-Type", "application/x-snarf")
+ snf = Snarfer(response)
+ snf.addtree(dirname)
+ return ""
+
+class SnarfFile(BrowserView):
+ """View returning a snarfed representation of an object tree.
+
+ This applies to any object (for="zope.interface.Interface").
+ """
+
+ def show(self):
+ """Return the snarfed response."""
+ dirname = tempfile.mktemp()
+ try:
+ os.mkdir(dirname)
+ syncer.toFS(self.context,
+ getName(self.context) or "root",
+ dirname)
+ return snarf_dir(self.request.response, dirname)
+ finally:
+ if os.path.isdir(dirname):
+ shutil.rmtree(dirname)
+
+class NewMetadata(Metadata):
+ """Subclass of Metadata that sets the 'added' flag in all entries."""
+
+ def getentry(self, file):
+ entry = Metadata.getentry(self, file)
+ if entry:
+ entry["flag"] = "added"
+ return entry
+
+
+class SnarfSubmission(BrowserView):
+ """Base class for the commit and checkin views."""
+
+ def run(self):
+ self.check_content_type()
+ self.set_transaction()
+ self.parse_args()
+ self.set_note()
+ try:
+ self.make_tempdir()
+ self.set_arguments()
+ self.make_metadata()
+ self.unsnarf_body()
+ return self.run_submission()
+ finally:
+ self.remove_tempdir()
+
+ def check_content_type(self):
+ if not self.request.getHeader("Content-Type") == "application/x-snarf":
+ raise ValueError(_("Content-Type is not application/x-snarf"))
+
+ def set_transaction(self):
+ self.txn = get_transaction()
+
+ def parse_args(self):
+ # The query string in the URL didn't get parsed, because we're
+ # getting a POST request with an unrecognized content-type
+ qs = self.request._environ.get("QUERY_STRING")
+ if qs:
+ self.args = cgi.parse_qs(qs)
+ else:
+ self.args = {}
+
+ def get_arg(self, key):
+ value = self.request.get(key)
+ if value is None:
+ values = self.args.get(key)
+ if values is not None:
+ value = " ".join(values)
+ return value
+
+ def set_note(self):
+ note = self.get_arg("note")
+ if note:
+ self.txn.note(note)
+
+ tempdir = None
+
+ def make_tempdir(self):
+ self.tempdir = tempfile.mktemp()
+ os.mkdir(self.tempdir)
+
+ def remove_tempdir(self):
+ if self.tempdir and os.path.exists(self.tempdir):
+ shutil.rmtree(self.tempdir)
+
+ def unsnarf_body(self):
+ fp = self.request.bodyFile
+ fp.seek(0)
+ uns = Unsnarfer(fp)
+ uns.unsnarf(self.tempdir)
+
+ def call_committer(self):
+ c = Committer(syncer.getSerializer, self.metadata,
+ getAnnotations=syncer.getAnnotations)
+ c.synch(self.container, self.name, self.fspath)
+
+
+class SnarfCheckin(SnarfSubmission):
+ """View for checking a new sub-tree into Zope.
+
+ The input should be a POST request whose data is a snarf archive.
+ This creates a brand new tree and doesn't return anything.
+ """
+
+ def run_submission(self):
+ # XXX need to make sure the top-level name doesn't already
+ # exist, or existing site data can get screwed
+ self.call_committer()
+ return ""
+
+ def set_arguments(self):
+ # Compute self.{name, container, fspath} for checkin()
+ name = self.get_arg("name")
+ if not name:
+ raise ValueError(_("required argument 'name' missing"))
+ src = self.get_arg("src")
+ if not src:
+ src = name
+ self.container = self.context
+ self.name = name
+ self.fspath = os.path.join(self.tempdir, src)
+
+ def make_metadata(self):
+ self.metadata = NewMetadata()
+
+
+class SnarfCommit(SnarfSubmission):
+ """View for committing changes to an existing tree.
+
+ The input should be a POST request whose data is a snarf archive.
+ It returns an updated snarf archive, or a text document with
+ errors.
+ """
+
+ def run_submission(self):
+ self.call_checker()
+ if self.errors:
+ return self.send_errors()
+ else:
+ self.call_committer()
+ self.write_to_filesystem()
+ return self.send_archive()
+
+ def set_arguments(self):
+ # Compute self.{name, container, fspath} for commit()
+ self.name = getName(self.context)
+ self.container = getParent(self.context)
+ if self.container is None and self.name == "":
+ # Hack to get loading the root to work
+ self.container = getRoot(self.context)
+ self.fspath = os.path.join(self.tempdir, "root")
+ else:
+ self.fspath = os.path.join(self.tempdir, self.name)
+
+ def make_metadata(self):
+ self.metadata = Metadata()
+
+ def get_checker(self, raise_on_conflicts=False):
+ return Checker(syncer.getSerializer,
+ self.metadata,
+ raise_on_conflicts,
+ getAnnotations=syncer.getAnnotations)
+
+ def call_checker(self):
+ if self.get_arg("raise"):
+ c = self.get_checker(True)
+ else:
+ c = self.get_checker()
+ c.check(self.container, self.name, self.fspath)
+ self.errors = c.errors()
+
+ def send_errors(self):
+ self.txn.abort()
+ lines = [_("Up-to-date check failed:")]
+ tempdir_sep = os.path.join(self.tempdir, "") # E.g. foo -> foo/
+ for e in self.errors:
+ lines.append(e.replace(tempdir_sep, ""))
+ lines.append("")
+ self.request.response.setHeader("Content-Type", "text/plain")
+ return "\n".join(lines)
+
+ def write_to_filesystem(self):
+ shutil.rmtree(self.tempdir) # Start with clean slate
+ os.mkdir(self.tempdir)
+ syncer.toFS(self.context,
+ getName(self.context) or "root",
+ self.tempdir)
+
+ def send_archive(self):
+ return snarf_dir(self.request.response, self.tempdir)
=== Zope3/src/zope/app/browser/fssync/configure.zcml 1.1 => 1.2 ===
--- /dev/null Tue Feb 24 11:49:14 2004
+++ Zope3/src/zope/app/browser/fssync/configure.zcml Tue Feb 24 11:49:14 2004
@@ -0,0 +1,31 @@
+<zope:configure
+ xmlns="http://namespaces.zope.org/browser"
+ xmlns:zope="http://namespaces.zope.org/zope">
+
+ <!-- toFS.snarf and fromFS.snarf views, for new fssync tools -->
+
+ <!-- fssync checkout, update -->
+ <page
+ for="zope.interface.Interface"
+ name="toFS.snarf"
+ permission="zope.ManageServices"
+ class=".SnarfFile"
+ attribute="show" />
+
+ <!-- fssync commit -->
+ <page
+ for="zope.interface.Interface"
+ name="fromFS.snarf"
+ permission="zope.ManageServices"
+ class=".SnarfCommit"
+ attribute="run" />
+
+ <!-- fssync checkin -->
+ <page
+ for="zope.interface.Interface"
+ name="checkin.snarf"
+ permission="zope.ManageServices"
+ class=".SnarfCheckin"
+ attribute="run" />
+
+</zope:configure>
=== Zope3/src/zope/app/browser/fssync/fromFS.pt 1.1 => 1.2 ===
--- /dev/null Tue Feb 24 11:49:14 2004
+++ Zope3/src/zope/app/browser/fssync/fromFS.pt Tue Feb 24 11:49:14 2004
@@ -0,0 +1,26 @@
+<html metal:use-macro="views/standard_macros/page">
+<body>
+<div metal:fill-slot="body">
+
+ <h1 i18n:translate="">Commit Action</h1>
+
+ <div tal:define="status view/update"
+ tal:condition="status"
+ i18n:translate="">
+ Commit results:
+ <pre tal:content="status" i18n:name="results">
+ Status from update method goes here.
+ </pre>
+ </div>
+
+ <p i18n:translate="">Upload a zipfile in the following form</p>
+
+ <form method="post" action="@@fromFS.html" enctype="multipart/form-data">
+ <input type="file" name="zipfile" size="40" />
+ <input type="submit" value="Upload"
+ i18n:attributes="value upload-button"/>
+ </form>
+
+</div>
+</body>
+</html>
More information about the Zope3-Checkins
mailing list