@@ -0,0 +1,1413 @@
+%0Afrom functools import partial%0A%0A%0Aclass Chain(object):%0A%0A    def __init__(self, dg, inprogress, added):%0A        self.dg = dg%0A        self.inprogress%0A        self.added = added%0A        self.rules = %5B%5D%0A%0A    def add_rule(self, rule):%0A        self.rules.append(rule)%0A%0A    @property%0A    def filtered(self):%0A        for item in self.added:%0A            for rule in self.rules:%0A                if not rule(self.dg, self.inprogress, item):%0A                    break%0A            else:%0A                yield item%0A%0A    def __iter__(self):%0A        return iter(self.filtered)%0A%0A%0Adef get_default_chain(dg, inprogress, added):%0A    chain = Chain(dg, inprogress, added)%0A    chain.add_rule(items_rule)%0A    chain.add_rule(target_based_rule)%0A    chain.add_rule(type_based_rule)%0A    return chain%0A%0A%0Adef type_based_rule(dg, inprogress, item):%0A    %22%22%22condition will be specified like:%0A        type_limit: 2%0A    %22%22%22%0A    _type = item%5B'resource_type'%5D%0A    type_count = 0%0A    for n in inprogress:%0A        if dg.node%5Bn%5D.get('resource_type') == _type:%0A            type_count += 1%0A    return item%5B'type_limit'%5D %3E type_count%0A%0A%0Adef target_based_rule(dg, inprogress, item, limit=1):%0A    target = item%5B'target'%5D%0A    target_count = 0%0A    for n in inprogress:%0A        if dg.node%5Bn%5D.get('target') == target:%0A            target_count += 1%0A    return limit %3E target_count%0A%0A%0Adef items_rule(dg, inprogress, item, limit=10):%0A    return len(inprogress) %3C limit%0A

Add chain and rules for specifying limits