[Zope3-checkins] CVS: Zope3/src/zope/app/browser/content - configure.zcml:1.23.2.1 file.py:1.2.28.1 folder.py:1.2.28.1 fssync.py:1.12.2.1 i18n.py:1.2.28.1 i18nimage.py:1.3.12.1 sql.py:1.5.24.1 sqltest.pt:1.2.28.1
Grégoire Weber
zope@i-con.ch
Sun, 22 Jun 2003 10:24:09 -0400
Update of /cvs-repository/Zope3/src/zope/app/browser/content
In directory cvs.zope.org:/tmp/cvs-serv24874/src/zope/app/browser/content
Modified Files:
Tag: cw-mail-branch
configure.zcml file.py folder.py fssync.py i18n.py
i18nimage.py sql.py sqltest.pt
Log Message:
Synced up with HEAD
=== Zope3/src/zope/app/browser/content/configure.zcml 1.23 => 1.23.2.1 ===
--- Zope3/src/zope/app/browser/content/configure.zcml:1.23 Tue May 20 15:09:53 2003
+++ Zope3/src/zope/app/browser/content/configure.zcml Sun Jun 22 10:22:38 2003
@@ -248,45 +248,28 @@
file="folder_icon.gif"
/>
- <browser:menuItems menu="zmi_views"
- for="zope.app.interfaces.content.folder.IFolder">
-
- <browser:menuItem title="Contents"
- action="@@contents.html"
- />
-
- </browser:menuItems>
-
<browser:menuItem menu="add_content"
for="zope.app.interfaces.container.IAdding"
title="Folder" action="Folder"
description="A simple Folder."
/>
- <browser:pages
+ <browser:page
+ name="contents.html"
+ menu="zmi_views" title="Contents"
for="zope.app.interfaces.content.folder.IFolder"
permission="zope.ManageContent"
class="zope.app.browser.container.contents.Contents"
- >
-
- <browser:page name="contents.html" attribute="contents" />
- <browser:page name="removeObjects.html" attribute="removeObjects" />
- <browser:page name="cutObjects.html" attribute="cutObjects" />
- <browser:page name="copyObjects.html" attribute="copyObjects" />
- <browser:page name="pasteObjects.html" attribute="pasteObjects" />
- <browser:page name="renameObjects.html" attribute="renameObjects" />
- <browser:page name="rename.html" attribute="rename" />
-
- </browser:pages>
+ attribute="contents"
+ />
- <browser:pages
+ <browser:page
+ name="index.html"
for="zope.app.interfaces.content.folder.IFolder"
permission="zope.View"
- class="zope.app.browser.container.contents.Contents">
-
- <browser:page name="index.html" attribute="index" />
-
- </browser:pages>
+ class="zope.app.browser.container.contents.Contents"
+ attribute="index"
+ />
<browser:page
for="zope.app.interfaces.content.folder.IFolder"
@@ -340,13 +323,6 @@
/>
<browser:menuItem
- menu="zmi_views"
- for="zope.app.interfaces.content.sql.ISQLScript"
- title="Cache"
- action="Caching.html"
- />
-
- <browser:menuItem
menu="add_content"
for="zope.app.interfaces.container.IAdding"
title="SQLScript"
@@ -440,6 +416,14 @@
permission="zope.ManageServices"
class="zope.app.browser.content.fssync.SnarfCommit"
attribute="commit"
+ />
+
+ <browser:page
+ for="zope.interface.Interface"
+ name="checkin.snarf"
+ permission="zope.ManageServices"
+ class="zope.app.browser.content.fssync.SnarfCommit"
+ attribute="checkin"
/>
</zopeConfigure>
=== Zope3/src/zope/app/browser/content/file.py 1.2 => 1.2.28.1 ===
--- Zope3/src/zope/app/browser/content/file.py:1.2 Wed Dec 25 09:12:30 2002
+++ Zope3/src/zope/app/browser/content/file.py Sun Jun 22 10:22:38 2003
@@ -46,7 +46,7 @@
"""File editing mix-in that uses a file-upload widget.
"""
- data = CustomWidget(FileWidget)
+ data_widget = CustomWidget(FileWidget)
=== Zope3/src/zope/app/browser/content/folder.py 1.2 => 1.2.28.1 ===
--- Zope3/src/zope/app/browser/content/folder.py:1.2 Wed Dec 25 09:12:30 2002
+++ Zope3/src/zope/app/browser/content/folder.py Sun Jun 22 10:22:38 2003
@@ -15,10 +15,10 @@
$Id$
"""
-
+from zope.interface import implements
from zope.app.browser.container.adding import Adding
from zope.app.interfaces.content.folder import IFolderAdding
class FolderAdding(Adding):
- __implements__ = IFolderAdding
+ implements(IFolderAdding)
=== Zope3/src/zope/app/browser/content/fssync.py 1.12 => 1.12.2.1 ===
--- Zope3/src/zope/app/browser/content/fssync.py:1.12 Tue May 20 15:09:54 2003
+++ Zope3/src/zope/app/browser/content/fssync.py Sun Jun 22 10:22:38 2003
@@ -18,18 +18,27 @@
"""
import os
+import cgi
import shutil
import tempfile
from transaction import get_transaction
-from zope.fssync.compare import checkUptodate
-
from zope.publisher.browser import BrowserView
-from zope.app.fssync.syncer import toFS, fromFS
-from zope.app.traversing import objectName, getParent, getRoot
+from zope.app.traversing import getName, getParent, getRoot
from zope.app.interfaces.exceptions import UserError
from zope.fssync.snarf import Snarfer, Unsnarfer
+from zope.app.fssync.syncer import toFS
+from zope.app.fssync.committer import Committer, Checker
+from zope.fssync.metadata import Metadata
+
+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):
@@ -40,85 +49,174 @@
def show(self):
"""Return the snarfed response."""
- response = self.request.response
- response.setStatus(200)
- response.setHeader("Content-Type", "application/x-snarf")
dirname = tempfile.mktemp()
try:
os.mkdir(dirname)
- toFS(self.context, objectName(self.context) or "root", dirname)
- snf = Snarfer(response)
- snf.addtree(dirname)
+ 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)
- return ""
-# And here is the inverse operation, fromFS.snarf.
+class NewMetadata(Metadata):
+ """Subclass of Metadata that sets the 'added' flag in all entries."""
-class SnarfCommit(SnarfFile):
+ def getentry(self, file):
+ entry = Metadata.getentry(self, file)
+ if entry:
+ entry["flag"] = "added"
+ return entry
+
+class SnarfCommit(BrowserView):
+
+ """View for committing and checking in changes.
+
+ The input to commit() should be a POST request whose data is a
+ snarf archive. It returns an updated snarf archive, or a text
+ document with errors.
+
+ The alternate entry point checkin() is for checking in a new
+ archive. It is similar to commit() but creates a brand new tree
+ and doesn't return anything.
+ """
- """View for committing changes."""
+ # XXX Maybe split into two classes with a common base instead?
def commit(self):
+ self.check_content_type()
+ self.set_transaction()
+ self.parse_args()
+ self.set_note()
+ try:
+ self.make_tempdir()
+ self.set_commit_arguments()
+ self.make_commit_metadata()
+ self.unsnarf_body()
+ self.call_checker()
+ if self.errors:
+ return self.send_errors()
+ else:
+ self.call_committer()
+ self.write_to_filesystem()
+ return self.send_archive()
+ finally:
+ self.remove_tempdir()
+
+ def checkin(self):
+ self.check_content_type()
+ self.set_transaction()
+ self.parse_args()
+ self.set_note()
+ try:
+ self.make_tempdir()
+ self.set_checkin_arguments()
+ self.make_checkin_metadata()
+ self.unsnarf_body()
+ self.call_committer()
+ return ""
+ finally:
+ self.remove_tempdir()
+
+ def check_content_type(self):
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/x-snarf\n"
- istr = self.request.bodyFile
- istr.seek(0)
- errors = self.do_commit(istr)
- if not errors:
- return self.show() # Return the snarfed tree!
+ 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.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, istr):
- # 000) Set transaction note
- note = self.request.get("note")
- if not note:
- # XXX Hack because cgi doesn't parse the query string
- qs = self.request._environ.get("QUERY_STRING")
- if qs and qs.startswith("note="):
- note = qs[5:]
- import urllib
- note = urllib.unquote(note)
+ 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:
- get_transaction().note(note)
- # 0) Allocate temporary names
- topdir = tempfile.mktemp()
- working = os.path.join(topdir, "working")
- current = os.path.join(topdir, "current")
- try:
- # 1) Create the top directory
- os.mkdir(topdir)
- # 2) Unsnarf into a working directory
- os.mkdir(working)
- 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)
- # 4) Check that the working originals are up-to-date
- errors = checkUptodate(working, current)
- if errors:
- # Make the messages nicer by editing out topdir
- errors = [x.replace(os.path.join(topdir, ""), "")
- for x in errors]
- return errors
- # 5) Now call fromFS()
- name = objectName(self.context)
- container = getParent(self.context)
- if container is None and name == "":
- # Hack to get loading the root to work; see top of fromFS().
- container = getRoot(self.context)
- fromFS(container, name, working)
- # 6) Return success
- return []
- finally:
- try:
- shutil.rmtree(topdir)
- except os.error:
- pass
+ self.txn.note(note)
+
+ def set_commit_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 set_checkin_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_commit_metadata(self):
+ self.metadata = Metadata()
+
+ def make_checkin_metadata(self):
+ self.metadata = NewMetadata()
+
+ 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_checker(self):
+ if self.get_arg("raise"):
+ c = Checker(self.metadata, True)
+ else:
+ c = Checker(self.metadata)
+ 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 call_committer(self):
+ c = Committer(self.metadata)
+ c.synch(self.container, self.name, self.fspath)
+
+ def write_to_filesystem(self):
+ shutil.rmtree(self.tempdir) # Start with clean slate
+ os.mkdir(self.tempdir)
+ 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/content/i18n.py 1.2 => 1.2.28.1 ===
--- Zope3/src/zope/app/browser/content/i18n.py:1.2 Wed Dec 25 09:12:30 2002
+++ Zope3/src/zope/app/browser/content/i18n.py Sun Jun 22 10:22:38 2003
@@ -41,8 +41,6 @@
class I18nFileEdit(BrowserView):
- __implements__ = BrowserView.__implements__
-
name = 'editForm'
title = 'Edit Form'
description = ('This edit form allows you to make changes to the ' +
=== Zope3/src/zope/app/browser/content/i18nimage.py 1.3 => 1.3.12.1 ===
--- Zope3/src/zope/app/browser/content/i18nimage.py:1.3 Wed Apr 30 19:37:51 2003
+++ Zope3/src/zope/app/browser/content/i18nimage.py Sun Jun 22 10:22:38 2003
@@ -25,8 +25,6 @@
class I18nImageEdit(BrowserView):
- __implements__ = BrowserView.__implements__
-
name = 'editForm'
title = 'Edit Form'
description = ('This edit form allows you to make changes to the ' +
=== Zope3/src/zope/app/browser/content/sql.py 1.5 => 1.5.24.1 ===
--- Zope3/src/zope/app/browser/content/sql.py:1.5 Thu Feb 20 11:46:04 2003
+++ Zope3/src/zope/app/browser/content/sql.py Sun Jun 22 10:22:38 2003
@@ -17,21 +17,11 @@
from zope.publisher.browser import BrowserView
from zope.app.interfaces.content.sql import ISQLScript
from zope.app.interfaces.rdb import DatabaseException
-from zope.proxy.context import ContextMethod
+from zope.context import ContextMethod
class SQLScriptTest(BrowserView):
"""Edit View for SQL Scripts"""
- # XXX: if the following line is uncommented, @@test.html stops working
- # __implements__ = BrowserView.__implements__
- #
- # Just found the reason: if you specify __implements__ here, it overrides
- # the one defined in zope.app.pagetemplate.simpeviewclass.simple,
- # and IBrowserPublisher disappears from the interface list. Instead,
- # __implements__ of the newly created class (see SimpleViewClass in the
- # same module) ought to be a union of __implements__ of all the base
- # classes. Or perhaps it should be done by zope.app.browser.form.editview?
-
__used_for__ = ISQLScript
error = None
@@ -39,20 +29,19 @@
def getArguments(self):
form = self.request.form
arguments = {}
- # XXX does anyone know what arg[0] and arg[1] are supposed to be?
- for arg in self.context.getArguments().items():
- value = form.get(arg[0])
+
+ for argname, argvalue in self.context.getArguments().items():
+ value = form.get(argname)
if value is None:
- value = arg[1].get('default')
+ value = argvalue.get('default')
if value is not None:
- arguments[arg[0].encode('UTF-8')] = value
+ arguments[argname.encode('UTF-8')] = value
return arguments
def getTestResults(self):
- self.context.getConnection()
try:
return self.context(**self.getArguments())
- except (DatabaseException, AttributeError), error:
+ except (DatabaseException, AttributeError, Exception), error:
self.error = error
return []
=== Zope3/src/zope/app/browser/content/sqltest.pt 1.2 => 1.2.28.1 ===
--- Zope3/src/zope/app/browser/content/sqltest.pt:1.2 Wed Dec 25 09:12:30 2002
+++ Zope3/src/zope/app/browser/content/sqltest.pt Sun Jun 22 10:22:38 2003
@@ -7,7 +7,7 @@
<div metal:fill-slot="body">
<form action="." method="post">
- <pre tal:content="context/getSource" />
+ <pre tal:content="context/source" />
<table border="1"
tal:define="args context/getArguments"