source: cmfdeployment/branches/kenw-p4-wip/structure.py @ 2380

Last change on this file since 2380 was 2380, checked in by kenw, 8 years ago

Committing new branch intended for Plone 4 compatibility; mostly required imports of new zope packages

File size: 7.2 KB
Line 
1##################################################################
2#
3# (C) Copyright 2002-2006 Kapil Thangavelu <k_vertigo@objectrealms.net>
4# All Rights Reserved
5#
6# This file is part of CMFDeployment.
7#
8# CMFDeployment is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# CMFDeployment is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with CMFDeployment; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21##################################################################
22"""
23Purpose: File System Directory Proxies and Modeling
24Author: kapil thangavelu <k_vertigo@objectrealms.net> @2002-2006
25License: GPL
26Created: 8/10/2002
27$Id: structure.py 1168M 2010-09-27 14:51:10Z (local) $
28"""
29
30import os
31from Acquisition import aq_base
32from OFS.ObjectManager import ObjectManager
33from OFS.Folder import Folder
34
35#from Interface import Base as Interface
36from zope.interface import Interface
37
38from Globals import DTMLFile
39
40class DirectoryCreationException(Exception): pass
41
42class IDirectory(Interface):
43
44    """
45    also implements IPropertyManager
46    """
47
48    def addDirectory(directory_name):
49        """
50        adds a sub directory to this
51        directory with the given name
52        """
53
54    def getName():
55        """
56        returns the name of this directory
57        """
58
59    def getPath():
60        """
61        returns the absolute path of
62        the directory relative to the
63        root directory
64        """
65
66class IRootDirectory(IDirectory):
67
68    def getRootDirectory():
69        """
70        return the root directory
71        """
72
73    def getDirectories():
74        """
75        returns a list consisting of this
76        directory and all its sub directories
77        """
78
79    def getDirectoryPaths():
80        """
81        returns a list consisting of this
82        directory and all its sub directory
83        paths
84        """
85
86    def mountFileStructure(path):
87        """
88        creates a fascimile consisting of the
89        file directory structure relative to this
90        RootDirectory at path.
91        """
92
93class Directory(ObjectManager):
94
95    meta_type = 'FS Structure Directory'
96
97    def __init__(self, id):
98        self.id = id
99
100    def getName(self):
101        return self.id
102
103    getId = getName
104
105    def getPath(self):
106        directories = ascendant_obj_collector(self, "getRootDirectory")
107        directories.reverse()
108        return os.sep.join([d.getName() for d in directories])
109
110    def addDirectory(self, directory_name):
111        d = Directory(directory_name)
112        self._setObject(directory_name, d, set_owner=0)
113
114    def all_meta_types(self):
115        return self.getRootDirectory().all_meta_types
116
117class FileSystemMountError(Exception): pass
118
119class FileSystemMountPoint:
120
121    mount_point = None
122
123    filesystem_mount = DTMLFile('ui/FileSystemMountForm', globals())
124   
125    def setMountPoint(self, mount_point, RESPONSE=None):
126        """ """
127        if not self.isValidMountPoint(mount_point):
128            raise FileSystemMountError(" invalid mount point %s"%mount_point)
129        self.mount_point = mount_point
130
131        if RESPONSE is not None:
132            RESPONSE.redirect('manage_workspace')
133
134    def isValidMountPoint(self, mount_point):
135        checks = (os.F_OK, os.R_OK, os.W_OK, os.X_OK)
136        return not not filter(None, map(lambda c, mp=mount_point, a=os.access: a(mp,c), checks))
137
138    def getMountPoint(self):
139        return self.mount_point
140
141    def mount(self):
142        directories = self.getDirectories()
143
144        mp = self.mount_point
145        j  = os.path.join
146        e  = os.path.exists
147        id = os.path.isdir
148        md = os.mkdir
149       
150        paths = [d.getPath() for d in directories]
151        for p in paths:
152            dp = j(mp, p)
153            if e(dp):
154                if not id(dp):               
155                    raise FileSystemMountError("file blocking mount %s"%dp)
156                continue
157            md(dp)
158           
159class RootDirectory(Folder, Directory, FileSystemMountPoint):
160
161    meta_type = 'FS Structure Root'
162
163    addDirectoryForm = DTMLFile('ui/StructureAddDirectoryForm', globals())
164
165    all_meta_types = (
166        {'name':Directory.meta_type,
167         'action':'addDirectoryForm'},
168        )
169
170    def getName(self):
171        return self.mount_point
172
173    def getRootDirectory(self):
174        return self
175
176    def getDirectories(self):
177        return descendant_obj_collector(self)
178
179    def getDirectoryPaths(self):
180        return [d.getPath() for d in self.getDirectories()]
181
182#################################
183# some variations on a theme     
184
185def ascendant_obj_collector(obj, attribute_name):
186    """
187    collect objects up the containment hierarchy
188    till we find one with an attribute_name attribute
189    """
190
191    res = []
192    w = res.append
193    o = obj.aq_inner
194
195    while not hasattr(o.aq_base, attribute_name):
196        w(o)
197        o = o.aq_parent
198    w(o)
199
200    return res
201
202class descender:
203
204    def __init__(self, gc_threshold=100):
205        self.gc_threshold = gc_threshold
206        self.obj_count = 0
207
208def descendant_obj_collector(o):
209    """
210    collect objects down the containment hierarchy
211    """
212   
213    r = []
214    for oc in o.objectValues():
215        r.append(oc)
216        if hasattr(oc.aq_base, 'isAnObjectManager'):
217            r.extend(descendant_obj_collector(oc))
218        if getattr(oc, '_p_changed', None)==None:
219            if hasattr(oc, '_p_deactivate'):
220                oc._p_deactivate()
221    return r
222
223def descendant_folder_collector(o):
224    r = []
225    w = r.append
226    for oc in o.objectValues():
227        if hasattr(aq_base(oc), 'isAnObjectManager'):
228            w(oc)
229            r.extend(descendant_folder_collector(oc))
230        elif getattr(oc, '_p_changed', None)==None:
231            if hasattr(oc, '_p_deactivate'):           
232                oc._p_deactivate()
233    return r
234
235class descendant_filtered_folder_collector(descender):
236   
237    def __call__(self, o, filter):
238        r = []
239        w = r.append
240        for oc in o.objectValues():
241            self.obj_count += 1           
242            if hasattr(aq_base(oc), 'isAnObjectManager'):
243                if not filter(oc): continue
244                w(oc)
245                r.extend(self(oc, filter))
246            elif getattr(oc, '_p_changed', None)==None:
247                if hasattr(oc, '_p_deactivate'):           
248                    oc._p_deactivate()
249            if self.obj_count % self.gc_threshold == 0:
250                if hasattr(o, '_p_jar'):
251                    o._p_jar.cacheGC()
252        return r
253
254def descendant_filter_collector(o, filter):
255    """
256    with filter
257    """
258    r = []
259    c = o.objectValues()
260    r.extend(filter(None, map(filter, c)))
261   
262    for oc in c:
263        if hasattr(oc.aq_base, 'isAnObjectManager'):
264            r.extend(descendant_filter_collector(oc, filter))   
265        if getattr(oc, '_p_changed', None)==None:
266            oc._p_deactivate()
267   
268    return r
Note: See TracBrowser for help on using the repository browser.