[Zope3-checkins] CVS: Zope3/src/zope/app/vfs/container - __init__.py:1.2 adding.py:1.2 configure.zcml:1.2 traverser.py:1.2 view.py:1.2
Jim Fulton
jim@zope.com
Wed, 25 Dec 2002 09:13:59 -0500
Update of /cvs-repository/Zope3/src/zope/app/vfs/container
In directory cvs.zope.org:/tmp/cvs-serv15352/src/zope/app/vfs/container
Added Files:
__init__.py adding.py configure.zcml traverser.py view.py
Log Message:
Grand renaming:
- Renamed most files (especially python modules) to lower case.
- Moved views and interfaces into separate hierarchies within each
project, where each top-level directory under the zope package
is a separate project.
- Moved everything to src from lib/python.
lib/python will eventually go away. I need access to the cvs
repository to make this happen, however.
There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.
=== Zope3/src/zope/app/vfs/container/__init__.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:59 2002
+++ Zope3/src/zope/app/vfs/container/__init__.py Wed Dec 25 09:13:28 2002
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.
=== Zope3/src/zope/app/vfs/container/adding.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:59 2002
+++ Zope3/src/zope/app/vfs/container/adding.py Wed Dec 25 09:13:28 2002
@@ -0,0 +1,59 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Adding View for IContentContainer
+
+This
+
+$Id$
+"""
+from zope.component import getAdapter
+
+from zope.event import publish
+from zope.app.event.objectevent import ObjectAddedEvent
+
+from zope.publisher.interfaces import IPublishTraverse
+from zope.publisher.vfs import VFSView
+
+from zope.app.interfaces.container import IAdding
+from zope.app.interfaces.container import IContainerNamesContainer
+from zope.app.interfaces.container import IZopeContainer
+
+
+class Adding(VFSView):
+
+ __implements__ = IAdding, VFSView.__implements__
+
+ ############################################################
+ # Implementation methods for interface
+ # IAdding.py
+
+ def add(self, content):
+ 'See IAdding'
+ container = self.context
+ container = getAdapter(container, IZopeContainer)
+ name = container.setObject(self.contentName, content)
+ publish(self.context, ObjectAddedEvent(container[name]))
+ return container[name]
+
+ def setContentName(self, name):
+ self.contentName = name
+
+ # See IAdding
+ contentName = None # usually set by setContentName
+
+ # See IPresentation
+ request = None # set in VFSView.__init__
+
+ # See IContextDependent
+ context = None # set in VFSView.__init__
=== Zope3/src/zope/app/vfs/container/configure.zcml 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:59 2002
+++ Zope3/src/zope/app/vfs/container/configure.zcml Wed Dec 25 09:13:28 2002
@@ -0,0 +1,32 @@
+<zopeConfigure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:vfs="http://namespaces.zope.org/vfs">
+
+ <vfs:view
+ name="_traverse"
+ for="zope.app.interfaces.container.IItemContainer"
+ factory="zope.app.vfs.container.traverser.ItemTraverser" />
+
+ <vfs:view
+ name="_traverse"
+ for="zope.app.interfaces.container.IReadContainer"
+ factory="zope.app.vfs.container.traverser.ContainerTraverser" />
+
+
+ <vfs:view
+ for="zope.app.interfaces.container.IContentContainer"
+ name="+"
+ factory="zope.app.vfs.container.adding.Adding"
+ allowed_attributes="setContentName add"
+ permission="zope.ManageContent" />
+
+ <!-- Generic VFS Container View -->
+ <vfs:view
+ name="vfs"
+ for="zope.app.interfaces.container.IContainer"
+ permission="zope.ManageContent"
+ allowed_interface="zope.publisher.interfaces.vfs.IVFSDirectoryPublisher"
+ factory="zope.app.vfs.container.view.VFSContainerView"
+ />
+
+</zopeConfigure>
=== Zope3/src/zope/app/vfs/container/traverser.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:59 2002
+++ Zope3/src/zope/app/vfs/container/traverser.py Wed Dec 25 09:13:28 2002
@@ -0,0 +1,89 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""Define VFS View Traverser for folder contents.
+
+$Id$
+"""
+
+from zope.publisher.interfaces.vfs import IVFSPublisher
+from zope.publisher.interfaces import NotFound
+from zope.app.interfaces.container import \
+ ISimpleReadContainer, IItemContainer
+from zope.component import queryView
+
+
+class ContainerTraverser:
+
+ __implements__ = IVFSPublisher
+ __used_for__ = ISimpleReadContainer
+
+ def __init__(self, container, request):
+ """Initialize Traverser."""
+ self.context = container
+ self.request = request
+
+ def _splitExtension(self, name):
+ """Split the possible extension from the name"""
+ ext_start = name.rfind(".")
+ if ext_start > 0:
+ return name[:ext_start], name[ext_start:]
+ return name, ""
+
+ def publishTraverse(self, request, name):
+ """See IPublishTraverse."""
+ context = self.context
+
+ # First, try to resolve the name as we get it.
+ subob = context.get(name, None)
+
+ if subob is None:
+ # It did not work the first time, so let's try without the
+ # extension.
+ name, ext = self._splitExtension(name)
+ subob = context.get(name, None)
+
+ if subob is None:
+ view = queryView(context, name, request)
+ if view is not None:
+ return view
+
+ raise NotFound(context, name, request)
+
+ return subob
+
+
+class ItemTraverser(ContainerTraverser):
+
+ __used_for__ = IItemContainer
+
+ def publishTraverse(self, request, name):
+ """See IPublishTraverse."""
+ context = self.context
+
+ # First, try to resolve the name as we get it.
+ try:
+ return context[name]
+ except KeyError:
+ pass
+
+ # It did not work the first time, so let's try without the extension.
+ name, ext = self._splitExtension(name)
+ try:
+ return context[name]
+ except KeyError:
+ view = queryView(context, name, request)
+ if view is not None:
+ return view
+
+ raise NotFound(context, name, request)
=== Zope3/src/zope/app/vfs/container/view.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:59 2002
+++ Zope3/src/zope/app/vfs/container/view.py Wed Dec 25 09:13:28 2002
@@ -0,0 +1,176 @@
+##############################################################################
+#
+# Copyright (c) 2001, 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.
+#
+##############################################################################
+"""VFS-View for IContainer
+
+VFS-view implementation for a generic container. It should really work for
+all container-like objects. There is not much that can be done differently.
+
+$Id$
+"""
+import fnmatch
+import datetime
+zerotime = datetime.datetime.fromtimestamp(0)
+
+from zope.component import \
+ getView, queryView, getAdapter, queryAdapter, createObject
+
+from zope.proxy.introspection import removeAllProxies
+
+from zope.publisher.interfaces import NotFound
+from zope.publisher.vfs import VFSView
+from zope.publisher.interfaces.vfs import IVFSPublisher
+from zope.publisher.vfs import VFSRequest
+from zope.publisher.interfaces.vfs import IVFSDirectoryPublisher
+
+from zope.app.interfaces.container import IContainer
+from zope.app.interfaces.dublincore import IZopeDublinCore
+
+
+class VFSContainerView(VFSView):
+
+ __implements__ = IVFSDirectoryPublisher, VFSView.__implements__
+
+ # This attribute specifies which type of container (factory id) should be
+ # used when a directory is created.
+ _directory_type = 'Container'
+
+ def exists(self, name):
+ 'See IVFSDirectoryPublisher'
+ try:
+ self.publishTraverse(self.request, name)
+ except NotFound:
+ return False
+ return True
+
+ def listdir(self, with_stats=0, pattern='*'):
+ 'See IVFSDirectoryPublisher'
+ file_list = self.context.keys()
+ # filter them using the pattern
+ file_list = list(
+ filter(lambda f, p=pattern, fnm=fnmatch.fnmatch: fnm(f, p),
+ file_list))
+ # sort them alphabetically
+ file_list.sort()
+ if not with_stats:
+ result = file_list
+ else:
+ result = []
+ for file in file_list:
+ obj = self.context[file]
+ view = queryView(obj, 'vfs', self.request)
+ if view is not None:
+ stat = view.stat()
+ else:
+ # Even though this object has no VFS view, we should
+ # display it.
+ stat = (16384+511, 0, 0, 0, "nouser", "nogroup", 0,
+ zerotime, zerotime, zerotime)
+ result.append((file, stat))
+
+ return result
+
+
+ def mkdir(self, name, mode=777):
+ 'See IVFSDirectoryPublisher'
+ if not (name in self.context):
+ adding = getView(self.context, "+", self.request)
+ adding.setContentName(name)
+ add = queryView(adding, self._directory_type, self.request)
+ add()
+
+ def remove(self, name):
+ 'See IVFSDirectoryPublisher'
+ container = removeAllProxies(self.context)
+ container.__delitem__(name)
+ # XXX: We should have a ObjectRemovedEvent here
+
+ def rmdir(self, name):
+ 'See IVFSDirectoryPublisher'
+ self.remove(name)
+
+ def rename(self, old, new):
+ 'See IVFSDirectoryPublisher'
+ container = self.context
+ content = container[old]
+ self.remove(old)
+ # Re-add the object
+ adding = getView(container, "+", self.request)
+ adding.setContentName(new)
+ content = adding.add(content)
+
+ def writefile(self, name, mode, instream, start=0):
+ 'See IVFSDirectoryPublisher'
+ # Find the extension
+ ext_start = name.rfind('.')
+ if ext_start > 0:
+ ext = name[ext_start:]
+ else:
+ ext = "."
+
+ # Create and add a new content object.
+ adding = getView(self.context, "+", self.request)
+ adding.setContentName(name)
+ add = queryView(adding, ext, self.request)
+ if add is None:
+ # We do not know about this content type, so choose the generic
+ # one.
+ add = queryView(adding, ".", self.request)
+
+ add(mode, instream, start)
+
+ def check_writable(self, name):
+ 'See IVFSDirectoryPublisher'
+ # XXX Cheesy band aid :-)
+ return 1
+
+ def isdir(self):
+ 'See IVFSObjectPublisher'
+ return 1
+
+ def isfile(self):
+ 'See IVFSObjectPublisher'
+ return 0
+
+ def stat(self):
+ 'See IVFSObjectPublisher'
+ dc = getAdapter(self.context, IZopeDublinCore)
+ if dc is not None:
+ created = dc.created
+ modified = dc.modified
+ else:
+ created = zerotime
+ modified = zerotime
+
+ # Sometimes this value is not set, but we need to return a datetime
+ if created is None:
+ created = zerotime
+ # It happens that modified might still be None, so make sure we return
+ # a date. *nix then uses the created date as the modified one, which we
+ # do too. ;)
+ if modified is None:
+ modified = created
+
+ dir_mode = 16384 + 504
+ uid = "nouser"
+ gid = "nogroup"
+ return (dir_mode, 0, 0, 0, uid, gid, 4096, modified, modified,
+ created)
+
+
+ def publishTraverse(self, request, name):
+ 'See IVFSPublisher'
+ # This is a nice way of doing the name lookup; this way we can keep
+ # all the extension handeling code in the Traverser code.
+ traverser = getView(self.context, '_traverse', request)
+ return traverser.publishTraverse(request, name)