def _updatePluginRegistry(registry, xml, should_purge, encoding=None): if should_purge: registry._plugin_types = [] registry._plugin_type_info = PersistentMapping() registry._plugins = PersistentMapping() # When PAS import is used in an extension profile, the plugin # registry will have been deleted (content import deletes by # default) but should_purge will be false; need to initialize # _plugins since PluginRegistry's constructor doesn't if registry._plugins is None: registry._plugins = PersistentMapping() pir = PluginRegistryImporter(registry, encoding) reg_info = pir.parseXML(xml) for info in reg_info['plugin_types']: iface = _resolveDottedName(info['interface']) # Avoid duplicate plugin types if iface not in registry._plugin_types: registry._plugin_types.append(iface) registry._plugin_type_info[iface] = { 'id': info['id'], 'title': info['title'], 'description': info['description'], } registry._plugins[iface] = tuple([x['id'] for x in info['plugins']])
def allCriteria(self, bib_type=None): # migrate CMFBAT v0.8 duplicates engine, mending a linguistic fault-pas if shasattr(self, '_criterias'): print 'CMFBibliographyAT: performing duplicates engine property update - v0.8 -> v0.9 (allCriteria of %s)' % '/'.join(self.getId()) self._criteria = PersistentMapping() self.initCriteria() try: delattr(self, '_criterias') except: pass # this should have been performed by __init__ but after some product migrations we might want to check it here again if not shasattr(self, '_criteria'): self._criteria = PersistentMapping() if not shasattr(self, 'duplicates_criteria'): self.duplicates_criteria = PersistentMapping() # first call? initialize self._criteria (available duplicates criteria per reference type) if not self._criteria: self.initCriteria() # always init criteria, during development, schema changes, etc. self.initCriteria() if bib_type: try: self._criteria[bib_type] except KeyError: return False return self._criteria[bib_type] else: critKeys = self._criteria.keys() critKeys.sort() return [(key, self._criteria[key]) for key in critKeys]
def initCriteria(self): """ initialize the dictionary of import criteria for each bibliography type """ # this is a migration 0.8 -> 0.9 fix: if not shasattr(self, '_criteria'): self._criteria = PersistentMapping() bib_tool = getToolByName(self, 'portal_bibliography') has = self._criteria_names.has_key for bib_type in bib_tool.getBibliographyContentTypes(): bibname = bib_type['name'] self._criteria[bibname] = [ criteria for criteria in self._nonmeta_criteria ] #adds all meta_data as criteria for each bibliography type for field in bib_type['schema'].fields(): field_name = field.getName() if field_name in self._ignored_criteria: continue if not shasattr(field, 'is_duplicates_criterion'): continue if not field.is_duplicates_criterion: continue if has(field_name): self._criteria[bibname].append( self._criteria_names[field_name]) else: self._criteria[bibname].append(field_name) self._criteria[bibname].sort() self._criteria[bibname] = tuple(self._criteria[bibname])
def get_po_header(self, lang): """ """ # For backwards compatibility if not hasattr(aq_base(self), '_po_headers'): self._po_headers = PersistentMapping() return self._po_headers.get(lang, empty_po_header)
def _initDCWorkflowStates(workflow, states): """ Initialize DCWorkflow states """ from Products.DCWorkflow.States import StateDefinition for s_info in states: id = str(s_info['state_id']) # no unicode! if not workflow.states.has_key(id): s = StateDefinition(id) workflow.states._setObject(id, s) s = workflow.states._getOb(id) s.setProperties(title=s_info['title'], description=s_info['description'], transitions=s_info['transitions']) for k, v in s_info['permissions'].items(): s.setPermission(k, isinstance(v, list), v) gmap = s.group_roles = PersistentMapping() for group_id, roles in s_info['groups']: gmap[group_id] = roles vmap = s.var_values = PersistentMapping() for name, v_info in s_info['variables'].items(): value = _convertVariableValue(v_info['value'], v_info['type']) vmap[name] = value
def setPermission(self, permission, roles, REQUEST=None): """ Set a permission for this State. """ if self.state_permission_role_list_dict is None: self.state_permission_role_list_dict = PersistentMapping() self.state_permission_role_list_dict[permission] = tuple(roles)
def getTreeIdList(self, htree=None): """ Return list of all tree ids """ if self._tree_list is None or len(self._tree_list.keys()) == 0: tree_list = self._getTreeIdList(htree=htree) self._tree_list = PersistentMapping() for tree in tree_list: self._tree_list[tree] = None return sorted(self._tree_list.keys())
def setCriteria(self, duplicates_criteria): """update criteria for all bibliography types""" if not duplicates_criteria: duplicates_criteria = {} bib_tool = getToolByName(self, 'portal_bibliography') for key in bib_tool.getReferenceTypes(): duplicates_criteria[key] = [] self.duplicates_criteria = PersistentMapping(duplicates_criteria) self.criteriaUpdated = True
def listPolicies(self): """ return the list of defined policies a policy is a 2-uple (output_mime_type, [list of required transforms]) """ # XXXFIXME: backward compat, should be removed latter if not hasattr(self, '_policies'): self._policies = PersistentMapping() return self._policies.items()
def __init__(self): self._schemas = PersistentMapping() self._templates = PersistentMapping() self._registeredTemplates = PersistentMapping() # meta_type -> [names of CatalogTools] self.catalog_map = PersistentMapping() self.catalog_map['Reference'] = [] # References not in portal_catalog # DM (avoid persistency bug): "_types" now maps known schemas to signatures self._types = {}
def setStatePermissionRoleListDict(self, permission_roles): """ create a dict containing the state's permission (as key) and its associated role list (value) use a PersistentMapping so that the ZODB is updated when this dict is changed """ self.state_permission_role_list_dict = PersistentMapping( {k: tuple(v) for (k, v) in permission_roles.items()})
def __init__(self, plugin_type_info): self._plugin_types = [x[0] for x in plugin_type_info] self._plugin_type_info = PersistentMapping() for interface in plugin_type_info: self._plugin_type_info[interface[0]] = { 'id': interface[1], 'title': interface[2], 'description': interface[3] }
def setDependentProducts(jar, productid, dep_ids): productid = str(productid) rd = _getCentralRefreshData(jar, 1) products = rd.get('products', None) if products is None: rd['products'] = products = PersistentMapping() product = products.get(productid, None) if product is None: products[productid] = product = PersistentMapping() product['dependent_products'] = tuple(map(str, dep_ids))
def _save_user_state(self, user_name, user_state): """ Saves the state for the passed user to the session database """ if user_state: user_state_json = json.dumps(user_state) user_settings = getattr(self._dmd.ZenUsers, user_name) state_container = getattr(user_settings, '_browser_state', None) if isinstance(state_container, basestring) or state_container is None: state_container = PersistentMapping() user_settings._browser_state = state_container if user_state_json != state_container.get('state', ''): state_container['state'] = user_state_json
def _getPlugins(self, plugin_type): parent = aq_parent(aq_inner(self)) if plugin_type not in self._plugin_types: raise KeyError, plugin_type if self._plugins is None: self._plugins = PersistentMapping() return self._plugins.setdefault(plugin_type, ())
def fixArchetypesTool(portal, out): at = portal.archetype_tool if not hasattr(at, '_templates'): # They come in pairs at._templates = PersistentMapping() at._registeredTemplates = PersistentMapping() if not hasattr(at, 'catalog_map'): at.catalog_map = PersistentMapping() install_uidcatalog(out, portal)
def getSelectedCriteria(self, bib_type=None): # migrate CMFBAT v0.8 duplicates engine, mending a linguistic fault-pas if shasattr(self, 'imp_criterias'): print 'CMFBibliographyAT: performing duplicates engine property update - v0.8 -> v0.9 (getSelectedCriteria of %s)' % '/'.join( self.getId()) self.duplicates_criteria = PersistentMapping() self.duplicates_criteria = copy.deepcopy(self.imp_criterias) self.criteriaUpdated = self.criteriasUpdated try: delattr(self, 'imp_criterias') except: pass try: delattr(self, 'criteriasUpdated') except: pass # first call? initialize self.duplicates_criteria bib_tool = getToolByName(self, 'portal_bibliography') if not shasattr(self, 'duplicates_criteria') or not self.duplicates_criteria: if self.getId() == bib_tool.getId(): for reference_type in bib_tool.getReferenceTypes(): self.duplicates_criteria[reference_type] = PersistentList( self._default_duplicates_criteria) self.criteriaUpdated = True else: self.duplicates_criteria = bib_tool.getSelectedCriteria() self.criteriaUpdated = True if not shasattr(self, '_criteria') or not self._criteria: self.initCriteria() # make sure, our selected criteria are in sync with available criteria duplicates_criteria = {} for key in self._criteria.keys(): duplicates_criteria[key] = [ criterion for criterion in self._criteria[key] if self.duplicates_criteria.has_key(key) and ( criterion in self.duplicates_criteria[key]) ] if bib_type: try: duplicates_criteria[bib_type] except KeyError: return False return duplicates_criteria[bib_type] else: return duplicates_criteria
def test_catch_extra_attribute(self): # The mapper for PersistentMappings doesn't allow an # extra attribute. classification = None ob = PersistentMapping() ob.extra = '678' ob['a'] = 'b' ob['c'] = 'd' obj_db = MockObjectDatabase() m = self.conf.mappers["pm"] event = SerializationEvent( self.conf, m, '', classification, obj_db, ob) self.assertRaises(SerializationError, m.serializer.serialize, event)
def setBrowserState(self, state): """ Save the browser state for the current user. @param state: The browser state as a JSON-encoded string @type state: str """ userSettings = self.context.dmd.ZenUsers.getUserSettings() state_container = getattr(userSettings, '_browser_state', None) if isinstance(state_container, basestring) or state_container is None: state_container = PersistentMapping() userSettings._browser_state = state_container if state != state_container.get('state', ''): state_container['state'] = state
def __init__(self, plugin_type_info=()): if isinstance(plugin_type_info, basestring): # some tool is passing us our ID. raise ValueError('Must pass a sequence of plugin info dicts!') self._plugin_types = [x[0] for x in plugin_type_info] self._plugin_type_info = PersistentMapping() for interface in plugin_type_info: self._plugin_type_info[interface[0]] = { 'id': interface[1], 'title': interface[2], 'description': interface[3] }
def create_frozen_state(self, workflow, **parameters): """ create a 'frozen' state """ if 'frozen' not in workflow.states: workflow.states.addState('frozen') frozen_state = workflow.states['frozen'] default_mapping = workflow.states.objectValues()[0].permission_roles.copy() frozen_state.title = 'frozen' frozen_state.permission_roles = default_mapping frozen_state.group_roles = PersistentMapping() frozen_state.var_values = PersistentMapping() frozen_state.transitions = ()
def test_get_serial_detects_new_objects(self): # Verifies the behavior of _get_serial() and _set_serial(). conn1 = self.db.open() try: ob = self._write_basic_object(conn1) self.assertNotEqual(conn1._get_serial(ob), '\0' * 8) # Replace the object and verify it gets a new serial. ob1 = PersistentMapping() ob1.strdata = 'cba' ob1._p_oid = conn1.root()['TestRoot']._p_oid conn1.root()['TestRoot'] = ob1 self.assertEqual(conn1._get_serial(ob1), '\0' * 8) finally: conn1.close()
def test_copy_of(self): # Verifies the functionality of zodb_copy(). ob1 = PersistentMapping() ob1._p_oid = 'xxx' self.assertEqual(ob1._p_oid, 'xxx') # Precondition ob1['fish'] = PersistentMapping() ob1['fish']['trout'] = 1 ob1['fish']['herring'] = 2 ob2 = zodb_copy(ob1) self.assert_(ob2 is not ob1) self.assert_(ob2['fish'] is not ob1['fish']) self.assert_(ob2._p_oid is None) self.assertEqual(list(ob2.keys()), ['fish']) self.assertEqual(len(ob2['fish'].keys()), 2)
def setRoleMapping(self, portal_role, userfolder_role, REQUEST=None): """ set the mapping of roles between roles understood by the portal and roles coming from outside user sources """ if not hasattr(self, 'role_map'): self.role_map = PersistentMapping() if len(userfolder_role) < 1: del self.role_map[portal_role] else: self.role_map[portal_role] = userfolder_role return MessageDialog(title='Mapping updated', message='The Role mappings have been updated', action='manage_mapRoles')
def setMultiEntryTransition(self, transition_url, max_entry_number): """ Set a transition as multiple - i.e max_entry_number of forms which will be rendered. This method is called in after scripts and usually this number is set by user in a web form. """ if getattr(aq_base(self), '_multi_entry_transitions', None) is None: self._multi_entry_transitions = PersistentMapping() self._multi_entry_transitions[transition_url] = max_entry_number
def initCriteria(self): """ initialize the dictionary of import criteria for each bibliography type """ # this is a migration 0.8 -> 0.9 fix: if not shasattr(self, '_criteria'): self._criteria = PersistentMapping() bib_tool = getToolByName(self, 'portal_bibliography') has = self._criteria_names.has_key for bib_type in bib_tool.getBibliographyContentTypes(): bibname = bib_type['name'] self._criteria[bibname] = [criteria for criteria in self._nonmeta_criteria] #adds all meta_data as criteria for each bibliography type for field in bib_type['schema'].fields(): field_name = field.getName() if field_name in self._ignored_criteria: continue if not shasattr(field, 'is_duplicates_criterion'): continue if not field.is_duplicates_criterion: continue if has(field_name): self._criteria[bibname].append(self._criteria_names[field_name]) else : self._criteria[bibname].append(field_name) self._criteria[bibname].sort() self._criteria[bibname] = tuple(self._criteria[bibname])
def _initDCWorkflowWorklists(workflow, worklists): """ Initialize DCWorkflow worklists """ from Products.DCWorkflow.Worklists import WorklistDefinition for w_info in worklists: id = str(w_info['worklist_id']) # no unicode! if not workflow.worklists.has_key(id): w = WorklistDefinition(id) workflow.worklists._setObject(id, w) w = workflow.worklists._getOb(id) action = w_info['action'] guard = w_info['guard'] props = { 'guard_roles': ';'.join(guard['roles']), 'guard_permissions': ';'.join(guard['permissions']), 'guard_groups': ';'.join(guard['groups']), 'guard_expr': guard['expression'] } w.setProperties(description=w_info['description'], actbox_name=action['name'], actbox_url=action['url'], actbox_category=action['category'], actbox_icon=action.get('icon', ''), props=props) w.var_matches = PersistentMapping() for k, v in w_info['match'].items(): w.var_matches[str(k)] = tuple([str(x) for x in v])
def setChainForPortalTypes(self, pt_names, chain, verify=True, REQUEST=None): """ Set a chain for specific portal types. """ cbt = self._chains_by_type if cbt is None: self._chains_by_type = cbt = PersistentMapping() if isinstance(chain, six.string_types): if chain == '(Default)': chain = None else: chain = [wf.strip() for wf in chain.split(',') if wf.strip()] if chain is None: for type_id in pt_names: if type_id in cbt: del cbt[type_id] return ti_ids = [t.getId() for t in self._listTypeInfo()] for type_id in pt_names: if verify and not (type_id in ti_ids): continue cbt[type_id] = tuple(chain)
def setGlobalConfigurationAttr(self, **kw): """ Set global business configuration attribute. """ if getattr(aq_base(self), '_global_configuration_attributes', None) is None: self._global_configuration_attributes = PersistentMapping() for key, value in kw.items(): self._global_configuration_attributes[key] = value
def set(self, status): history = getattr(self.context, 'workflow_history', None) if history is None: history = self.context.workflow_history = PersistentMapping() wfh = list(history.get(self.wf_id, ())) wfh.append(status) history[self.wf_id] = tuple(wfh)
def setChain(self, portal_type, chain, REQUEST=None): """Set the chain for a portal type. @type chain: tuple of strings or None @param chain: A tuple of workflow ids to be set for the portal type. A few special values exsist: - C{None}: Acquire chain from a policy above, ultimatly from the portal workflow settings. - C{()} (empty tuple): No workflow for this type. - C{('default',)}: Use the configured default workflow. """ # Verify input data if portal_type not in [pt.id for pt in self._listTypeInfo()]: raise ValueError("'%s' is not a valid portal type." % portal_type) if isinstance(chain, six.string_types): chain = map(lambda x: x.strip(), chain.split(',')) wftool = getToolByName(self, 'portal_workflow') cbt = self._chains_by_type if cbt is None: self._chains_by_type = cbt = PersistentMapping() # if chain is None or default, we remove the entry if chain is None: if portal_type in cbt: del cbt[portal_type] elif len(chain) == 1 and chain[0] == DEFAULT_CHAIN: cbt[portal_type] = chain else: for wf_id in chain: if wf_id != '' and not wftool.getWorkflowById(wf_id): raise ValueError("'%s' is not a workflow ID.\nchain: %s" % (wf_id, repr(chain))) cbt[portal_type] = tuple(chain)
def wl_lockmapping(self, killinvalids=0, create=0): """ if 'killinvalids' is 1, locks who are no longer valid will be deleted """ try: locks = getattr(self, '_dav_writelocks', None) except Exception: locks = None if locks is None: if create: locks = self._dav_writelocks = PersistentMapping() else: # Don't generate a side effect transaction. locks = {} return locks elif killinvalids: # Delete invalid locks for token, lock in list(locks.items()): if not lock.isValid(): del locks[token] if (not locks) and hasattr(aq_base(self), '__no_valid_write_locks__'): self.__no_valid_write_locks__() return locks else: return locks
def __init__(self, id, title, sourcelang, languages): self.id = id self.title = title # Language Manager data self._languages = tuple(languages) self._default_language = sourcelang # Here the message translations are stored self._messages = PersistentMapping() # Data for the PO files headers self._po_headers = PersistentMapping() for lang in self._languages: self._po_headers[lang] = empty_po_header
def setRankForCategory(self, category, rank): """Set the object's rank for the specified category """ if not hasattr(self, '_categoryRanks') \ or not isinstance(self._categoryRanks, PersistentMapping): self._categoryRanks = PersistentMapping() self._categoryRanks[category] = rank
def setStatusOf(self, wf_id, ob, status): """Invoked by workflow definitions. Appends to the workflow history. """ ob_id = self._getId(ob, 1) assert ob_id, 'No version history ID available' repo = self._getRepository() h = repo.getHistory(ob_id) if h is None: h = PersistentMapping() repo.setHistory(ob_id, h) wfh = h.get(wf_id) if wfh is not None: wfh = list(wfh) else: wfh = [] wfh.append(status) h[wf_id] = tuple(wfh)
def test_serial_cleanup(self): # Verify that _set_serial() cleans up. conn1 = self.db.open() try: conn1.serial_cleanup_threshold = 10 for n in range(conn1.serial_cleanup_threshold + 1): new_ob = PersistentMapping() new_ob._p_oid = 'fake_oid_' + str(n) old_size = len(conn1._serials or ()) conn1._set_serial(new_ob, '01234567') new_size = len(conn1._serials) if new_size < old_size: # Cleaned up. Success. break else: self.fail("_set_serial() did not clean up") finally: conn1.close()
def _prepare_root(self): osio = self._get_osio() oid = osio.conf.oid_gen.root_oid try: self[oid] except (KeyError, LoadError): # Create the root object. from Persistence import PersistentMapping root = PersistentMapping() root._p_jar = self root._p_changed = 1 root._p_oid = oid t = transaction.Transaction() t.note('Initial database creation') self.tpc_begin(t) self.commit(root, t) self.tpc_vote(t) self.tpc_finish(t)
def __init__(self, id=None): if id is not None: assert id == self.id self.encodings_map = encodings_map.copy() self.suffix_map = suffix_map.copy() # Major key -> minor IMimetype objects self._mimetypes = PersistentMapping() # ext -> IMimetype mapping self.extensions = PersistentMapping() # glob -> (regex, mimetype) mapping self.globs = OOBTree() self.manage_addProperty("defaultMimetype", "text/plain", "string") self.manage_addProperty("unicodePolicies", "strict ignore replace", "tokens") self.manage_addProperty("unicodePolicy", "unicodePolicies", "selection") self.manage_addProperty("fallbackEncoding", "latin1", "string") # initialize mime types initialize(self) self._new_style_mtr = 1
def __init__( self, plugin_type_info ): self._plugin_types = [x[0] for x in plugin_type_info] self._plugin_type_info = PersistentMapping() for interface in plugin_type_info: self._plugin_type_info[interface[0]] = { 'id': interface[1] , 'title': interface[2] , 'description': interface[3] }
def __init__(self, plugin_type_info=()): if isinstance(plugin_type_info, basestring): # some tool is passing us our ID. raise ValueError('Must pass a sequence of plugin info dicts!') self._plugin_types = [x[0] for x in plugin_type_info] self._plugin_type_info = PersistentMapping() for interface in plugin_type_info: self._plugin_type_info[interface[0]] = { 'id': interface[1] , 'title': interface[2] , 'description': interface[3] }
def setRoleMapping(self, portal_role, userfolder_role, REQUEST=None): """ set the mapping of roles between roles understood by the portal and roles coming from outside user sources """ if not hasattr(self, 'role_map'): self.role_map = PersistentMapping() if len(userfolder_role) < 1: del self.role_map[portal_role] else: self.role_map[portal_role] = userfolder_role return MessageDialog( title ='Mapping updated', message='The Role mappings have been updated', action ='manage_mapRoles')
def __init__(self, id, title, languages=('en', )): self.id = id self.title = title # Language Manager data self._languages = tuple(languages) # We suppose all zope/portal products are written in English # therefore we consider all new messages in English # Default language in Catalog is always 'en', thus it can be different # from the default language of the portal self._default_language = 'en' # self._languages[0] # Here the message translations are stored self._messages = PersistentMapping() self._po_headers = PersistentMapping()
def __init__(self, id, **kwargs): self._data = PersistentMapping() extres = id.startswith('http://') or id.startswith('https://') if id.startswith('/') or id.endswith('/') or ('//' in id and not extres): raise ValueError("Invalid Resource ID: %s" % id) self._data['id'] = id expression = kwargs.get('expression', '') self.setExpression(expression) self._data['authenticated'] = kwargs.get('authenticated', False) self._data['enabled'] = kwargs.get('enabled', True) self._data['cookable'] = kwargs.get('cookable', True) self._data['cacheable'] = kwargs.get('cacheable', True) self._data['conditionalcomment'] = kwargs.get('conditionalcomment','') self.isExternal = extres if extres: self._data['cacheable'] = False #External resources are NOT cacheable self._data['cookable'] = False #External resources are NOT mergable
def __init__(self, id, **kwargs): self._data = PersistentMapping() extres = id.startswith("http://") or id.startswith("https://") if id.startswith("/") or id.endswith("/") or ("//" in id and not extres): raise ValueError("Invalid Resource ID: %s" % id) self._data["id"] = id expression = kwargs.get("expression", "") self.setExpression(expression) self._data["authenticated"] = kwargs.get("authenticated", False) self._data["enabled"] = kwargs.get("enabled", True) self._data["cookable"] = kwargs.get("cookable", True) self._data["cacheable"] = kwargs.get("cacheable", True) self._data["conditionalcomment"] = kwargs.get("conditionalcomment", "") self._data["bundle"] = kwargs.get("bundle", "default") self.isExternal = extres if extres: self._data["cacheable"] = False # External resources are NOT cacheable self._data["cookable"] = False # External resources are NOT mergable
def getSelectedCriteria(self, bib_type = None): # migrate CMFBAT v0.8 duplicates engine, mending a linguistic fault-pas if shasattr(self, 'imp_criterias'): print 'CMFBibliographyAT: performing duplicates engine property update - v0.8 -> v0.9 (getSelectedCriteria of %s)' % '/'.join(self.getId()) self.duplicates_criteria = PersistentMapping() self.duplicates_criteria = copy.deepcopy(self.imp_criterias) self.criteriaUpdated = self.criteriasUpdated try: delattr(self, 'imp_criterias') except: pass try: delattr(self, 'criteriasUpdated') except: pass # first call? initialize self.duplicates_criteria bib_tool = getToolByName(self, 'portal_bibliography') if not shasattr(self, 'duplicates_criteria') or not self.duplicates_criteria: if self.getId() == bib_tool.getId(): for reference_type in bib_tool.getReferenceTypes(): self.duplicates_criteria[reference_type] = PersistentList(self._default_duplicates_criteria) self.criteriaUpdated = True else: self.duplicates_criteria = bib_tool.getSelectedCriteria() self.criteriaUpdated = True if not shasattr(self, '_criteria') or not self._criteria: self.initCriteria() # make sure, our selected criteria are in sync with available criteria duplicates_criteria = {} for key in self._criteria.keys(): duplicates_criteria[key] = [ criterion for criterion in self._criteria[key] if self.duplicates_criteria.has_key(key) and (criterion in self.duplicates_criteria[key]) ] if bib_type: try: duplicates_criteria[bib_type] except KeyError: return False return duplicates_criteria[bib_type] else: return duplicates_criteria
def setProperties(self, description, actbox_name='', actbox_url='', actbox_category='global', actbox_icon='', props=None, REQUEST=None): ''' ''' if props is None: props = REQUEST self.description = str(description) for key in self.getAvailableCatalogVars(): # Populate var_matches. fieldname = 'var_match_%s' % key v = props.get(fieldname, '') if v: if not self.var_matches: self.var_matches = PersistentMapping() if tales_re.match(v).group(1): # Found a TALES prefix self.var_matches[key] = Expression(v) else: # Falling back to formatted string v = [ var.strip() for var in v.split(';') ] self.var_matches[key] = tuple(v) else: if self.var_matches and self.var_matches.has_key(key): del self.var_matches[key] self.actbox_name = str(actbox_name) self.actbox_url = str(actbox_url) self.actbox_category = str(actbox_category) self.actbox_icon = str(actbox_icon) g = Guard() if g.changeFromProperties(props or REQUEST): self.guard = g else: self.guard = None if REQUEST is not None: return self.manage_properties(REQUEST, 'Properties changed.')
class Resource(Persistent): security = ClassSecurityInfo() def __init__(self, id, **kwargs): self._data = PersistentMapping() extres = id.startswith('http://') or id.startswith('https://') if id.startswith('/') or id.endswith('/') or ('//' in id and not extres): raise ValueError("Invalid Resource ID: %s" % id) self._data['id'] = id expression = kwargs.get('expression', '') self.setExpression(expression) self._data['authenticated'] = kwargs.get('authenticated', False) self._data['enabled'] = kwargs.get('enabled', True) self._data['cookable'] = kwargs.get('cookable', True) self._data['cacheable'] = kwargs.get('cacheable', True) self._data['conditionalcomment'] = kwargs.get('conditionalcomment','') self._data['bundle'] = kwargs.get('bundle', 'default') self.isExternal = extres if extres: self._data['cacheable'] = False #External resources are NOT cacheable self._data['cookable'] = False #External resources are NOT mergable def copy(self): result = self.__class__(self.getId()) for key, value in self._data.items(): if key != 'id': result._data[key] = value return result security.declarePublic('getId') def getId(self): return self._data['id'] security.declarePublic('getQuotedId') def getQuotedId(self): return quote_plus(self._data['id']) security.declareProtected(permissions.ManagePortal, '_setId') def _setId(self, id): if id.startswith('/') or id.endswith('/') or ( ('//' in id) and not self.isExternalResource()): raise ValueError("Invalid Resource ID: %s" %id) self._data['id'] = id security.declarePublic('getCookedExpression') def getCookedExpression(self): # Automatic inline migration of expressions if 'cooked_expression' not in self._data: expr = Expression(self._data['expression']) self._data['cooked_expression'] = expr return self._data['cooked_expression'] security.declarePublic('getExpression') def getExpression(self): return self._data['expression'] security.declareProtected(permissions.ManagePortal, 'setExpression') def setExpression(self, expression): # Update the cooked expression self._data['cooked_expression'] = Expression( expression ) self._data['expression'] = expression security.declarePublic('getAuthenticated') def getAuthenticated(self): # Automatic inline migration if 'authenticated' not in self._data: self._data['authenticated'] = False return bool(self._data['authenticated']) security.declareProtected(permissions.ManagePortal, 'setAuthenticated') def setAuthenticated(self, authenticated): self._data['authenticated'] = authenticated security.declarePublic('getEnabled') def getEnabled(self): return bool(self._data['enabled']) security.declareProtected(permissions.ManagePortal, 'setEnabled') def setEnabled(self, enabled): self._data['enabled'] = enabled security.declarePublic('getCookable') def getCookable(self): return self._data['cookable'] security.declareProtected(permissions.ManagePortal, 'setCookable') def setCookable(self, cookable): if self.isExternalResource() and cookable: raise ValueError("External Resources cannot be merged") self._data['cookable'] = cookable security.declarePublic('getCacheable') def getCacheable(self): # as this is a new property, old instance might not have that value, so # return True as default return self._data.get('cacheable', True) security.declareProtected(permissions.ManagePortal, 'setCacheable') def setCacheable(self, cacheable): if self.isExternalResource() and cacheable: raise ValueError("External Resources are not cacheable") self._data['cacheable'] = cacheable security.declarePublic('getConditionalcomment') def getConditionalcomment(self): # New property, return blank if the old instance doesn't have that value return self._data.get('conditionalcomment','') security.declareProtected(permissions.ManagePortal, 'setConditionalcomment') def setConditionalcomment(self, conditionalcomment): self._data['conditionalcomment'] = conditionalcomment security.declarePublic('isExternalResource') def isExternalResource(self): return getattr(self, 'isExternal', False) security.declarePublic('getBundle') def getBundle(self): return self._data.get('bundle', None) or 'default' security.declareProtected(permissions.ManagePortal, 'setBundle') def setBundle(self, bundle): self._data['bundle'] = bundle
class Resource(Persistent): security = ClassSecurityInfo() def __init__(self, id, **kwargs): self._data = PersistentMapping() extres = id.startswith("http://") or id.startswith("https://") if id.startswith("/") or id.endswith("/") or ("//" in id and not extres): raise ValueError("Invalid Resource ID: %s" % id) self._data["id"] = id expression = kwargs.get("expression", "") self.setExpression(expression) self._data["authenticated"] = kwargs.get("authenticated", False) self._data["enabled"] = kwargs.get("enabled", True) self._data["cookable"] = kwargs.get("cookable", True) self._data["cacheable"] = kwargs.get("cacheable", True) self._data["conditionalcomment"] = kwargs.get("conditionalcomment", "") self._data["bundle"] = kwargs.get("bundle", "default") self.isExternal = extres if extres: self._data["cacheable"] = False # External resources are NOT cacheable self._data["cookable"] = False # External resources are NOT mergable def copy(self): result = self.__class__(self.getId()) for key, value in self._data.items(): if key != "id": result._data[key] = value return result security.declarePublic("getId") def getId(self): return self._data["id"] security.declarePublic("getQuotedId") def getQuotedId(self): return quote_plus(self._data["id"]) security.declareProtected(permissions.ManagePortal, "_setId") def _setId(self, id): if id.startswith("/") or id.endswith("/") or (("//" in id) and not self.isExternalResource()): raise ValueError("Invalid Resource ID: %s" % id) self._data["id"] = id security.declarePublic("getCookedExpression") def getCookedExpression(self): # Automatic inline migration of expressions if "cooked_expression" not in self._data: expr = Expression(self._data["expression"]) self._data["cooked_expression"] = expr return self._data["cooked_expression"] security.declarePublic("getExpression") def getExpression(self): return self._data["expression"] security.declareProtected(permissions.ManagePortal, "setExpression") def setExpression(self, expression): # Update the cooked expression self._data["cooked_expression"] = Expression(expression) self._data["expression"] = expression security.declarePublic("getAuthenticated") def getAuthenticated(self): # Automatic inline migration if "authenticated" not in self._data: self._data["authenticated"] = False return bool(self._data["authenticated"]) security.declareProtected(permissions.ManagePortal, "setAuthenticated") def setAuthenticated(self, authenticated): self._data["authenticated"] = authenticated security.declarePublic("getEnabled") def getEnabled(self): return bool(self._data["enabled"]) security.declareProtected(permissions.ManagePortal, "setEnabled") def setEnabled(self, enabled): self._data["enabled"] = enabled security.declarePublic("getCookable") def getCookable(self): return self._data["cookable"] security.declareProtected(permissions.ManagePortal, "setCookable") def setCookable(self, cookable): if self.isExternalResource() and cookable: raise ValueError("External Resources cannot be merged") self._data["cookable"] = cookable security.declarePublic("getCacheable") def getCacheable(self): # as this is a new property, old instance might not have that value, so # return True as default return self._data.get("cacheable", True) security.declareProtected(permissions.ManagePortal, "setCacheable") def setCacheable(self, cacheable): if self.isExternalResource() and cacheable: raise ValueError("External Resources are not cacheable") self._data["cacheable"] = cacheable security.declarePublic("getConditionalcomment") def getConditionalcomment(self): # New property, return blank if the old instance doesn't have that value return self._data.get("conditionalcomment", "") security.declareProtected(permissions.ManagePortal, "setConditionalcomment") def setConditionalcomment(self, conditionalcomment): self._data["conditionalcomment"] = conditionalcomment security.declarePublic("isExternalResource") def isExternalResource(self): return getattr(self, "isExternal", False) security.declarePublic("getBundle") def getBundle(self): return self._data.get("bundle", None) or "default" security.declareProtected(permissions.ManagePortal, "setBundle") def setBundle(self, bundle): self._data["bundle"] = bundle
class ArchetypeTool(UniqueObject, ActionProviderBase, SQLStorageConfig, Folder): """Archetypes tool, manage aspects of Archetype instances. """ id = TOOL_NAME meta_type = TOOL_NAME.title().replace('_', ' ') implements(IArchetypeTool) isPrincipiaFolderish = True # Show up in the ZMI security = ClassSecurityInfo() meta_types = all_meta_types = () manage_options = ( ( {'label': 'Types', 'action': 'manage_debugForm', }, {'label': 'Catalogs', 'action': 'manage_catalogs', }, {'label': 'Templates', 'action': 'manage_templateForm', }, {'label': 'UIDs', 'action': 'manage_uids', }, {'label': 'Update Schema', 'action': 'manage_updateSchemaForm', }, {'label': 'Migration', 'action': 'manage_migrationForm', }, ) + SQLStorageConfig.manage_options ) security.declareProtected(permissions.ManagePortal, 'manage_uids') manage_uids = PageTemplateFile('viewContents', _www) security.declareProtected(permissions.ManagePortal, 'manage_templateForm') manage_templateForm = PageTemplateFile('manageTemplates', _www) security.declareProtected(permissions.ManagePortal, 'manage_debugForm') manage_debugForm = PageTemplateFile('generateDebug', _www) security.declareProtected(permissions.ManagePortal, 'manage_updateSchemaForm') manage_updateSchemaForm = PageTemplateFile('updateSchemaForm', _www) security.declareProtected(permissions.ManagePortal, 'manage_migrationForm') manage_migrationForm = PageTemplateFile('migrationForm', _www) security.declareProtected(permissions.ManagePortal, 'manage_dumpSchemaForm') manage_dumpSchemaForm = PageTemplateFile('schema', _www) security.declareProtected(permissions.ManagePortal, 'manage_catalogs') manage_catalogs = PageTemplateFile('manage_catalogs', _www) def __init__(self): self._schemas = PersistentMapping() self._templates = PersistentMapping() self._registeredTemplates = PersistentMapping() # meta_type -> [names of CatalogTools] self.catalog_map = PersistentMapping() self.catalog_map['Reference'] = [] # References not in portal_catalog # DM (avoid persistency bug): "_types" now maps known schemas to # signatures self._types = {} security.declareProtected(permissions.ManagePortal, 'manage_dumpSchema') def manage_dumpSchema(self, REQUEST=None): """XML Dump Schema of passed in class. """ from Products.Archetypes.Schema import getSchemata package = REQUEST.get('package', '') type_name = REQUEST.get('type_name', '') spec = self.getTypeSpec(package, type_name) type = self.lookupType(package, type_name) options = {} options['classname'] = spec options['schematas'] = getSchemata(type['klass']) REQUEST.RESPONSE.setHeader('Content-Type', 'text/xml') return self.manage_dumpSchemaForm(**options) # Template Management # Views can be pretty generic by iterating the schema so we don't # register by type anymore, we just create per site selection # lists # # We keep two lists, all register templates and their # names/titles and the mapping of type to template bindings both # are persistent security.declareProtected(permissions.ManagePortal, 'registerTemplate') def registerTemplate(self, template, name=None): # Lookup the template by name if not name: obj = self.unrestrictedTraverse(template, None) try: name = obj.title_or_id() except: name = template self._registeredTemplates[template] = name security.declareProtected(permissions.View, 'lookupTemplates') def lookupTemplates(self, instance_or_portaltype=None): """Lookup templates by giving an instance or a portal_type. Returns a DisplayList. """ results = [] if not isinstance(instance_or_portaltype, basestring): portal_type = instance_or_portaltype.getTypeInfo().getId() else: portal_type = instance_or_portaltype try: templates = self._templates[portal_type] except KeyError: return DisplayList() # XXX Look this up in the types tool later # self._templates[instance] = ['base_view',] # templates = self._templates[instance] for t in templates: results.append((t, self._registeredTemplates[t])) return DisplayList(results).sortedByValue() security.declareProtected(permissions.View, 'listTemplates') def listTemplates(self): """Lists all the templates. """ return DisplayList(self._registeredTemplates.items()).sortedByValue() security.declareProtected(permissions.ManagePortal, 'bindTemplate') def bindTemplate(self, portal_type, templateList): """Creates binding between a type and its associated views. """ self._templates[portal_type] = templateList security.declareProtected(permissions.ManagePortal, 'manage_templates') def manage_templates(self, REQUEST=None): """Sets all the template/type mappings. """ prefix = 'template_names_' for key in REQUEST.form.keys(): if key.startswith(prefix): k = key[len(prefix):] v = REQUEST.form.get(key) self.bindTemplate(k, v) add = REQUEST.get('addTemplate') name = REQUEST.get('newTemplate') if add and name: self.registerTemplate(name) return REQUEST.RESPONSE.redirect(self.absolute_url() + '/manage_templateForm') security.declareProtected(permissions.View, 'typeImplementsInterfaces') def typeImplementsInterfaces(self, type, interfaces): """Checks if an type uses one of the given interfaces. """ if isinstance(type, dict) and 'klass' in type: type = type['klass'] for iface in interfaces: res = iface.implementedBy(type) if res: return True return False security.declareProtected(permissions.View, 'isTemplateEnabled') def isTemplateEnabled(self, type): """Checks if an type uses ITemplateMixin. """ return self.typeImplementsInterfaces(type, [ITemplateMixin]) security.declareProtected( permissions.View, 'listTemplateEnabledPortalTypes') def listTemplateEnabledPortalTypes(self): """Return a list of portal_types with ITemplateMixin """ return self.listPortalTypesWithInterfaces([ITemplateMixin]) security.declareProtected( permissions.View, 'listPortalTypesWithInterfaces') def listPortalTypesWithInterfaces(self, ifaces): """Returns a list of ftis of which the types implement one of the given interfaces. Only returns AT types. Get a list of FTIs of types implementing IReferenceable: >>> portal = layer['portal'] >>> from Products.Archetypes.config import TOOL_NAME >>> tool = getToolByName(portal, TOOL_NAME) >>> ftis = tool.listPortalTypesWithInterfaces([IReferenceable]) Sort the type ids and print them: >>> type_ids = [fti.getId() for fti in ftis] >>> type_ids.sort() >>> type_ids ['ATBIFolder', 'Collection', 'ComplexType', ...] """ pt = getToolByName(self, 'portal_types') value = [] for data in listTypes(): klass = data['klass'] for iface in ifaces: if iface.implementedBy(klass): ti = pt.getTypeInfo(data['portal_type']) if ti is not None: value.append(ti) return value # Type/Schema Management security.declareProtected(permissions.View, 'listRegisteredTypes') def listRegisteredTypes(self, inProject=False, portalTypes=False): """Return the list of sorted types. """ def type_sort(a, b): v = cmp(a['package'], b['package']) if v != False: return v c = cmp(a['klass'].__class__.__name__, b['klass'].__class__.__name__) if c == False: return cmp(a['package'], b['package']) return c values = listTypes() values.sort(type_sort) if inProject: # portal_type can change (as it does after ATCT-migration), so we # need to check against the content_meta_type of each type-info ttool = getToolByName(self, 'portal_types') types = [ti.Metatype() for ti in ttool.listTypeInfo()] if portalTypes: values = [v for v in values if v['portal_type'] in types] else: values = [v for v in values if v['meta_type'] in types] return values security.declareProtected(permissions.View, 'getTypeSpec') def getTypeSpec(self, package, type): t = self.lookupType(package, type) module = t['klass'].__module__ klass = t['name'] return '%s.%s' % (module, klass) security.declareProtected(permissions.View, 'listTypes') def listTypes(self, package=None, type=None): """Just the class. """ if type is None: return [t['klass'] for t in listTypes(package)] else: return [getType(type, package)['klass']] security.declareProtected(permissions.View, 'lookupType') def lookupType(self, package, type): types = self.listRegisteredTypes() for t in types: if t['package'] != package: continue if t['meta_type'] == type: # We have to return the schema wrapped into the acquisition of # something to allow access. Otherwise we will end up with: # Your user account is defined outside the context of the object # being accessed. t['schema'] = ImplicitAcquisitionWrapper(t['schema'], self) return t return None security.declareProtected(permissions.ManagePortal, 'manage_installType') def manage_installType(self, typeName, package=None, uninstall=None, REQUEST=None): """Un/Install a type TTW. """ typesTool = getToolByName(self, 'portal_types') try: typesTool._delObject(typeName) except (ConflictError, KeyboardInterrupt): raise except: # XXX bare exception pass if uninstall is not None: if REQUEST: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/manage_debugForm') return typeinfo_name = '%s: %s' % (package, typeName) # We want to run the process/modify_fti code which might not # have been called typeDesc = getType(typeName, package) process_types([typeDesc], package) klass = typeDesc['klass'] # get the meta type of the FTI from the class, use the default FTI as # default fti_meta_type = getattr(klass, '_at_fti_meta_type', None) if fti_meta_type in (None, 'simple item'): fti_meta_type = FactoryTypeInformation.meta_type typesTool.manage_addTypeInformation(fti_meta_type, id=typeName, typeinfo_name=typeinfo_name) t = getattr(typesTool, typeName, None) if t: t.title = getattr(klass, 'archetype_name', typeDesc['portal_type']) # and update the actions as needed fixActionsForType(klass, typesTool) if REQUEST: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/manage_debugForm') security.declarePublic('getSearchWidgets') def getSearchWidgets(self, package=None, type=None, context=None, nosort=None): """Empty widgets for searching. """ return self.getWidgets(package=package, type=type, context=context, mode='search', nosort=nosort) security.declarePublic('getWidgets') def getWidgets(self, instance=None, package=None, type=None, context=None, mode='edit', fields=None, schemata=None, nosort=None): """Empty widgets for standalone rendering. """ widgets = [] w_keys = {} context = context is not None and context or self instances = instance is not None and [instance] or [] f_names = fields if not instances: for t in self.listTypes(package, type): instance = t('fake_instance') instance._at_is_fake_instance = True wrapped = instance.__of__(context) wrapped.initializeArchetype() instances.append(wrapped) for instance in instances: if schemata is not None: schema = instance.Schemata()[schemata].copy() else: schema = instance.Schema().copy() fields = schema.fields() if mode == 'search': # Include only fields which have an index # XXX duplicate fieldnames may break this, # as different widgets with the same name # on different schemas means only the first # one found will be used indexes = self.portal_catalog.indexes() fields = [f for f in fields if (f.accessor and not f.accessor in w_keys and f.accessor in indexes)] if f_names is not None: fields = filter(lambda f: f.getName() in f_names, fields) for field in fields: widget = field.widget field_name = field.getName() accessor = field.getAccessor(instance) if mode == 'search': field.required = False field.addable = False # for ReferenceField if not isinstance(field.vocabulary, DisplayList): field.vocabulary = field.Vocabulary(instance) if '' not in field.vocabulary.keys(): field.vocabulary = DisplayList([('', _(u'at_search_any', default=u'<any>'))]) + \ field.vocabulary widget.populate = False field_name = field.accessor # accessor must be a method which doesn't take an argument # this lambda is facking an accessor accessor = lambda: field.getDefault(instance) w_keys[field_name] = None widgets.append((field_name, WidgetWrapper( field_name=field_name, mode=mode, widget=widget, instance=instance, field=field, accessor=accessor))) if mode == 'search' and nosort == None: widgets.sort() return [widget for name, widget in widgets] security.declarePrivate('_rawEnum') 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())) security.declareProtected(permissions.View, 'enum') 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) security.declareProtected(permissions.View, 'Content') def Content(self): """Return a list of all the content ids. """ catalog = getToolByName(self, UID_CATALOG) keys = catalog.uniqueValuesFor('UID') results = catalog(dict(UID=keys)) return results # Management Forms security.declareProtected(permissions.ManagePortal, 'manage_doGenerate') def manage_doGenerate(self, sids=(), REQUEST=None): """(Re)generate types. """ schemas = [] for sid in sids: schemas.append(self.getSchema(sid)) for s in schemas: s.generate() if REQUEST: return REQUEST.RESPONSE.redirect(self.absolute_url() + '/manage_workspace') security.declareProtected(permissions.ManagePortal, 'manage_inspect') 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') security.declareProtected(permissions.ManagePortal, 'manage_reindex') def manage_reindex(self, REQUEST=None): """Assign UIDs to all basecontent objects. """ def _index(object, archetype_tool): archetype_tool.registerContent(object) self._rawEnum(_index, self) return REQUEST.RESPONSE.redirect(self.absolute_url() + '/manage_uids') security.declareProtected(permissions.ManagePortal, 'index') index = manage_reindex def _listAllTypes(self): """List all types -- either currently known or known to us. """ allTypes = _types.copy() allTypes.update(self._types) return allTypes.keys() security.declareProtected(permissions.ManagePortal, 'getChangedSchema') def getChangedSchema(self): """Returns a list of tuples indicating which schema have changed. Tuples have the form (schema, changed). """ list = [] currentTypes = _types ourTypes = self._types modified = False keys = self._listAllTypes() keys.sort() for t in keys: if t not in ourTypes: # Add it ourTypes[t] = currentTypes[t]['signature'] modified = True list.append((t, 0)) elif t not in currentTypes: # Huh: what shall we do? We remove it -- this might be wrong! del ourTypes[t] modified = True # We do not add an entry because we cannot update # these objects (having no longer type information for them) else: list.append((t, ourTypes[t] != currentTypes[t]['signature'])) if modified: self._p_changed = True return list security.declareProtected(permissions.ManagePortal, 'manage_updateSchema') def manage_updateSchema(self, REQUEST=None, update_all=None, remove_instance_schemas=None): """Make sure all objects' schema are up to date. """ out = StringIO() print >> out, 'Updating schema...' update_types = [] if REQUEST is None: # DM (avoid persistency bug): avoid code duplication update_types = [ti[0] for ti in self.getChangedSchema() if ti[1]] else: # DM (avoid persistency bug): for t in self._listAllTypes(): if REQUEST.form.get(t, False): update_types.append(t) update_all = REQUEST.form.get('update_all', False) remove_instance_schemas = REQUEST.form.get( 'remove_instance_schemas', False) # XXX: Enter this block only when there are types to update! if update_types: # Use the catalog's ZopeFindAndApply method to walk through # all objects in the portal. This works much better than # relying on the catalog to find objects, because an object # may be uncatalogable because of its schema, and then you # can't update it if you require that it be in the catalog. catalog = getToolByName(self, 'portal_catalog') portal = getToolByName(self, 'portal_url').getPortalObject() meta_types = [_types[t]['meta_type'] for t in update_types] if remove_instance_schemas: func_update_changed = self._removeSchemaAndUpdateChangedObject func_update_all = self._removeSchemaAndUpdateObject else: func_update_changed = self._updateChangedObject func_update_all = self._updateObject if update_all: catalog.ZopeFindAndApply(portal, obj_metatypes=meta_types, search_sub=True, apply_func=func_update_all) else: catalog.ZopeFindAndApply(portal, obj_metatypes=meta_types, search_sub=True, apply_func=func_update_changed) for t in update_types: self._types[t] = _types[t]['signature'] self._p_changed = True print >> out, 'Done.' return out.getvalue() # A counter to ensure that in a given interval a subtransaction # commit is done. subtransactioncounter = 0 def _updateObject(self, o, path, remove_instance_schemas=None): o._updateSchema(remove_instance_schemas=remove_instance_schemas) # Subtransactions to avoid eating up RAM when used inside a # 'ZopeFindAndApply' like in manage_updateSchema self.subtransactioncounter += 1 # Only every 250 objects a sub-commit, otherwise it eats up all # diskspace if not self.subtransactioncounter % 250: transaction.savepoint(optimistic=True) def _updateChangedObject(self, o, path): if not o._isSchemaCurrent(): self._updateObject(o, path) def _removeSchemaAndUpdateObject(self, o, path): self._updateObject(o, path, remove_instance_schemas=True) def _removeSchemaAndUpdateChangedObject(self, o, path): if not o._isSchemaCurrent(): self._removeSchemaAndUpdateObject(o, path) security.declareProtected(permissions.ManagePortal, 'manage_updateSchema') def manage_migrate(self, REQUEST=None): """Run Extensions.migrations.migrate. """ from Products.Archetypes.Extensions.migrations import migrate out = migrate(self) self.manage_updateSchema() return out # Catalog management security.declareProtected(permissions.View, 'listCatalogs') def listCatalogs(self): """Show the catalog mapping. """ return self.catalog_map security.declareProtected(permissions.ManagePortal, 'manage_updateCatalogs') def manage_updateCatalogs(self, REQUEST=None): """Set the catalog map for meta_type to include the list catalog_names. """ prefix = 'catalog_names_' for key in REQUEST.form.keys(): if key.startswith(prefix): k = key[len(prefix):] v = REQUEST.form.get(key) self.setCatalogsByType(k, v) return REQUEST.RESPONSE.redirect(self.absolute_url() + '/manage_catalogs') security.declareProtected(permissions.ManagePortal, 'setCatalogsByType') def setCatalogsByType(self, portal_type, catalogList): """ associate catalogList with meta_type. (unfortunally not portal_type). catalogList is a list of strings with the ids of the catalogs. Each catalog is has to be a tool, means unique in site root. """ self.catalog_map[portal_type] = catalogList security.declareProtected(permissions.View, 'getCatalogsByType') 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 return catalogs
class MembershipTool(UniqueObject, Folder): """ This tool accesses member data through an acl_users object. It can be replaced with something that accesses member data in a different way. """ implements(IMembershipTool) id = 'portal_membership' meta_type = 'CMF Membership Tool' memberareaCreationFlag = 1 security = ClassSecurityInfo() manage_options = ( ({'label': 'Configuration', 'action': 'manage_mapRoles'}, {'label': 'Overview', 'action': 'manage_overview'}) + Folder.manage_options) # # ZMI methods # security.declareProtected(ManagePortal, 'manage_overview') manage_overview = DTMLFile('explainMembershipTool', _dtmldir) # # 'portal_membership' interface methods # security.declareProtected(ManagePortal, 'manage_mapRoles') manage_mapRoles = DTMLFile('membershipRolemapping', _dtmldir) security.declareProtected(SetOwnPassword, 'setPassword') @postonly def setPassword(self, password, domains=None, REQUEST=None): '''Allows the authenticated member to set his/her own password. ''' if not self.isAnonymousUser(): member = self.getAuthenticatedMember() rtool = queryUtility(IRegistrationTool) if rtool is not None: failMessage = rtool.testPasswordValidity(password) if failMessage is not None: raise BadRequest(failMessage) member.setSecurityProfile(password=password, domains=domains) else: raise BadRequest('Not logged in.') security.declarePublic('getAuthenticatedMember') def getAuthenticatedMember(self): ''' Returns the currently authenticated member object or the Anonymous User. Never returns None. ''' u = getSecurityManager().getUser() if u is None: u = nobody return self.wrapUser(u) security.declarePrivate('wrapUser') def wrapUser(self, u, wrap_anon=0): """ Set up the correct acquisition wrappers for a user object. Provides an opportunity for a portal_memberdata tool to retrieve and store member data independently of the user object. """ b = getattr(u, 'aq_base', None) if b is None: # u isn't wrapped at all. Wrap it in self.acl_users. b = u u = u.__of__(self.acl_users) if (b is nobody and not wrap_anon) or hasattr(b, 'getMemberId'): # This user is either not recognized by acl_users or it is # already registered with something that implements the # member data tool at least partially. return u # Apply any role mapping if we have it if hasattr(self, 'role_map'): for portal_role in self.role_map.keys(): if (self.role_map.get(portal_role) in u.roles and portal_role not in u.roles): u.roles.append(portal_role) mdtool = queryUtility(IMemberDataTool) if mdtool is not None: try: u = mdtool.wrapUser(u) except ConflictError: raise except: logger.exception("Error during wrapUser") return u security.declareProtected(ManagePortal, 'getPortalRoles') def getPortalRoles(self): """ Return all local roles defined by the portal itself, which means roles that are useful and understood by the portal object """ parent = self.aq_inner.aq_parent roles = list(parent.userdefined_roles()) # This is *not* a local role in the portal but used by it roles.append('Manager') roles.append('Owner') return roles security.declareProtected(ManagePortal, 'setRoleMapping') @postonly def setRoleMapping(self, portal_role, userfolder_role, REQUEST=None): """ set the mapping of roles between roles understood by the portal and roles coming from outside user sources """ if not hasattr(self, 'role_map'): self.role_map = PersistentMapping() if len(userfolder_role) < 1: del self.role_map[portal_role] else: self.role_map[portal_role] = userfolder_role return MessageDialog( title='Mapping updated', message='The Role mappings have been updated', action='manage_mapRoles') security.declareProtected(ManagePortal, 'getMappedRole') def getMappedRole(self, portal_role): """ returns a role name if the portal role is mapped to something else or an empty string if it is not """ if hasattr(self, 'role_map'): return self.role_map.get(portal_role, '') else: return '' security.declarePublic('getMembersFolder') def getMembersFolder(self): """ Get the members folder object. """ parent = aq_parent(aq_inner(self)) members_folder = getattr(parent, 'Members', None) if members_folder is None: return None request_container = RequestContainer(REQUEST=getRequest()) return members_folder.__of__(request_container) security.declareProtected(ManagePortal, 'getMemberareaCreationFlag') def getMemberareaCreationFlag(self): """ Returns the flag indicating whether the membership tool will create a member area if an authenticated user from an underlying user folder logs in first without going through the join process """ return self.memberareaCreationFlag security.declareProtected(ManagePortal, 'setMemberareaCreationFlag') def setMemberareaCreationFlag(self): """ sets the flag indicating whether the membership tool will create a member area if an authenticated user from an underlying user folder logs in first without going through the join process """ if not hasattr(self, 'memberareaCreationFlag'): self.memberareaCreationFlag = 0 if self.memberareaCreationFlag == 0: self.memberareaCreationFlag = 1 else: self.memberareaCreationFlag = 0 return MessageDialog( title='Member area creation flag changed', message='Member area creation flag has been updated', action='manage_mapRoles') security.declarePublic('createMemberArea') def createMemberArea(self, member_id=''): """ Create a member area for 'member_id' or authenticated user. """ if not self.getMemberareaCreationFlag(): return None members = self.getMembersFolder() if members is None: return None if self.isAnonymousUser(): return None if member_id: if not self.isMemberAccessAllowed(member_id): return None member = self.getMemberById(member_id) if member is None: return None else: member = self.getAuthenticatedMember() member_id = member.getId() if hasattr(aq_base(members), member_id): return None else: f_title = "%s's Home" % member_id members.manage_addPortalFolder(id=member_id, title=f_title) f = getattr(members, member_id) f.manage_permission(View, ['Owner', 'Manager', 'Reviewer'], 0) f.manage_permission(AccessContentsInformation, ['Owner', 'Manager', 'Reviewer'], 0) # Grant Ownership and Owner role to Member f.changeOwnership(member) f.__ac_local_roles__ = None f.manage_setLocalRoles(member_id, ['Owner']) return f security.declarePublic('createMemberarea') createMemberarea = createMemberArea security.declareProtected(ManageUsers, 'deleteMemberArea') @postonly def deleteMemberArea(self, member_id, REQUEST=None): """ Delete member area of member specified by member_id. """ members = self.getMembersFolder() if not members: return 0 if hasattr(aq_base(members), member_id): members.manage_delObjects(member_id) return 1 else: return 0 security.declarePublic('isAnonymousUser') def isAnonymousUser(self): ''' Returns 1 if the user is not logged in. ''' u = getSecurityManager().getUser() if u is None or u.getUserName() == 'Anonymous User': return 1 return 0 security.declarePublic('checkPermission') def checkPermission(self, permissionName, object, subobjectName=None): ''' Checks whether the current user has the given permission on the given object or subobject. ''' if subobjectName is not None: object = getattr(object, subobjectName) return _checkPermission(permissionName, object) security.declareProtected(ManageUsers, 'isMemberAccessAllowed') def isMemberAccessAllowed(self, member_id): """Check if the authenticated user is this member or an user manager. """ sm = getSecurityManager() user = sm.getUser() if user is None: return False if member_id == user.getId(): return True return sm.checkPermission(ManageUsers, self) security.declarePublic('credentialsChanged') def credentialsChanged(self, password, REQUEST=None): ''' Notifies the authentication mechanism that this user has changed passwords. This can be used to update the authentication cookie. Note that this call should *not* cause any change at all to user databases. ''' if not self.isAnonymousUser(): user = getSecurityManager().getUser() name = user.getUserName() # this really does need to be the user name, and not the user id, # because we're dealing with authentication credentials cctool = queryUtility(ICookieCrumbler) if cctool is not None: cctool.credentialsChanged(user, name, password, REQUEST) security.declareProtected(ManageUsers, 'getMemberById') def getMemberById(self, id): ''' Returns the given member. ''' user = self._huntUser(id, self) if user is not None: user = self.wrapUser(user) return user def _huntUserFolder(self, member_id, context): """Find userfolder containing user in the hierarchy starting from context """ uf = context.acl_users while uf is not None: user = uf.getUserById(member_id) if user is not None: return uf container = aq_parent(aq_inner(uf)) parent = aq_parent(aq_inner(container)) uf = getattr(parent, 'acl_users', None) return None def _huntUser(self, member_id, context): """Find user in the hierarchy of userfolders starting from context """ uf = self._huntUserFolder(member_id, context) if uf is not None: return uf.getUserById(member_id).__of__(uf) def __getPUS(self): """ Retrieve the nearest user folder """ warn('__getPUS is deprecated and will be removed in CMF 2.4, ' 'please acquire "acl_users" instead.', DeprecationWarning, stacklevel=2) return self.acl_users security.declareProtected(ManageUsers, 'listMemberIds') def listMemberIds(self): '''Lists the ids of all members. This may eventually be replaced with a set of methods for querying pieces of the list rather than the entire list at once. ''' user_folder = self.acl_users return [ x.getId() for x in user_folder.getUsers() ] security.declareProtected(ManageUsers, 'listMembers') def listMembers(self): '''Gets the list of all members. ''' return map(self.wrapUser, self.acl_users.getUsers()) security.declareProtected(ListPortalMembers, 'searchMembers') def searchMembers(self, search_param, search_term): """ Search the membership """ mdtool = queryUtility(IMemberDataTool) if mdtool is not None: return mdtool.searchMemberData(search_param, search_term) return None security.declareProtected(View, 'getCandidateLocalRoles') def getCandidateLocalRoles(self, obj): """ What local roles can I assign? """ member = self.getAuthenticatedMember() member_roles = member.getRolesInContext(obj) if _checkPermission(ManageUsers, obj): local_roles = self.getPortalRoles() if 'Manager' not in member_roles: local_roles.remove('Manager') else: local_roles = [ role for role in member_roles if role not in ('Member', 'Authenticated') ] local_roles.sort() return tuple(local_roles) security.declareProtected(View, 'setLocalRoles') @postonly def setLocalRoles(self, obj, member_ids, member_role, reindex=1, REQUEST=None): """ Add local roles on an item. """ if (_checkPermission(ChangeLocalRoles, obj) and member_role in self.getCandidateLocalRoles(obj)): for member_id in member_ids: roles = list(obj.get_local_roles_for_userid(userid=member_id)) if member_role not in roles: roles.append(member_role) obj.manage_setLocalRoles(member_id, roles) if reindex and hasattr(aq_base(obj), 'reindexObjectSecurity'): obj.reindexObjectSecurity() security.declareProtected(View, 'deleteLocalRoles') @postonly def deleteLocalRoles(self, obj, member_ids, reindex=1, recursive=0, REQUEST=None): """ Delete local roles of specified members. """ if _checkPermission(ChangeLocalRoles, obj): for member_id in member_ids: if obj.get_local_roles_for_userid(userid=member_id): obj.manage_delLocalRoles(userids=member_ids) break if recursive and hasattr(aq_base(obj), 'contentValues'): for subobj in obj.contentValues(): self.deleteLocalRoles(subobj, member_ids, 0, 1) if reindex and hasattr(aq_base(obj), 'reindexObjectSecurity'): # reindexObjectSecurity is always recursive obj.reindexObjectSecurity() security.declarePrivate('addMember') def addMember(self, id, password, roles, domains, properties=None): '''Adds a new member to the user folder. Security checks will have already been performed. Called by portal_registration. ''' self.acl_users._doAddUser(id, password, roles, domains) if properties is not None: member = self.getMemberById(id) member.setMemberProperties(properties) security.declareProtected(ManageUsers, 'deleteMembers') @postonly def deleteMembers(self, member_ids, delete_memberareas=1, delete_localroles=1, REQUEST=None): """ Delete members specified by member_ids. """ # Delete members in acl_users. acl_users = self.acl_users if _checkPermission(ManageUsers, acl_users): if isinstance(member_ids, basestring): member_ids = (member_ids,) member_ids = list(member_ids) for member_id in member_ids[:]: if not acl_users.getUserById(member_id, None): member_ids.remove(member_id) try: acl_users.userFolderDelUsers(member_ids) except (AttributeError, NotImplementedError): raise NotImplementedError('The underlying User Folder ' 'doesn\'t support deleting members.') else: raise AccessControl_Unauthorized('You need the \'Manage users\' ' 'permission for the underlying User Folder.') # Delete member data in portal_memberdata. mdtool = queryUtility(IMemberDataTool) if mdtool is not None: for member_id in member_ids: mdtool.deleteMemberData(member_id) # Delete members' home folders including all content items. if delete_memberareas: for member_id in member_ids: self.deleteMemberArea(member_id) # Delete members' local roles. if delete_localroles: self.deleteLocalRoles(getUtility(ISiteRoot), member_ids, reindex=1, recursive=1) return tuple(member_ids) security.declarePublic('getHomeFolder') def getHomeFolder(self, id=None, verifyPermission=0): """Returns a member's home folder object or None. Set verifyPermission to 1 to return None when the user doesn't have the View permission on the folder. """ return None security.declarePublic('getHomeUrl') def getHomeUrl(self, id=None, verifyPermission=0): """Returns the URL to a member's home folder or None. Set verifyPermission to 1 to return None when the user doesn't have the View permission on the folder. """ return None