Mercurial > p > roundup > code
diff roundup/backends/back_anydbm.py @ 4466:f1fe6fd0aa61
Multilinks can be filtered by combining elements with AND, OR and NOT now.
A javascript gui was added for "keywords", see issue2550648.
Developed by Sascha Teichmann; funded by Intevation. (Bernhard Reiter)
| author | Bernhard Reiter <Bernhard.Reiter@intevation.de> |
|---|---|
| date | Mon, 08 Nov 2010 16:21:02 +0000 |
| parents | 9d37875416c3 |
| children | 1613754d2646 |
line wrap: on
line diff
--- a/roundup/backends/back_anydbm.py Fri Nov 05 13:17:18 2010 +0000 +++ b/roundup/backends/back_anydbm.py Mon Nov 08 16:21:02 2010 +0000 @@ -49,6 +49,87 @@ def db_nuke(config): shutil.rmtree(config.DATABASE) +class Binary: + + def __init__(self, x, y): + self.x = x + self.y = y + + def visit(self, visitor): + self.x.visit(visitor) + self.y.visit(visitor) + +class Unary: + + def __init__(self, x): + self.x = x + + def generate(self, atom): + return atom(self) + + def visit(self, visitor): + self.x.visit(visitor) + +class Equals(Unary): + + def evaluate(self, v): + return self.x in v + + def visit(self, visitor): + visitor(self) + +class Not(Unary): + + def evaluate(self, v): + return not self.x.evaluate(v) + + def generate(self, atom): + return "NOT(%s)" % self.x.generate(atom) + +class Or(Binary): + + def evaluate(self, v): + return self.x.evaluate(v) or self.y.evaluate(v) + + def generate(self, atom): + return "(%s)OR(%s)" % ( + self.x.generate(atom), + self.y.generate(atom)) + +class And(Binary): + + def evaluate(self, v): + return self.x.evaluate(v) and self.y.evaluate(v) + + def generate(self, atom): + return "(%s)AND(%s)" % ( + self.x.generate(atom), + self.y.generate(atom)) + +def compile_expression(opcodes): + + stack = [] + push, pop = stack.append, stack.pop + for opcode in opcodes: + if opcode == -2: push(Not(pop())) + elif opcode == -3: push(And(pop(), pop())) + elif opcode == -4: push(Or(pop(), pop())) + else: push(Equals(opcode)) + + return pop() + +class Expression: + + def __init__(self, v): + try: + opcodes = [int(x) for x in v] + if min(opcodes) >= -1: raise ValueError() + + compiled = compile_expression(opcodes) + self.evaluate = lambda x: compiled.evaluate([int(y) for y in x]) + except: + self.evaluate = lambda x: bool(set(x) & set(v)) + # # Now the database # @@ -1702,12 +1783,10 @@ if not v: match = not nv else: - # othewise, make sure this node has each of the + # otherwise, make sure this node has each of the # required values - for want in v: - if want in nv: - match = 1 - break + expr = Expression(v) + if expr.evaluate(nv): match = 1 elif t == STRING: if nv is None: nv = ''
