""" ldaputil.modlist2 - create modify modlist's with schema knowledge (c) by Michael Stroeder $Id: modlist2.py,v 1.3 2004/06/30 07:13:19 michael Exp $ """ __version__ = '0.2.0' import ldap def list_dict(l): """ return a dictionary with all items of l being the keys of the dictionary """ d = {} for i in l: d[i]=None return d def modifyModlist( sub_schema,old_entry,new_entry,ignore_attr_types=None,ignore_oldexistent=0 ): """ Build differential modify list for calling LDAPObject.modify()/modify_s() sub_schema Instance of ldap.schema.subentry.SubSchema old_entry Dictionary holding the old entry new_entry Dictionary holding what the new entry should be ignore_attr_types List of attribute type names to be ignored completely ignore_oldexistent If non-zero attribute type names which are in old_entry but are not found in new_entry at all are not deleted. This is handy for situations where your application sets attribute value to '' for deleting an attribute. In most cases leave zero. """ # Type checking assert isinstance(sub_schema,ldap.schema.subentry.SubSchema) assert isinstance(old_entry,ldap.schema.models.Entry) assert isinstance(new_entry,ldap.schema.models.Entry) # Performance optimization AttributeType = ldap.schema.AttributeType # Build a dictionary with key of all attribute types to be ignored ignore_attr_types = list_dict([ sub_schema.getoid(AttributeType,attr_type) for attr_type in (ignore_attr_types or []) ]) # Start building the modlist result modlist = [] # Sanitize new_entry for a in new_entry.keys(): # Filter away list items which are empty strings or None new_entry[a] = filter(None,new_entry[a]) # Check for attributes with empty value lists if not new_entry[a]: # Remove the empty attribute del new_entry[a] for attrtype in new_entry.keys(): if ignore_attr_types.has_key(sub_schema.getoid(AttributeType,attrtype)): # This attribute type is ignored continue # Filter away list items which are empty strings or None new_value = new_entry[attrtype] old_value = filter(None,old_entry.get(attrtype,[])) # We have to check if attribute value lists differs old_value_dict=list_dict(old_value) new_value_dict=list_dict(new_value) delete_values = 0 for v in old_value: if not new_value_dict.has_key(v): delete_values = 1 break if delete_values: modlist.append((ldap.MOD_DELETE,attrtype,None)) modlist.append((ldap.MOD_ADD,attrtype,new_value)) else: add_values = [] for v in new_value: if not old_value_dict.has_key(v): add_values.append(v) if add_values: modlist.append((ldap.MOD_ADD,attrtype,add_values)) # Remove all attributes of old_entry which are not present # in new_entry at all if not ignore_oldexistent: for attrtype in old_entry.keys(): if not new_entry.has_key(attrtype) and \ not ignore_attr_types.has_key(sub_schema.getoid(AttributeType,attrtype)): modlist.append((ldap.MOD_DELETE,attrtype,None)) return modlist # modifyModlist()