root/trunk/LeMillFactoryTool.py

Revision 3077, 6.2 kB (checked in by jukka, 1 year ago)

Removed debugging prints from code.

  • Property svn:executable set to *
Line 
1 import os
2 import Globals
3 from AccessControl import Owned, ClassSecurityInfo, getSecurityManager
4 from AccessControl.Permission import Permission
5 from Acquisition import aq_parent, aq_base, aq_inner, aq_get
6 from OFS.SimpleItem import SimpleItem
7 from ZPublisher.Publish import call_object, missing_name, dont_publish_class
8 from ZPublisher.mapply import mapply
9 from Products.CMFCore.utils import UniqueObject, getToolByName
10 from Products.CMFPlone.FactoryTool import FactoryTool as PloneFactoryTool
11 from Products.CMFPlone.FactoryTool import TempFolder as PloneTempFolder
12 from LargeSectionFolder import LeMillFolder
13 import time
14
15 ListType=type([])
16
17 FACTORY_INFO = '__factory__info__'
18
19
20 class TempFolder(LeMillFolder, PloneTempFolder):
21     portal_type = meta_type = 'TempFolder'
22     isPrincipiaFolderish = 0
23
24
25 # ##############################################################################
26 class FactoryTool(PloneFactoryTool):
27     """ Modified one method, much faster with Large Folders now """
28     id = 'portal_factory'
29     meta_type= 'LeMill FactoryTool'
30     toolicon = 'skins/lemill/tool.gif'
31     security = ClassSecurityInfo()
32     isPrincipiaFolderish = 0
33
34
35     security.declarePublic('__call__')
36     def __call__(self, *args, **kwargs):
37         """call method"""
38         self._fixRequest()
39         factory_info = self.REQUEST.get(FACTORY_INFO, {})
40         stack = factory_info['stack']
41         type_name = stack[0]
42         id = stack[1]
43
44         # do a passthrough if parent contains the id
45         if hasattr(aq_parent(self), id):
46             return aq_parent(self).restrictedTraverse('/'.join(stack[1:]))(*args, **kwargs)
47
48         tempFolder = self._getTempFolder(type_name)
49         # Mysterious hack that fixes some problematic interactions with SpeedPack:
50         #   Get the first item in the stack by explicitly calling __getitem__
51         temp_obj = tempFolder.__getitem__(id)
52         stack = stack[2:]
53         if stack:
54             obj = temp_obj.restrictedTraverse('/'.join(stack))
55         else:
56             obj = temp_obj
57         return mapply(obj, self.REQUEST.args, self.REQUEST,
58                                call_object, 1, missing_name, dont_publish_class,
59                                self.REQUEST, bind=1)
60
61
62     def removeFactoryFromPath(self, path):
63         """ Removers /portal_factory/type_name from path so that the path
64          can be compared to the path where object should be.
65          Returns tuple, where first element tells if the path was pointing into a factory """
66         if type(path)==tuple:
67             path=list(path)
68         if len(path)>2 and path[-2]=='portal_factory':
69             return (True, path[:-2])
70         return (False, path)
71
72     def addFactoryToPathString(self, path_string, type_name):
73         """ Returns a path string where portal_factory is in place """
74         if (not 'portal_factory' in path_string) or (not type_name in path_string):
75             return '%s/portal_factory/%s' % (path_string, type_name)
76         else:
77             return path_string
78
79     def __bobo_traverse__(self, REQUEST, name):
80         # __bobo_traverse__ can be invoked directly by a restricted_traverse method call
81         # in which case the traversal stack will not have been cleared by __before_publishing_traverse__
82         name = str(name) # fix unicode weirdness
83         types_tool = getToolByName(self, 'portal_types')
84         if not name in types_tool.listContentTypes():
85             return getattr(self, name) # not a type name -- do the standard thing
86         return self._getTempFolder(str(name)) # a type name -- return a temp folder
87
88
89     def _getTempFolder(self, type_name):
90         factory_info = self.REQUEST.get(FACTORY_INFO, {})
91         tempFolder = factory_info.get(type_name, None)
92         if tempFolder:
93             tempFolder = aq_inner(tempFolder).__of__(self)
94             return tempFolder
95        
96         # make sure we can add an object of this type to the temp folder
97         types_tool = getToolByName(self, 'portal_types')
98         if not type_name in types_tool.TempFolder.allowed_content_types:
99             # update allowed types for tempfolder
100             types_tool.TempFolder.allowed_content_types=(types_tool.listContentTypes())
101
102         tempFolder = TempFolder(type_name).__of__(self)
103         intended_parent = aq_parent(self)
104         portal = getToolByName(self, 'portal_url').getPortalObject()
105         folder_roles = {} # mapping from permission name to list or tuple of roles
106                           # list if perm is acquired; tuple if not
107         n_acquired = 0    # number of permissions that are acquired
108
109         # build initial folder_roles dictionary
110         for p in intended_parent.ac_inherited_permissions(1):
111             name, value = p[:2]
112             p=Permission(name,value,intended_parent)
113             roles = p.getRoles()
114             folder_roles[name] = roles
115             if type(roles) is ListType:
116                 n_acquired += 1
117
118         # If intended_parent is not the portal, walk up the acquisition hierarchy and
119         # acquire permissions explicitly so we can assign the acquired version to the
120         # temp_folder.  In addition to being cumbersome, this is undoubtedly very slow.
121         if intended_parent != portal:
122             parent = aq_parent(aq_inner(intended_parent))
123             while(n_acquired and parent!=portal):
124                 n_acquired = 0
125                 for p in parent.ac_inherited_permissions(1):
126                     name, value = p[:2]
127                     roles = folder_roles[name]
128                     if type(roles) is ListType:
129                         p=Permission(name,value,parent)
130                         aq_roles=p.getRoles()
131                         for r in aq_roles:
132                             if not r in roles:
133                                 roles.append(r)
134                         if type(aq_roles) is ListType:
135                             n_acquired += 1
136                         else:
137                             roles = tuple(roles)
138                         folder_roles[name] = roles
139                 parent = aq_parent(aq_inner(parent))
140         for name, roles in folder_roles.items():
141             tempFolder.manage_permission(name, roles, acquire=type(roles) is ListType)
142
143         factory_info[type_name] = tempFolder
144         self.REQUEST.set(FACTORY_INFO, factory_info)
145         return tempFolder
146
147
148 Globals.InitializeClass(FactoryTool)
Note: See TracBrowser for help on using the browser.