# BridgeDB by Nick Mathewson.
# Copyright (c) 2007-2012, The Tor Project, Inc.
# See LICENSE for licensing information 

from ipaddr import IPv6Address, IPv4Address

funcs = {}

def filterAssignBridgesToRing(hmac, numRings, assignedRing):
    ruleset = frozenset([hmac, numRings, assignedRing]) 
    try: 
        return funcs[ruleset]
    except KeyError:
        def f(bridge):
            digest = hmac(bridge.getID())
            pos = long( digest[:8], 16 )
            which = pos % numRings
            if which == assignedRing: return True
            return False
        f.__name__ = "filterAssignBridgesToRing(%s, %s, %s)" % (hmac, numRings,
                                                                 assignedRing)
        funcs[ruleset] = f
        return f

def filterBridgesByRules(rules):
    ruleset = frozenset(rules)
    try: 
        return funcs[ruleset] 
    except KeyError:
        def g(x):
            r = [f(x) for f in rules]
            if False in r: return False
            return True
        funcs[ruleset] = g
        return g  

def filterBridgesByIP4(bridge):
    try:
        if IPv4Address(bridge.ip): return True
    except ValueError:
        pass

    for k in bridge.or_addresses.keys():
        if type(k) is IPv4Address:
            return True
    return False

def filterBridgesByIP6(bridge):
    try:
        if IPv6Address(bridge.ip): return True
    except ValueError:
        pass

    for k in bridge.or_addresses.keys():
        if type(k) is IPv6Address:
            return True
    return False

def filterBridgesByOnlyIP4(bridge):
    for k in bridge.or_addresses.keys():
        if type(k) is IPv6Address:
            return False
    if type(k) is IPv4Address:
        return True
    return False

def filterBridgesByOnlyIP6(bridge):
    for k in bridge.or_addresses.keys():
        if type(k) is IPv4Address:
            return False
    if type(k) is IPv6Address:
        return True
    return False

@@ -725,16 +725,76 @@
 edRing)%0A
+        setattr(f, %22description%22, %22ring=%25d%22 %25 assignedRing)%0A
         
@@ -812,16 +812,16 @@
 et%5D = f%0A
-
         
@@ -1068,32 +1068,122 @@
     return True%0A
+        setattr(g, %22description%22, %22 %22.join(%5Bgetattr(f,'description','') for f in rules%5D))%0A
         funcs%5Bru
@@ -1446,32 +1446,83 @@
     return False
+%0Asetattr(filterBridgesByIP4, %22description%22, %22ip=4%22)
 %0A%0Adef filterBrid
@@ -1724,32 +1724,32 @@
     return True%0A
-
     return False
@@ -1740,32 +1740,83 @@
     return False
+%0Asetattr(filterBridgesByIP6, %22description%22, %22ip=6%22)
 %0A%0Adef filterBrid

5935 - Add descriptions to filters