class map_http_methods_to_model(Aspect): """map GET/POST/PUT/DELETE to node methods """ model = aspect.aspectkw(model=None) def GET(self, url, **kw): id, node = self.traverse(url) if url.endswith('/'): criteria = kw['query'].get('criteria') base_criteria = kw['query'].get('base_criteria') if criteria or base_criteria: node = filter_search(node, criteria=criteria, base_criteria=base_criteria) return node.iteritems() return node def POST(self, url, data, **kw): """Add a new child, must not exist already """ id, node = self.traverse(url) return node.add(data) def PUT(self, url, data, **kw): """Add/overwrite children - I guess """ id, node = self.traverse(url) try: node.update(data) except ValueError, e: raise exc.BadRequest(e.args[0])
class child_aspect(Aspect): child_aspect = aspect.aspectkw(child_aspect=None) @aspect.plumb def __getitem__(_next, self, key): child = _next(key) if self.child_aspect: # XXX: hack dn = child.dn directory = child.directory child = self.child_aspect(child) child.dn = dn child.directory = directory return child @aspect.plumb def search(_next, self, *args, **kw): for node in _next(*args, **kw): if self.child_aspect: # XXX: hack dn = node.dn directory = node.directory node = self.child_aspect(node) node.dn = dn node.directory = directory yield node
class filter_search(Aspect): criteria = aspect.aspectkw(criteria=None) base_criteria = aspect.aspectkw(base_criteria=None) def __iter__(self): return self.search(attrlist=['']) def itervalues(self): return self.search() def iteritems(self): return ((node.dn, node) for node in self.itervalues()) @aspect.plumb def search(_next, self, **kw): return _next(criteria=self.criteria, base_criteria=self.base_criteria, **kw)
class view(aspect.Aspect): """A view of an ldap directory """ scope = aspect.aspectkw(scope=ldap.SCOPE_SUBTREE) base_dn = aspect.aspectkw(None) filterstr = aspect.aspectkw(None) # dn_from_id = aspect.aspectkw(dn_from_id=None) # id_from_dn = aspect.aspectkw(id_from_dn=None) def __iter__(self): return self.search(attrlist=['']) def itervalues(self): return self.search() def iteritems(self): return ((node.dn, node) for node in self.itervalues()) @aspect.plumb def search(_next, self, attrlist=None, criteria=None, base_criteria=None, filterstr=None): if filterstr is not None: filterstr = '(&%s%s)' % (filterstr, self.filterstr) else: filterstr = self.filterstr return _next(base=self.base_dn, scope=self.scope, filterstr=filterstr, attrlist=attrlist, criteria=criteria, base_criteria=base_criteria)
class configure(Aspect): """Provide configuration Instantiates a model's classes on demand, supplying them config. This creates the read only part of a model. """ config = aspect.aspectkw(config=None) # XXX: needed for now as prototyping does not work as expected yet # XXX: might work also via inheritance def __getattr__(self, name): """Blend in children as attributes Children can be accessed via getattr, except if aliased by a real attribute. """ try: return self.__getitem__(name) except KeyError: raise AttributeError(name) @aspect.plumb def __getitem__(_next, self, key): node = _next(key) config = (self.config or dict()).get(key, dict()) if metachao.utils.isclass(node): # XXX: this destroys order node = node(**config) else: node = configure(node, config=config) return node def values(self): for k in self.keys(): yield self[k]
class children_attribute_name_mapping(attribute_name_mapping_base): attribute_name_map = aspect.aspectkw(None) @aspect.plumb def add(_next, self, attributes): attributes = OrderedDict((self.incoming_attribute_map.get(k, k), v) for k, v in attributes.items()) return _next(attributes) # @aspect.plumb # def __getitem__(_next, self, key): # node = _next(key) # if self.attribute_name_map: # dn = node.dn # id = node._id # node = attribute_name_mapping( # node, # attribute_name_map=self.attribute_name_map, # ) # node.dn = dn # node._id = id # return node @aspect.plumb def search(_next, self, criteria=None, base_criteria=None, **kw): if criteria is not None: criteria = [ dict((self.incoming_attribute_map.get(k, k), v) for k, v in crit.items()) for crit in criteria ] if base_criteria is not None: base_criteria = [ dict((self.incoming_attribute_map.get(k, k), v) for k, v in crit.items()) for crit in base_criteria ] return _next(criteria=criteria, base_criteria=base_criteria, **kw)