def allowDiscussion(self, allowDiscussion=None, **kw): default = self.defaultIsDiscussable() current = self.rawIsDiscussable() # If we already overwrote the default or the value we try to set is # not the default we change it. Otherwise we keep what's there. if current is not None or (current is None and default != allowDiscussion): dtool = getToolByName(self, "portal_discussion", None) try: if dtool is not None: try: dtool.overrideDiscussionFor(self, allowDiscussion) except AttributeError: # CMF 2.1.0's CMFDefault.DiscussionTool # has tried to delete the class attribute. # TODO: remove this when we move to a later # CMF. pass except Unauthorized: # Catch Unauthorized exception that could be raised by the # discussion tool when the authenticated users hasn't # ModifyPortalContent permissions. # Explanation: # A user might have CreatePortalContent but not ModifyPortalContent # so allowDiscussion could raise a Unauthorized error although it's # called from trusted code. That is VERY bad inside setDefault()! log( "Catched Unauthorized on discussiontool." "overrideDiscussionFor(%s)" % self.absolute_url(1), level=DEBUG, )
def allowDiscussion(self, allowDiscussion=None, **kw): default = self.defaultIsDiscussable() current = self.rawIsDiscussable() # If we already overwrote the default or the value we try to set is # not the default we change it. Otherwise we keep what's there. if (current is not None or (current is None and default != allowDiscussion)): dtool = getToolByName(self, 'portal_discussion', None) try: if dtool is not None: try: dtool.overrideDiscussionFor(self, allowDiscussion) except AttributeError: # CMF 2.1.0's CMFDefault.DiscussionTool # has tried to delete the class attribute. # TODO: remove this when we move to a later # CMF. pass except Unauthorized: # Catch Unauthorized exception that could be raised by the # discussion tool when the authenticated users hasn't # ModifyPortalContent permissions. # Explanation: # A user might have CreatePortalContent but not ModifyPortalContent # so allowDiscussion could raise a Unauthorized error although it's # called from trusted code. That is VERY bad inside setDefault()! log('Catched Unauthorized on discussiontool.' \ 'overrideDiscussionFor(%s)' % self.absolute_url(1), level=DEBUG)
def reindexObjectSecurity(self, skip_self=False): # Update security information in all registered catalogs. if isFactoryContained(self): return at = getToolByName(self, TOOL_NAME, None) if at is None: return catalogs = [c for c in at.getCatalogsByType(self.meta_type) if ICatalogTool.providedBy(c)] path = self.__url() for catalog in catalogs: for brain in catalog.unrestrictedSearchResults(path=path): brain_path = brain.getPath() if brain_path == path and skip_self: continue # Get the object if hasattr(aq_base(brain), '_unrestrictedGetObject'): try: ob = brain._unrestrictedGetObject() except (KeyError, AttributeError): ob = None if ob is None: log("reindexObjectSecurity: Cannot get %s from catalog" % brain_path, level=WARNING) continue # Recatalog with the same catalog uid. catalog.reindexObject(ob, idxs=self._cmf_security_indexes, update_metadata=0, uid=brain_path)
def registerType(klass, package): # Registering a class results in classgen doing its thing # Set up accessor/mutators and sane meta/portal_type generateClass(klass) data = { 'klass': klass, 'name': klass.__name__, 'identifier': klass.meta_type.capitalize().replace(' ', '_'), 'meta_type': klass.meta_type, 'portal_type': klass.portal_type, 'package': package, 'module': sys.modules[klass.__module__], 'schema': klass.schema, 'signature': klass.schema.signature(), } key = '%s.%s' % (package, data['meta_type']) if key in _types.keys(): existing = _types[key] existing_name = '%s.%s' % (existing['module'].__name__, existing['name']) override_name = '%s.%s' % (data['module'].__name__, data['name']) log('ArchetypesTool: Trying to register "%s" which ' 'has already been registered. The new type %s ' 'is going to override %s' % (key, override_name, existing_name)) _types[key] = data
def reindexObjectSecurity(self, skip_self=False): """update security information in all registered catalogs. """ if isFactoryContained(self): return at = getToolByName(self, TOOL_NAME, None) if at is None: return catalogs = [c for c in at.getCatalogsByType(self.meta_type) if ICatalogTool.providedBy(c)] path = self.__url() for catalog in catalogs: for brain in catalog.unrestrictedSearchResults(path=path): brain_path = brain.getPath() if brain_path == path and skip_self: continue # Get the object if hasattr(aq_base(brain), '_unrestrictedGetObject'): try: ob = brain._unrestrictedGetObject() except (KeyError, AttributeError): ob = None if ob is None: log("reindexObjectSecurity: Cannot get %s from catalog" % brain_path, level=WARNING) continue # Recatalog with the same catalog uid. catalog.reindexObject(ob, idxs=self._cmf_security_indexes, update_metadata=0, uid=brain_path)
def egov_reindexObjectSecurity(self, skip_self=False): if isFactoryContained(self): return at = getToolByName(self, TOOL_NAME, None) if at is None: return catalogs = [c for c in at.getCatalogsByType(self.meta_type) if ICatalogTool.providedBy(c)] path = "/".join(self.getPhysicalPath()) for catalog in catalogs: for brain in catalog.unrestrictedSearchResults(path=path): brain_path = brain.getPath() if brain_path == path and skip_self: continue # Get the object if hasattr(aq_base(brain), "_unrestrictedGetObject"): ob = brain._unrestrictedGetObject() else: # BBB: Zope 2.7 ob = self.unrestrictedTraverse(brain_path, None) if ob is None: # BBB: Ignore old references to deleted objects. # Can happen only in Zope 2.7, or when using # catalog-getObject-raises off in Zope 2.8 log("reindexObjectSecurity: Cannot get %s from catalog" % brain_path, level=WARNING) continue # Also append our new index indexes = list(self._cmf_security_indexes) indexes.append("get_local_roles") indexes.append("isLocalRoleAcquired") # Recatalog with the same catalog uid. catalog.reindexObject(ob, idxs=tuple(indexes), update_metadata=1, uid=brain_path)
def manage_inspect(self, UID, REQUEST=None): """Dump some things about an object hook in the debugger for now. """ object = self.getObject(UID) log("uid: %s, schema: %s" % (object, object.Schema())) return REQUEST.RESPONSE.redirect(self.absolute_url() + '/manage_uids')
def registerType(klass, package): # Registering a class results in classgen doing its thing # Set up accessor/mutators and sane meta/portal_type generateClass(klass) data = { 'klass': klass, 'name': klass.__name__, 'identifier': klass.meta_type.capitalize().replace(' ', '_'), 'meta_type': klass.meta_type, 'portal_type': klass.portal_type, 'package': package, 'module': sys.modules[klass.__module__], 'schema': klass.schema, 'signature': klass.schema.signature(), } key = '%s.%s' % (package, data['meta_type']) if key in _types.keys(): existing = _types[key] existing_name = '%s.%s' % ( existing['module'].__name__, existing['name']) override_name = '%s.%s' % (data['module'].__name__, data['name']) log('ArchetypesTool: Trying to register "%s" which ' 'has already been registered. The new type %s ' 'is going to override %s' % (key, override_name, existing_name)) _types[key] = data
def initializeInstance(self, instance, item=None, container=None): if (self.is_initialized(instance) or getattr(instance, '_at_is_fake_instance', None)): # duh, we don't need to be initialized twice return factory = getToolByName(instance, 'portal_factory') if factory.isTemporary(instance): return fields = instance.Schema().fields() fields = [ f for f in fields if IObjectField.providedBy(f) and f.getStorage().__class__ is self.__class__ ] columns = [] args = {} for field in fields: type = self.db_type_map.get(field.type, field.type) name = field.getName() # MySQL supports escape for columns names! if self.__class__.__name__ == 'MySQLSQLStorage': columns.append('`%s` %s' % (name, type)) else: columns.append('%s %s' % (name, type)) parent = container or aq_parent(aq_inner(instance)) args['PARENTUID'] = getattr(aq_base(parent), 'UID', lambda: None)() args['table'] = instance.portal_type args['UID'] = instance.UID() # args['db_encoding']=kwargs.get('db_encoding',None) args['columns'] = ', ' + ', '.join(columns) if not self.table_exists(instance): self._query(instance, self.query_create, args) log('created table %s\n' % args['table']) try: self._query(instance, self.query_insert, args) except ConflictError: raise except: # usually, duplicate key # raise SQLInitException(msg) raise try: instance.__initialized += (self.getName(), ) except AttributeError: instance.__initialized = (self.getName(), ) # now, if we find an attribute called _v_$classname_temps, it # means the object was moved and we can initialize the fields # with those values temps_var = '_v_%s_temps' % self.getName() if hasattr(aq_base(instance), temps_var): temps = getattr(instance, temps_var) for key, value in temps.items(): instance.Schema()[key].set(instance, value) delattr(instance, temps_var) try: del instance.__cleaned except (AttributeError, KeyError): pass
def enum(self, callback, *args, **kwargs): catalog = getToolByName(self, UID_CATALOG) keys = catalog.uniqueValuesFor('UID') for uid in keys: o = self.getObject(uid) if o: callback(o, *args, **kwargs) else: log('No object for %s' % uid)
def initializeInstance(self, instance, item=None, container=None): if (self.is_initialized(instance) or getattr(instance, '_at_is_fake_instance', None)): # duh, we don't need to be initialized twice return factory = getToolByName(instance, 'portal_factory') if factory.isTemporary(instance): return fields = instance.Schema().fields() fields = [f for f in fields if IObjectField.providedBy(f) and f.getStorage().__class__ is self.__class__] columns = [] args = {} for field in fields: type = self.db_type_map.get(field.type, field.type) name = field.getName() # MySQL supports escape for columns names! if self.__class__.__name__ == 'MySQLSQLStorage': columns.append('`%s` %s' % (name, type)) else: columns.append('%s %s' % (name, type)) parent = container or aq_parent(aq_inner(instance)) args['PARENTUID'] = getattr(aq_base(parent), 'UID', lambda: None)() args['table'] = instance.portal_type args['UID'] = instance.UID() # args['db_encoding']=kwargs.get('db_encoding',None) args['columns'] = ', ' + ', '.join(columns) if not self.table_exists(instance): self._query(instance, self.query_create, args) log('created table %s\n' % args['table']) try: self._query(instance, self.query_insert, args) except ConflictError: raise except: # usually, duplicate key # raise SQLInitException(msg) raise try: instance.__initialized += (self.getName(),) except AttributeError: instance.__initialized = (self.getName(),) # now, if we find an attribute called _v_$classname_temps, it # means the object was moved and we can initialize the fields # with those values temps_var = '_v_%s_temps' % self.getName() if hasattr(aq_base(instance), temps_var): temps = getattr(instance, temps_var) for key, value in temps.items(): instance.Schema()[key].set(instance, value) delattr(instance, temps_var) try: del instance.__cleaned except (AttributeError, KeyError): pass
def wrap_method(klass, name, method, pattern='__at_wrapped_%s__'): old_method = getattr(klass, name) if isWrapperMethod(old_method): log('Already wrapped method %s.%s. Skipping.' % (klass.__name__, name)) return new_name = pattern % name setattr(klass, new_name, old_method) setattr(method, ORIG_NAME, new_name) setattr(method, WRAPPER, True) setattr(klass, name, method)
def _rawEnum(self, callback, *args, **kwargs): # Finds all object to check if they are 'referenceable'. catalog = getToolByName(self, 'portal_catalog') brains = catalog(dict(id=[])) for b in brains: o = b.getObject() if o is not None: if IBaseObject.providedBy(o): callback(o, *args, **kwargs) else: log('no object for brain: %s:%s' % (b, b.getURL()))
def isBinary(self): # Return true if this contains a binary value, else false. try: return self.binary except AttributeError: # XXX workaround for "[ 1040514 ] AttributeError on some types after # migration 1.2.4rc5->1.3.0" # Somehow and sometimes the binary attribute gets lost magically self.binary = not str(self.mimetype).startswith('text') log("BaseUnit: Failed to access attribute binary for mimetype %s. " "Setting binary to %s" % (self.mimetype, self.binary), level=ERROR) return self.binary
def getCatalogsByType(self, portal_type): # Return the catalog objects assoicated with a given type. catalogs = [] catalog_map = getattr(self, 'catalog_map', None) if catalog_map is not None: names = self.catalog_map.get(portal_type, ['portal_catalog']) else: names = ['portal_catalog'] portal = getToolByName(self, 'portal_url').getPortalObject() for name in names: try: catalogs.append(getToolByName(portal, name)) except (ConflictError, KeyboardInterrupt): raise except Exception, E: log('No tool %s' % name, E) pass
def marshall(self, instance, **kwargs): p = instance.getPrimaryField() if not p: raise TypeError, "Primary Field could not be found." data = p and instance[p.getName()] or "" content_type = length = None # Gather/Guess content type if IBaseUnit.providedBy(data): content_type = data.getContentType() length = data.get_size() data = data.getRaw() elif isinstance(data, File): content_type = data.content_type length = data.get_size() data = data.data else: log( "WARNING: PrimaryFieldMarshaller(%r): " "field %r does not return a IBaseUnit " "instance." % (instance, p.getName()) ) if hasattr(p, "getContentType"): content_type = p.getContentType(instance) or "text/plain" else: content_type = data and guess_content_type(data) or "text/plain" # DM 2004-12-01: "FileField"s represent a major field class # that does not use "IBaseUnit" yet. # Ensure, the used "File" objects get the correct length. if hasattr(p, "get_size"): length = p.get_size(instance) else: # DM: this almost surely is stupid! length = len(data) # ObjectField without IBaseUnit? if shasattr(data, "data"): data = data.data else: data = str(data) # DM 2004-12-01: recompute 'length' as we now know it # definitely length = len(data) return (content_type, length, data)
def marshall(self, instance, **kwargs): p = instance.getPrimaryField() if not p: raise TypeError, 'Primary Field could not be found.' data = p and instance[p.getName()] or '' content_type = length = None # Gather/Guess content type if IBaseUnit.providedBy(data): content_type = data.getContentType() length = data.get_size() data = data.getRaw() elif isinstance(data, File): content_type = data.content_type length = data.get_size() data = data.data else: log('WARNING: PrimaryFieldMarshaller(%r): ' 'field %r does not return a IBaseUnit ' 'instance.' % (instance, p.getName())) if hasattr(p, 'getContentType'): content_type = p.getContentType(instance) or 'text/plain' else: content_type = (data and guess_content_type(data) or 'text/plain') # DM 2004-12-01: "FileField"s represent a major field class # that does not use "IBaseUnit" yet. # Ensure, the used "File" objects get the correct length. if hasattr(p, 'get_size'): length = p.get_size(instance) else: # DM: this almost surely is stupid! length = len(data) # ObjectField without IBaseUnit? if shasattr(data, 'data'): data = data.data else: data = str(data) # DM 2004-12-01: recompute 'length' as we now know it # definitely length = len(data) return (content_type, length, data)
def egov_reindexObjectSecurity(self, skip_self=False): if isFactoryContained(self): return at = getToolByName(self, TOOL_NAME, None) if at is None: return catalogs = [ c for c in at.getCatalogsByType(self.meta_type) if ICatalogTool.providedBy(c) ] path = '/'.join(self.getPhysicalPath()) for catalog in catalogs: for brain in catalog.unrestrictedSearchResults(path=path): brain_path = brain.getPath() if brain_path == path and skip_self: continue # Get the object if hasattr(aq_base(brain), '_unrestrictedGetObject'): ob = brain._unrestrictedGetObject() else: # BBB: Zope 2.7 ob = self.unrestrictedTraverse(brain_path, None) if ob is None: # BBB: Ignore old references to deleted objects. # Can happen only in Zope 2.7, or when using # catalog-getObject-raises off in Zope 2.8 log("reindexObjectSecurity: Cannot get %s from catalog" % brain_path, level=WARNING) continue # Also append our new index indexes = list(self._cmf_security_indexes) indexes.append('get_local_roles') indexes.append('isLocalRoleAcquired') # Recatalog with the same catalog uid. catalog.reindexObject(ob, idxs=tuple(indexes), update_metadata=1, uid=brain_path)
def reindexObjectSecurity(self, skip_self=False): """update security information in all registered catalogs. """ if isFactoryContained(self): return at = getToolByName(self, TOOL_NAME, None) if at is None: return catalogs = [ c for c in at.getCatalogsByType(self.meta_type) if ICatalogTool.providedBy(c) ] path = self.__url() for catalog in catalogs: for brain in catalog.unrestrictedSearchResults(path=path): brain_path = brain.getPath() if brain_path == path and skip_self: continue # Get the object if hasattr(aq_base(brain), '_unrestrictedGetObject'): ob = brain._unrestrictedGetObject() else: # BBB: Zope 2.7 ob = self.unrestrictedTraverse(brain_path, None) if ob is None: # BBB: Ignore old references to deleted objects. # Can happen only in Zope 2.7, or when using # catalog-getObject-raises off in Zope 2.8 log("reindexObjectSecurity: Cannot get %s from catalog" % brain_path, level=WARNING) continue # Recatalog with the same catalog uid. catalog.reindexObject(ob, idxs=self._cmf_security_indexes, update_metadata=0, uid=brain_path)
def updateSecurity(self, klass, field, mode, methodName): security = _getSecurity(klass) perm = _modes[mode]['security'] perm = getattr(field, perm, None) method__roles__ = getattr(klass, '%s__roles__' % methodName, 0) # Check copied from SecurityInfo to avoid stomping over # existing permissions. if security.names.get(methodName, perm) != perm: log('The method \'%s\' was already protected by a ' 'different permission than the one declared ' 'on the field. Assuming that the explicit ' 'permission declared is the correct one and ' 'has preference over the permission declared ' 'on the field.' % methodName, level=logging.DEBUG) elif method__roles__ is None: security.declarePublic(methodName) elif method__roles__ == (): security.declarePrivate(methodName) else: security.declareProtected(perm, methodName)
def allowDiscussion(self, allowDiscussion=None, **kw): log_deprecated( "The allowDiscussion method from the ExtensibleMetadata in " "Products.ATContentTypes has been deprecated and will be removed " "in Plone 5. This method belongs to the old discussion " "infrastructure that already has been replaced by " "plone.app.discussion in Plone 4.1." ) if not 'portal_discussion' in self.objectIds(): return default = self.defaultIsDiscussable() current = self.rawIsDiscussable() # If we already overwrote the default or the value we try to set is # not the default we change it. Otherwise we keep what's there. if (current is not None or (current is None and default != allowDiscussion)): dtool = getToolByName(self, 'portal_discussion', None) try: if dtool is not None: try: dtool.overrideDiscussionFor(self, allowDiscussion) except AttributeError: # CMF 2.1.0's CMFDefault.DiscussionTool # has tried to delete the class attribute. # TODO: remove this when we move to a later # CMF. pass except Unauthorized: # Catch Unauthorized exception that could be raised by the # discussion tool when the authenticated users hasn't # ModifyPortalContent permissions. # Explanation: # A user might have CreatePortalContent but not ModifyPortalContent # so allowDiscussion could raise a Unauthorized error although it's # called from trusted code. That is VERY bad inside setDefault()! log('Catched Unauthorized on discussiontool.' \ 'overrideDiscussionFor(%s)' % self.absolute_url(1), level=DEBUG)
def reindexObjectSecurity(self, skip_self=False): """update security information in all registered catalogs. """ if isFactoryContained(self): return at = getToolByName(self, TOOL_NAME, None) if at is None: return catalogs = [c for c in at.getCatalogsByType(self.meta_type) if ICatalogTool.providedBy(c)] path = self.__url() for catalog in catalogs: for brain in catalog.unrestrictedSearchResults(path=path): brain_path = brain.getPath() if brain_path == path and skip_self: continue # Get the object if hasattr(aq_base(brain), '_unrestrictedGetObject'): ob = brain._unrestrictedGetObject() else: # BBB: Zope 2.7 ob = self.unrestrictedTraverse(brain_path, None) if ob is None: # BBB: Ignore old references to deleted objects. # Can happen only in Zope 2.7, or when using # catalog-getObject-raises off in Zope 2.8 log("reindexObjectSecurity: Cannot get %s from catalog" % brain_path, level=WARNING) continue # Recatalog with the same catalog uid. catalog.reindexObject(ob, idxs=self._cmf_security_indexes, update_metadata=0, uid=brain_path)
def addableTypes(self, instance, field): """ Returns a list of dictionaries which maps portal_type to a human readable form. """ tool = getToolByName(instance, 'portal_types') purl = getToolByName(instance, 'portal_url') lookupDestinationsFor = self.lookupDestinationsFor getRelativeContentURL = purl.getRelativeContentURL # if destination_types is None (by default) it will do # N-portal_types queries to the catalog which is horribly inefficient destination_types = getattr(self, 'destination_types', None) destination = self.destination types = [] options = {} for typeid in field.allowed_types: _info = tool.getTypeInfo(typeid) if _info is None: # The portal_type asked for was not # installed/has been removed. log("Warning: in Archetypes.Widget.lookupDestinationsFor: " \ "portal type %s not found" % typeid) continue if destination == None: options[typeid] = [None] elif isinstance(destination, DictType): options[typeid] = destination.get(typeid, [None]) if not isinstance(options[typeid], ListType): options[typeid] = [options[typeid]] elif isinstance(destination, ListType): options[typeid] = destination else: place = getattr(aq_base(instance), destination, destination) if callable(place): #restore acq.wrapper place = getattr(instance, destination) place = place() if isinstance(place, ListType): options[typeid] = place else: options[typeid] = [place] value = {} value['id'] = typeid value['name'] = _info.Title() value['destinations'] = [] for option in options.get(typeid): if option == None: value['destinations'] = value['destinations'] + \ lookupDestinationsFor(_info, tool, purl, destination_types=destination_types) elif option == '.': value['destinations'].append( getRelativeContentURL(instance)) else: try: place = getattr(aq_base(instance), option, option) except TypeError: place = option if callable(place): #restore acq.wrapper place = getattr(instance, option) place = place() if isinstance(place, ListType): value['destinations'] = place + value['destinations'] else: #TODO Might as well check for type, doing it everywhere else value['destinations'].append(place) if value['destinations']: types.append(value) return types
def unset(self, name, instance, **kwargs): if not shasattr(instance, "_md"): log("Broken instance %s, no _md" % instance) else: del instance._md[name] instance._p_changed = 1
def addableTypes(self, instance, field): """ Returns a list of dictionaries which maps portal_type to a human readable form. """ tool = getToolByName(instance, "portal_types") purl = getToolByName(instance, "portal_url") lookupDestinationsFor = self.lookupDestinationsFor getRelativeContentURL = purl.getRelativeContentURL # if destination_types is None (by default) it will do # N-portal_types queries to the catalog which is horribly inefficient destination_types = getattr(self, "destination_types", None) destination = self.destination types = [] options = {} for typeid in field.allowed_types: _info = tool.getTypeInfo(typeid) if _info is None: # The portal_type asked for was not # installed/has been removed. log("Warning: in Archetypes.Widget.lookupDestinationsFor: " "portal type %s not found" % typeid) continue if destination == None: options[typeid] = [None] elif isinstance(destination, DictType): options[typeid] = destination.get(typeid, [None]) if not isinstance(options[typeid], ListType): options[typeid] = [options[typeid]] elif isinstance(destination, ListType): options[typeid] = destination else: place = getattr(aq_base(instance), destination, destination) if callable(place): # restore acq.wrapper place = getattr(instance, destination) place = place() if isinstance(place, ListType): options[typeid] = place else: options[typeid] = [place] value = {} value["id"] = typeid value["name"] = _info.Title() value["destinations"] = [] for option in options.get(typeid): if option == None: value["destinations"] = value["destinations"] + lookupDestinationsFor( _info, tool, purl, destination_types=destination_types ) elif option == ".": value["destinations"].append(getRelativeContentURL(instance)) else: try: place = getattr(aq_base(instance), option, option) except TypeError: place = option if callable(place): # restore acq.wrapper place = getattr(instance, option) place = place() if isinstance(place, ListType): value["destinations"] = place + value["destinations"] else: # TODO Might as well check for type, doing it everywhere else value["destinations"].append(place) if value["destinations"]: types.append(value) return types