def getMessageFolderList(self): """ Returns the list of folders of the current server XXX Add read only transaction cache """ enabled = (getReadOnlyTransactionCache(self) is not None) if not enabled: enableReadOnlyTransactionCache(self) cache = getReadOnlyTransactionCache(self) if cache is not None: key = ('getMessageFolderList', self) try: return cache[key] except KeyError: pass else: raise "No Conversion Cache" # XXX - Implement this better server = self._getMailServer() if server is None: return () result = server.getMessageFolderList() if cache is not None: cache[key] = result return result
def getPermanentURL(self, document, view=True): """ Return a permanent URL of document in the context of the current section. This method must be implemented through a portal type dependent script: WebSection_getPermanentURL XXX The following argument is obsoleted because we no longer need /view. If view is True, the url returned point to html content and can be opened in a browser (ie. + '/view' for ooo documents) """ cache = getReadOnlyTransactionCache() if cache is not None: key = ('getPermanentURL', self, document.getPath()) try: return cache[key] except KeyError: pass document = document.getObject().__of__(self) result = document._getTypeBasedMethod( 'getPermanentURL', fallback_script_id='WebSection_getPermanentURL')(document) if cache is not None: cache[key] = result return result
def getDocumentValueList(self, **kw): """ Return the list of documents which belong to the current section. The API is designed to support additional parameters so that it is possible to group documents by reference, version, language, etc. or to implement filtering of documents. This method must be implemented through a portal type dependent script: WebSection_getDocumentValueList """ cache = getReadOnlyTransactionCache() if cache is not None: key = ('getDocumentValueList', self) + tuple(kw.items()) try: return cache[key] except KeyError: pass result = self._getTypeBasedMethod( 'getDocumentValueList', fallback_script_id='WebSection_getDocumentValueList')(**kw) if cache is not None: cache[key] = result if result is not None and not kw.get('src__', 0): result = [doc.__of__(self) for doc in result] return result
def getDefaultDocumentValue(self): """ Return the default document of the current section. This method must be implemented through a portal type dependent script: WebSection_getDefaultDocumentValue """ cache = getReadOnlyTransactionCache() if cache is not None: key = ('getDefaultDocumentValue', self) try: return cache[key] except KeyError: pass result = self._getTypeBasedMethod( 'getDefaultDocumentValue', fallback_script_id='WebSection_getDefaultDocumentValue')() if cache is not None: cache[key] = result if result is not None: result = result.__of__(self) return result
def getDefaultDocumentValue(self): """ Return the default document of the current section. This method must be implemented through a portal type dependent script: WebSection_getDefaultDocumentValue """ cache = getReadOnlyTransactionCache() if cache is not None: key = ('getDefaultDocumentValue', self) try: return cache[key] except KeyError: pass result = self._getTypeBasedMethod('getDefaultDocumentValue', fallback_script_id='WebSection_getDefaultDocumentValue')() if cache is not None: cache[key] = result if result is not None: result = result.__of__(self) return result
def getDocumentValueList(self, **kw): """ Return the list of documents which belong to the current section. The API is designed to support additional parameters so that it is possible to group documents by reference, version, language, etc. or to implement filtering of documents. This method must be implemented through a portal type dependent script: WebSection_getDocumentValueList """ cache = getReadOnlyTransactionCache() if cache is not None: key = ('getDocumentValueList', self) + tuple(kw.items()) try: return cache[key] except KeyError: pass result = self._getTypeBasedMethod('getDocumentValueList', fallback_script_id='WebSection_getDocumentValueList')(**kw) if cache is not None: cache[key] = result if result is not None and not kw.get('src__', 0): result = [doc.__of__(self) for doc in result] return result
def getPermanentURL(self, document, view=True): """ Return a permanent URL of document in the context of the current section. This method must be implemented through a portal type dependent script: WebSection_getPermanentURL XXX The following argument is obsoleted because we no longer need /view. If view is True, the url returned point to html content and can be opened in a browser (ie. + '/view' for ooo documents) """ cache = getReadOnlyTransactionCache() if cache is not None: key = ('getPermanentURL', self, document.getPath()) try: return cache[key] except KeyError: pass document = document.getObject().__of__(self) result = document._getTypeBasedMethod('getPermanentURL', fallback_script_id='WebSection_getPermanentURL')(document) if cache is not None: cache[key] = result return result
def getBreadcrumbItemList(self, document=None): """ Return a section dependent breadcrumb in the form of a list of (title, document) tuples. This method must be implemented through a portal type dependent script: WebSection_getBreadcrumbItemList """ if document is None: document = self cache = getReadOnlyTransactionCache() if cache is not None: key = ('getBreadcrumbItemList', self, document.getPath()) try: return cache[key] except KeyError: pass result = self._getTypeBasedMethod('getBreadcrumbItemList', fallback_script_id='WebSection_getBreadcrumbItemList')(document) if cache is not None: cache[key] = result return result
def getBreadcrumbItemList(self, document=None): """ Return a section dependent breadcrumb in the form of a list of (title, document) tuples. This method must be implemented through a portal type dependent script: WebSection_getBreadcrumbItemList """ if document is None: document = self cache = getReadOnlyTransactionCache() if cache is not None: key = ('getBreadcrumbItemList', self, document.getPath()) try: return cache[key] except KeyError: pass result = self._getTypeBasedMethod( 'getBreadcrumbItemList', fallback_script_id='WebSection_getBreadcrumbItemList')(document) if cache is not None: cache[key] = result return result
def _getMailServer(self): """ A private method to retrieve a mail server based on the URL definition. XXX - Danger: if the server Url is changed, we break things. An interactor is required to clear the variable """ enabled = (getReadOnlyTransactionCache(self) is not None) if not enabled: enableReadOnlyTransactionCache(self) cache = getReadOnlyTransactionCache(self) if cache is not None: key = ('_getMailServer', self) try: return cache[key] except KeyError: pass else: raise "No Conversion Cache" # XXX - Implement this better # No server defined if not self.getURLServer(): return None # XXX - Here we need to add a switch (POP vs. IMAP vs. IMAPS etc.) url_protocol = self.getUrlProtocol('imaps') # Default to IMAP if url_protocol == 'imaps': result = IMAPSServer(self.getURLServer(), self.getUserId(), self.getPassword(), port=self.getURLPort()) elif url_protocol == 'imap': result = IMAPServer(self.getURLServer(), self.getUserId(), self.getPassword(), port=self.getURLPort()) elif url_protocol == 'pops': result = POPSServer(self.getURLServer(), self.getUserId(), self.getPassword(), port=self.getURLPort()) elif url_protocol == 'pop': result = POPServer(self.getURLServer(), self.getUserId(), self.getPassword(), port=self.getURLPort()) else: raise NotImplementedError if cache is not None: cache[key] = result return result
def getSiteMapTree(self, **kw): """ Return a site map tree section dependent breadcrumb in the form of a list of dicts whose structure is provided as a tree so that it is easy to implement recursive call with TAL/METAL: [ { 'url' : '/erp5/web_site_module/site/section', 'level' : 1, 'translated_title' : 'Section Title', 'subsection' : [ { 'url' : '/erp5/web_site_module/site/section/reference', 'level' : 2, 'translated_title' : 'Sub Section Title', 'subsection' : None, }, ... ], } ... ] This method must be implemented through a portal type dependent script: WebSection_getSiteMapTree """ cache = getReadOnlyTransactionCache() if cache is not None: key = ('getSiteMapTree', self) + tuple(kw.items()) try: return cache[key] except KeyError: pass result = self._getTypeBasedMethod( 'getSiteMapTree', fallback_script_id='WebSection_getSiteMapTree')(**kw) if cache is not None: cache[key] = result return result
def getSiteMapTree(self, **kw): """ Return a site map tree section dependent breadcrumb in the form of a list of dicts whose structure is provided as a tree so that it is easy to implement recursive call with TAL/METAL: [ { 'url' : '/erp5/web_site_module/site/section', 'level' : 1, 'translated_title' : 'Section Title', 'subsection' : [ { 'url' : '/erp5/web_site_module/site/section/reference', 'level' : 2, 'translated_title' : 'Sub Section Title', 'subsection' : None, }, ... ], } ... ] This method must be implemented through a portal type dependent script: WebSection_getSiteMapTree """ cache = getReadOnlyTransactionCache() if cache is not None: key = ('getSiteMapTree', self) + tuple(kw.items()) try: return cache[key] except KeyError: pass result = self._getTypeBasedMethod('getSiteMapTree', fallback_script_id='WebSection_getSiteMapTree')(**kw) if cache is not None: cache[key] = result return result
def getMessageFolderList(self): """ Returns the list of folders of the current server XXX Add read only transaction cache """ cache = getReadOnlyTransactionCache() if cache is not None: key = ('getMessageFolderList', self) try: return cache[key] except KeyError: pass server = self._getMailServer() if server is None: return () result = server.getMessageFolderList() if cache is not None: cache[key] = result return result
def _getMailServer(self): """ A private method to retrieve a mail server based on the URL definition. XXX - Danger: if the server Url is changed, we break things. An interactor is required to clear the variable """ cache = getReadOnlyTransactionCache() if cache is not None: key = ('_getMailServer', self) try: return cache[key] except KeyError: pass # No server defined if not self.getURLServer(): return None # XXX - Here we need to add a switch (POP vs. IMAP vs. IMAPS etc.) url_protocol = self.getUrlProtocol('imaps') # Default to IMAP if url_protocol == 'imaps': result = IMAPSServer(self.getURLServer(), self.getUserId(), self.getPassword(), port=self.getURLPort()) elif url_protocol == 'imap': result = IMAPServer(self.getURLServer(), self.getUserId(), self.getPassword(), port=self.getURLPort()) elif url_protocol == 'pops': result = POPSServer(self.getURLServer(), self.getUserId(), self.getPassword(), port=self.getURLPort()) elif url_protocol == 'pop': result = POPServer(self.getURLServer(), self.getUserId(), self.getPassword(), port=self.getURLPort()) else: raise NotImplementedError if cache is not None: cache[key] = result return result
def test(self, context, tested_base_category_list=None, **kw): """ A Predicate can be tested on a given context. Parameters can passed in order to ignore some conditions. - tested_base_category_list: this is the list of category that we do want to test. For example, we might want to test only the destination or the source of a predicate. This method returns portal type name if test success, else returns False. """ self = self.asPredicate() result = 1 if getattr(aq_base(self), '_identity_criterion', None) is None: self._identity_criterion = {} self._range_criterion = {} for property, value in self._identity_criterion.iteritems(): result = result and (context.getProperty(property) in value) for property, (min, max) in self._range_criterion.iteritems(): value = context.getProperty(property) if min is not None: result = result and (value >= min) if max is not None: result = result and (value < max) multimembership_criterion_base_category_list = \ self.getMultimembershipCriterionBaseCategoryList() membership_criterion_base_category_list = \ self.getMembershipCriterionBaseCategoryList() tested_base_category = {} membership_criterion_category_list = \ self.getMembershipCriterionCategoryList() if tested_base_category_list is not None: membership_criterion_category_list = [x for x in \ membership_criterion_category_list if x.split('/', 1)[0] in \ tested_base_category_list] # Test category memberships. Enable the read-only transaction cache # temporarily, if not enabled, because this part is strictly read-only, # and context.isMemberOf is very expensive, when the category list has # many items. enabled = getReadOnlyTransactionCache() is not None try: if not enabled: enableReadOnlyTransactionCache() for c in membership_criterion_category_list: bc = c.split('/', 1)[0] if (bc not in tested_base_category) and \ (bc in multimembership_criterion_base_category_list): tested_base_category[bc] = 1 elif (bc not in tested_base_category) and \ (bc in membership_criterion_base_category_list): tested_base_category[bc] = 0 if (bc in multimembership_criterion_base_category_list): tested_base_category[bc] = tested_base_category[bc] and \ context.isMemberOf(c) elif (bc in membership_criterion_base_category_list): tested_base_category[bc] = tested_base_category[bc] or \ context.isMemberOf(c) finally: if not enabled: disableReadOnlyTransactionCache() result = result and (0 not in tested_base_category.values()) # Test method calls test_method_id_list = self.getTestMethodIdList() if test_method_id_list: for test_method_id in test_method_id_list: if (test_method_id is not None) and result: method = getattr(context, test_method_id) result = result and method(self) else: result = result and self.getDestinationPortalType() return result
def _forceIdentification(self, request): # force identification (usable for extensible content) cache = getReadOnlyTransactionCache() if cache is not None: key = ('__bobo_traverse__', self, 'user') try: user = cache[key] except KeyError: user = _MARKER else: user = _MARKER old_user = getSecurityManager().getUser() if user is _MARKER: user = None # By default, do nothing if old_user is None or old_user.getUserName() == 'Anonymous User': portal_membership = getToolByName(self.getPortalObject(), 'portal_membership') if portal_membership is not None: try: if request.get('PUBLISHED', _MARKER) is _MARKER: # request['PUBLISHED'] is required by validate request['PUBLISHED'] = self has_published = False else: has_published = True try: name = None acl_users = self.getPortalObject().acl_users user_list = acl_users._extractUserIds( request, acl_users.plugins) if len(user_list) > 0: name = user_list[0][0] else: auth = request._auth # this logic is copied from identify() in # AccessControl.User.BasicUserFolder. if auth and auth.lower().startswith('basic '): name = decodestring( auth.split(' ')[-1]).split(':', 1)[0] if name is not None: user = portal_membership._huntUser(name, self) else: user = None except AttributeError: # This kind of error happens with unrestrictedTraverse, # because the request object is a fake, and it is just # a dict object. user = None if not has_published: try: del request.other['PUBLISHED'] except AttributeError: # The same here as above. unrestrictedTraverse provides # just a plain dict, so request.other does not exist. del request['PUBLISHED'] except: LOG("ERP5 WARNING", 0, "Failed to retrieve user in __bobo_traverse__ of WebSection %s" % self.getPath(), error=True) user = None if user is not None and user.getUserName() == 'Anonymous User': user = None # If the user which is connected is anonymous, # do not try to change SecurityManager if cache is not None: cache[key] = user old_manager = None if user is not None: # We need to perform identification old_manager = getSecurityManager() newSecurityManager(get_request(), user) return old_manager, user
def test(self, context, tested_base_category_list=None, strict_membership=0, **kw): """ A Predicate can be tested on a given context. Parameters can passed in order to ignore some conditions. - tested_base_category_list: this is the list of category that we do want to test. For example, we might want to test only the destination or the source of a predicate. - if strict_membership is specified, we should make sure that we are strictly a member of tested categories """ self = self.asPredicate() result = 1 if getattr(aq_base(self), '_identity_criterion', None) is None: self._identity_criterion = PersistentMapping() self._range_criterion = PersistentMapping() # LOG('PREDICATE TEST', 0, # 'testing %s on context of %s' % \ # (self.getRelativeUrl(), context.getRelativeUrl())) for property, value in self._identity_criterion.iteritems(): if isinstance(value, (list, tuple)): result = context.getProperty(property) in value else: result = context.getProperty(property) == value # LOG('predicate test', 0, # '%s after prop %s : %s == %s' % \ # (result, property, context.getProperty(property), value)) if not result: return result for property, (min, max) in self._range_criterion.iteritems(): value = context.getProperty(property) if min is not None: result = value >= min # LOG('predicate test', 0, # '%s after prop %s : %s >= %s' % \ # (result, property, value, min)) if not result: return result if max is not None: result = value < max # LOG('predicate test', 0, # '%s after prop %s : %s < %s' % \ # (result, property, value, max)) if not result: return result multimembership_criterion_base_category_list = \ self.getMultimembershipCriterionBaseCategoryList() membership_criterion_base_category_list = \ self.getMembershipCriterionBaseCategoryList() tested_base_category = {} # LOG('predicate test', 0, # 'categories will be tested in multi %s single %s as %s' % \ # (multimembership_criterion_base_category_list, # membership_criterion_base_category_list, # self.getMembershipCriterionCategoryList())) membership_criterion_category_list = \ self.getMembershipCriterionCategoryList() if tested_base_category_list is not None: membership_criterion_category_list = [x for x in \ membership_criterion_category_list if x.split('/', 1)[0] in \ tested_base_category_list] # Test category memberships. Enable the read-only transaction cache # temporarily, if not enabled, because this part is strictly read-only, # and context.isMemberOf is very expensive, when the category list has # many items. enabled = getReadOnlyTransactionCache() is not None try: if not enabled: enableReadOnlyTransactionCache() for c in membership_criterion_category_list: bc = c.split('/', 1)[0] if (bc not in tested_base_category) and \ (bc in multimembership_criterion_base_category_list): tested_base_category[bc] = 1 elif (bc not in tested_base_category) and \ (bc in membership_criterion_base_category_list): tested_base_category[bc] = 0 if (bc in multimembership_criterion_base_category_list): tested_base_category[bc] = tested_base_category[bc] and \ context.isMemberOf(c, strict_membership=strict_membership) # LOG('predicate test', 0, # '%s after multi membership to %s' % \ # (tested_base_category[bc], c)) elif (bc in membership_criterion_base_category_list): tested_base_category[bc] = tested_base_category[bc] or \ context.isMemberOf(c, strict_membership=strict_membership) finally: if not enabled: disableReadOnlyTransactionCache() # LOG('predicate test', 0, # '%s after single membership to %s' % \ # (tested_base_category[bc], c)) result = 0 not in tested_base_category.values() # LOG('predicate test', 0, # '%s after category %s ' % (result, tested_base_category.items())) if not result: return result # Test method calls test_method_id_list = self.getTestMethodIdList() if test_method_id_list is not None : for test_method_id in test_method_id_list : if test_method_id is not None: method = getattr(context,test_method_id) try: result = method(self) except TypeError: if method.func_code.co_argcount != isinstance(method, MethodType): raise # backward compatibilty with script that takes no argument warn('Predicate %s uses an old-style method (%s) that does not' ' take the predicate as argument' % ( self.getRelativeUrl(), method.__name__), DeprecationWarning) result = method() # LOG('predicate test', 0, # '%s after method %s ' % (result, test_method_id)) if not result: return result test_tales_expression = self.getTestTalesExpression() if test_tales_expression != 'python: True': expression = Expression(test_tales_expression) from Products.ERP5Type.Utils import createExpressionContext # evaluate a tales expression with the tested value as context result = expression(createExpressionContext(context)) return result
def _forceIdentification(self, request): # force identification (usable for extensible content) cache = getReadOnlyTransactionCache() if cache is not None: key = ('__bobo_traverse__', self, 'user') try: user = cache[key] except KeyError: user = _MARKER else: user = _MARKER old_user = getSecurityManager().getUser() if user is _MARKER: user = None # By default, do nothing if old_user is None or old_user.getUserName() == 'Anonymous User': portal_membership = getToolByName(self.getPortalObject(), 'portal_membership') if portal_membership is not None: try: if request.get('PUBLISHED', _MARKER) is _MARKER: # request['PUBLISHED'] is required by validate request['PUBLISHED'] = self has_published = False else: has_published = True try: name = None acl_users = self.getPortalObject().acl_users user_list = acl_users._extractUserIds(request, acl_users.plugins) if len(user_list) > 0: name = user_list[0][0] else: auth = request._auth # this logic is copied from identify() in # AccessControl.User.BasicUserFolder. if auth and auth.lower().startswith('basic '): name = decodestring(auth.split(' ')[-1]).split(':', 1)[0] if name is not None: user = portal_membership._huntUser(name, self) else: user = None except AttributeError: # This kind of error happens with unrestrictedTraverse, # because the request object is a fake, and it is just # a dict object. user = None if not has_published: try: del request.other['PUBLISHED'] except AttributeError: # The same here as above. unrestrictedTraverse provides # just a plain dict, so request.other does not exist. del request['PUBLISHED'] except: LOG("ERP5 WARNING",0, "Failed to retrieve user in __bobo_traverse__ of WebSection %s" % self.getPath(), error=sys.exc_info()) user = None if user is not None and user.getUserName() == 'Anonymous User': user = None # If the user which is connected is anonymous, # do not try to change SecurityManager if cache is not None: cache[key] = user old_manager = None if user is not None: # We need to perform identification old_manager = getSecurityManager() newSecurityManager(get_request(), user) return old_manager, user