import logging class NotRegistered(Exception): pass class NotAvailable(Exception): pass class ObjectHandler(object): def __init__(self,model,schemas): self.model = model self.schemas = schemas def serialize(self,o): d = {'meta': {},'schemas':[]} for schema in self.schemas: if schema.URI == 'urn:scim:schemas:core:1.0': d.update(self.as_dict(schema,o)) else: d.update({schema.URI: self.as_dict(schema,o)}) d['schemas'].append(schema.URI) return d def create(self,d): for schema in self.schemas: if schema.URI in d['schemas']: data = d if schema.URI != 'urn:scim:schemas:core:1.0': data = d[schema.URI] try: return schema.create(self.model,data) except NotAvailable: pass raise NotAvailable("No way to create this object") def as_dict(self,schema,o): d = dict([(a,schema.__class__.__dict__[a].__get__(o)) for a in schema.ATTRIBUTES]) logging.debug(d) return d def update(self,o,d,replace=False): meta_attributes = d['meta'].get('attributes',{}) for schema in self.schemas: if schema in d['schemas']: data = d if schema.URI != 'urn:scim:schemas:core:1.0': data = d[schema] for a in schema.ATTRIBUTES: v = data[a] t = type(v) p = getattr(schema,a) if a in meta_attributes: if not data.has_key(a): p.__delete__(o) else: p.__set__(o,v) ## replace else: #add / remove if t is dict: #merge p.__set__(o,p.__get__(o).update(v)) elif (t is list or t is tuple) and not t is str: for i in v: if type(i) is dict: if i.get('operation',None) == 'delete': p.remove(o,i) else: p.update(o,i) else: # no nested lists p.add(o,i) else: p.__set__(o,v) # simple type class ObjectTypeRegistry(object): def __init__(self): self._registry = {} def register(self,model,prefix,schemas): if prefix == None: prefix = "%ss" % model.__name__ #for schema in schemas: # for attr in schema.ATTRIBUTES: # setattr(model,attr,schema.__dict__['externalId']) self._registry[prefix] = ObjectHandler(model,schemas) types = ObjectTypeRegistry() def register(model,prefix,schemas): return types.register(model, prefix, schemas)