[tor-commits] [bridgedb/develop] Deprecate old bridgedb.Bridges.Bridge class.

isis at torproject.org isis at torproject.org
Thu Feb 19 02:21:12 UTC 2015


commit 07f01e9df28b35433ca7b6891855ab64c3fa402e
Author: Isis Lovecruft <isis at torproject.org>
Date:   Tue Nov 4 22:23:42 2014 +0000

    Deprecate old bridgedb.Bridges.Bridge class.
---
 lib/bridgedb/Bridges.py         |  252 --------------------------------------
 lib/bridgedb/test/deprecated.py |  256 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 256 insertions(+), 252 deletions(-)

diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py
index dead9f2..36637aa 100644
--- a/lib/bridgedb/Bridges.py
+++ b/lib/bridgedb/Bridges.py
@@ -75,258 +75,6 @@ def is_valid_ip(ip):
     return True
 
 
-class Bridge(object):
-    """Holds information for a single bridge, along with any Pluggable
-    Transports it is also running.
-
-    :attr str nickname: The bridge's nickname.  Not currently used.
-    :attr ip: (:class:`ipaddr.IPAddress`) The bridge's IPv4 address, specified
-        on the 'r'-line in a networkstatus document.
-    :attr int orport: The bridge's OR port.
-    :attr dict or_addresses: The bridges alternate IP addresses. The keys
-        should be instances of ``ipaddr.IPAddress``, and the value should be a
-        :class:`bridgedb.parse.addr.PortList` for the port(s) on which that
-        address is listening.
-    :attr list transports: List of :class:`PluggableTransport` instances for
-        each PT which the bridge supports.
-    :attr str fingerprint: The bridge's identity digest, in lowercase hex,
-        without whitespace.
-    :attr bool running: ``True``, if this bridge was given the ``Running`` flag.
-    :attr bool stable: ``True``, if this bridge was given the ``Stable`` flag.
-    :attr dict blockingCountries: A dictionary whose keys are strings of
-        ``"IP:port"`` pairs, and the keys are lists of two letter country
-        codes which block that IP:port. For example::
-            {"1.2.3.4:9001": ['sk', 'us', 'ir', 'cn']}
-    :attr str desc_digest: SHA1 hexdigest of the bridge's descriptor as
-        defined in the networkstatus document.
-    :attr str ei_digest: SHA1 hexdigest of the bridge's extra-info document as
-        given in the bridge's descriptor, corresponding to desc_digest.
-    :attr bool verified: Did we receive the descriptor for this bridge that
-        was specified in the networkstatus?
-    """
-    def __init__(self, nickname, ip, orport, fingerprint=None, id_digest=None,
-                 or_addresses=None, transports=None):
-        """Create a new Bridge. One of fingerprint and id_digest must be set.
-        """
-        self.nickname = nickname
-        self.ip = ip
-        self.orport = orport
-        if not or_addresses: or_addresses = {}
-        self.or_addresses = or_addresses
-        if not transports: transports = []
-        self.transports = transports
-        self.running = self.stable = None
-        self.blockingCountries = {}
-        self.desc_digest = None
-        self.ei_digest = None
-        self.verified = False
-
-        if id_digest is not None:
-            assert fingerprint is None
-            if len(id_digest) != DIGEST_LEN:
-                raise TypeError("Bridge with invalid ID")
-            self.fingerprint = toHex(id_digest)
-        elif fingerprint is not None:
-            if not isValidFingerprint(fingerprint):
-                raise TypeError("Bridge with invalid fingerprint (%r)"%
-                                fingerprint)
-            self.fingerprint = fingerprint.lower()
-        else:
-            raise TypeError("Bridge with no ID")
-
-    def setDescriptorDigest(self, digest):
-        """Set the descriptor digest, specified in the NS."""
-        self.desc_digest = digest
-
-    def setExtraInfoDigest(self, digest):
-        """Set the extra-info digest, specified in the descriptor."""
-        self.ei_digest = digest
-
-    def setVerified(self):
-        """Call when the bridge's descriptor is parsed"""
-        self.verified = True
-
-    def isVerified(self):
-        """Returns the truthiness of ``verified``"""
-        return self.verified
-
-    def getID(self):
-        """Return the bridge's identity digest."""
-        return fromHex(self.fingerprint)
-
-    def __repr__(self):
-        """Return a piece of python that evaluates to this bridge."""
-        if self.or_addresses:
-            return "Bridge(%r,%r,%d,%r,or_addresses=%s)"%(
-                self.nickname, self.ip, self.orport, self.fingerprint,
-                self.or_addresses)
-        return "Bridge(%r,%r,%d,%r)"%(
-            self.nickname, self.ip, self.orport, self.fingerprint)
-
-    def getConfigLine(self, includeFingerprint=False, addressClass=None,
-            request=None, transport=None):
-        """Returns a valid bridge line for inclusion in a torrc.
-
-        :param bool includeFingerprint: If ``True``, include the
-            ``fingerprint`` of this :class:`Bridge` in the returned bridge
-            line.
-        :param DOCDOC addressClass: Type of address to choose.
-        :param str request: A string unique to this request e.g. email-address
-            or ``uniformMap(ip)`` or ``'default'``.
-        :param str transport: A pluggable transport method name.
-        """
-
-        if not request: request = 'default'
-        digest = getHMACFunc('Order-Or-Addresses')(request)
-        pos = long(digest[:8], 16) # lower 8 bytes -> long
-
-        # default address type
-        if not addressClass: addressClass = ipaddr.IPv4Address
-
-        # pluggable transports
-        if transport:
-            # filter by 'methodname'
-            transports = filter(lambda x: transport == x.methodname,
-                    self.transports)
-            # filter by 'addressClass' 
-            transports = filter(lambda x: isinstance(x.address, addressClass),
-                    transports)
-            if transports:
-                pt = transports[pos % len(transports)]
-                return pt.getTransportLine(includeFingerprint)
-
-        # filter addresses by address class
-        addresses = filter(lambda x: isinstance(x[0], addressClass),
-                self.or_addresses.items())
-
-        # default ip, orport should get a chance at being selected
-        if isinstance(self.ip, addressClass):
-            addresses.insert(0,(self.ip, addr.PortList(self.orport)))
-
-        if addresses:
-            address,portlist = addresses[pos % len(addresses)]
-            if isinstance(address, ipaddr.IPv6Address): ip = "[%s]"%address
-            else: ip = "%s"%address
-            orport = portlist[pos % len(portlist)]
-
-            if includeFingerprint:
-                return "%s:%d %s" % (ip, orport, self.fingerprint)
-            else:
-                return "%s:%d" % (ip, orport)
-
-    def getAllConfigLines(self,includeFingerprint=False):
-        """Generator. Iterate over all valid config lines for this bridge."""
-        for address,portlist in self.or_addresses.items():
-            if type(address) is ipaddr.IPv6Address:
-                ip = "[%s]" % address
-            else:
-                ip = "%s" % address
-
-            for orport in portlist:
-                if includeFingerprint:
-                    yield "bridge %s:%d %s" % (ip,orport,self.fingerprint)
-                else:
-                    yield "bridge %s:%d" % (ip,orport)
-        for pt in self.transports:
-            yield pt.getTransportLine(includeFingerprints)
-
-
-    def assertOK(self):
-        assert is_valid_ip(self.ip)
-        assert isValidFingerprint(self.fingerprint)
-        assert 1 <= self.orport <= 65535
-        if self.or_addresses:
-            for address, portlist in self.or_addresses.items():
-                assert is_valid_ip(address)
-                for port in portlist:
-                    assert type(port) is int
-                    assert 1 <= port <= 65535
-
-    def setStatus(self, running=None, stable=None):
-        if running is not None:
-            self.running = running
-        if stable is not None:
-            self.stable = stable
-
-    def isBlocked(self, countryCode, addressClass, methodname=None):
-        """ if at least one address:port of the selected addressClass and
-        (optional) transport type is not blocked in countryCode, return True
-        """
-        # 1) transport is specified
-        if methodname is not None:
-            for transport in self.transports:
-                key = "%s:%s" % (transport.address, transport.port)
-                if (isinstance(transport.address, addressClass)
-                        and transport.methodname.lower() == methodname.lower()):
-                    try:
-                        if countryCode not in self.blockingCountries[key]:
-                            return False
-                    except KeyError:
-                        return False # no blocklist
-            return True
-        # 2) no transport specified (default)
-        else:
-            # 3) check primary ip, port
-            # XXX: could be more elegant if ip,orport were not special case
-            if isinstance(self.ip, addressClass):
-                key = "%s:%s" % (self.ip, self.orport)
-                try:
-                    if countryCode not in self.blockingCountries[key]:
-                        return False
-                except KeyError: return False # no blocklist
-
-            # 4) check or addresses
-            for address,portlist in self.or_addresses.items():
-                if isinstance(address, addressClass):
-                    # check each port
-                    for port in portlist:
-                        key = "%s:%s" % (address, port)
-                        try:
-                            if countryCode not in self.blockingCountries[key]:
-                                return False
-                        except KeyError: return False # no blocklist
-            return True 
-
-    # Bridge Stability (#5482) properties.
-    @property
-    def familiar(self):
-        """
-        A bridge is 'familiar' if 1/8 of all active bridges have appeared
-        more recently than it, or if it has been around for a Weighted Time of 8 days.
-        """
-        with bridgedb.Storage.getDB() as db:
-            return db.getBridgeHistory(self.fingerprint).familiar
-
-    @property
-    def wfu(self):
-        """Weighted Fractional Uptime"""
-        with bridgedb.Storage.getDB() as db:
-            return db.getBridgeHistory(self.fingerprint).weightedFractionalUptime
-
-    @property
-    def weightedTime(self):
-        """Weighted Time"""
-        with bridgedb.Storage.getDB() as db:
-            return db.getBridgeHistory(self.fingerprint).weightedTime
-
-    @property
-    def wmtbac(self):
-        """Weighted Mean Time Between Address Change"""
-        with bridgedb.Storage.getDB() as db:
-            return db.getBridgeHistory(self.fingerprint).wmtbac
-
-    @property
-    def tosa(self):
-        """the Time On Same Address (TOSA)"""
-        with bridgedb.Storage.getDB() as db:
-            return db.getBridgeHistory(self.fingerprint).tosa
-
-    @property
-    def weightedUptime(self):
-        """Weighted Uptime"""
-        with bridgedb.Storage.getDB() as db:
-            return db.getBridgeHistory(self.fingerprint).weightedUptime
-
 def getDescriptorDigests(desc):
     """Return the SHA-1 hash hexdigests of all descriptor descs
 
diff --git a/lib/bridgedb/test/deprecated.py b/lib/bridgedb/test/deprecated.py
index 40cfe0a..d85f6f9 100644
--- a/lib/bridgedb/test/deprecated.py
+++ b/lib/bridgedb/test/deprecated.py
@@ -124,6 +124,262 @@ class ParseORAddressError(Exception):
 
 @deprecate.deprecated(
     Version('bridgedb', 0, 2, 4),
+    replacement='bridgedb.bridges.Bridge')
+class Bridge(object):
+    """Holds information for a single bridge, along with any Pluggable
+    Transports it is also running.
+
+    :attr str nickname: The bridge's nickname.  Not currently used.
+    :attr ip: (:class:`ipaddr.IPAddress`) The bridge's IPv4 address, specified
+        on the 'r'-line in a networkstatus document.
+    :attr int orport: The bridge's OR port.
+    :attr dict or_addresses: The bridges alternate IP addresses. The keys
+        should be instances of ``ipaddr.IPAddress``, and the value should be a
+        :class:`bridgedb.parse.addr.PortList` for the port(s) on which that
+        address is listening.
+    :attr list transports: List of :class:`PluggableTransport` instances for
+        each PT which the bridge supports.
+    :attr str fingerprint: The bridge's identity digest, in lowercase hex,
+        without whitespace.
+    :attr bool running: ``True``, if this bridge was given the ``Running`` flag.
+    :attr bool stable: ``True``, if this bridge was given the ``Stable`` flag.
+    :attr dict blockingCountries: A dictionary whose keys are strings of
+        ``"IP:port"`` pairs, and the keys are lists of two letter country
+        codes which block that IP:port. For example::
+            {"1.2.3.4:9001": ['sk', 'us', 'ir', 'cn']}
+    :attr str desc_digest: SHA1 hexdigest of the bridge's descriptor as
+        defined in the networkstatus document.
+    :attr str ei_digest: SHA1 hexdigest of the bridge's extra-info document as
+        given in the bridge's descriptor, corresponding to desc_digest.
+    :attr bool verified: Did we receive the descriptor for this bridge that
+        was specified in the networkstatus?
+    """
+    def __init__(self, nickname, ip, orport, fingerprint=None, id_digest=None,
+                 or_addresses=None, transports=None):
+        """Create a new Bridge. One of fingerprint and id_digest must be set.
+        """
+        self.nickname = nickname
+        self.ip = ip
+        self.orport = orport
+        if not or_addresses: or_addresses = {}
+        self.or_addresses = or_addresses
+        if not transports: transports = []
+        self.transports = transports
+        self.running = self.stable = None
+        self.blockingCountries = {}
+        self.desc_digest = None
+        self.ei_digest = None
+        self.verified = False
+
+        if id_digest is not None:
+            assert fingerprint is None
+            if len(id_digest) != DIGEST_LEN:
+                raise TypeError("Bridge with invalid ID")
+            self.fingerprint = toHex(id_digest)
+        elif fingerprint is not None:
+            if not isValidFingerprint(fingerprint):
+                raise TypeError("Bridge with invalid fingerprint (%r)"%
+                                fingerprint)
+            self.fingerprint = fingerprint.lower()
+        else:
+            raise TypeError("Bridge with no ID")
+
+    def setDescriptorDigest(self, digest):
+        """Set the descriptor digest, specified in the NS."""
+        self.desc_digest = digest
+
+    def setExtraInfoDigest(self, digest):
+        """Set the extra-info digest, specified in the descriptor."""
+        self.ei_digest = digest
+
+    def setVerified(self):
+        """Call when the bridge's descriptor is parsed"""
+        self.verified = True
+
+    def isVerified(self):
+        """Returns the truthiness of ``verified``"""
+        return self.verified
+
+    def getID(self):
+        """Return the bridge's identity digest."""
+        return fromHex(self.fingerprint)
+
+    def __repr__(self):
+        """Return a piece of python that evaluates to this bridge."""
+        if self.or_addresses:
+            return "Bridge(%r,%r,%d,%r,or_addresses=%s)"%(
+                self.nickname, self.ip, self.orport, self.fingerprint,
+                self.or_addresses)
+        return "Bridge(%r,%r,%d,%r)"%(
+            self.nickname, self.ip, self.orport, self.fingerprint)
+
+    def getConfigLine(self, includeFingerprint=False, addressClass=None,
+            request=None, transport=None):
+        """Returns a valid bridge line for inclusion in a torrc.
+
+        :param bool includeFingerprint: If ``True``, include the
+            ``fingerprint`` of this :class:`Bridge` in the returned bridge
+            line.
+        :param DOCDOC addressClass: Type of address to choose.
+        :param str request: A string unique to this request e.g. email-address
+            or ``uniformMap(ip)`` or ``'default'``.
+        :param str transport: A pluggable transport method name.
+        """
+
+        if not request: request = 'default'
+        digest = getHMACFunc('Order-Or-Addresses')(request)
+        pos = long(digest[:8], 16) # lower 8 bytes -> long
+
+        # default address type
+        if not addressClass: addressClass = ipaddr.IPv4Address
+
+        # pluggable transports
+        if transport:
+            # filter by 'methodname'
+            transports = filter(lambda x: transport == x.methodname,
+                    self.transports)
+            # filter by 'addressClass'
+            transports = filter(lambda x: isinstance(x.address, addressClass),
+                    transports)
+            if transports:
+                pt = transports[pos % len(transports)]
+                return pt.getTransportLine(includeFingerprint)
+
+        # filter addresses by address class
+        addresses = filter(lambda x: isinstance(x[0], addressClass),
+                self.or_addresses.items())
+
+        # default ip, orport should get a chance at being selected
+        if isinstance(self.ip, addressClass):
+            addresses.insert(0,(self.ip, addr.PortList(self.orport)))
+
+        if addresses:
+            address,portlist = addresses[pos % len(addresses)]
+            if isinstance(address, ipaddr.IPv6Address): ip = "[%s]"%address
+            else: ip = "%s"%address
+            orport = portlist[pos % len(portlist)]
+
+            if includeFingerprint:
+                return "%s:%d %s" % (ip, orport, self.fingerprint)
+            else:
+                return "%s:%d" % (ip, orport)
+
+    def getAllConfigLines(self,includeFingerprint=False):
+        """Generator. Iterate over all valid config lines for this bridge."""
+        for address,portlist in self.or_addresses.items():
+            if type(address) is ipaddr.IPv6Address:
+                ip = "[%s]" % address
+            else:
+                ip = "%s" % address
+
+            for orport in portlist:
+                if includeFingerprint:
+                    yield "bridge %s:%d %s" % (ip,orport,self.fingerprint)
+                else:
+                    yield "bridge %s:%d" % (ip,orport)
+        for pt in self.transports:
+            yield pt.getTransportLine(includeFingerprints)
+
+
+    def assertOK(self):
+        assert is_valid_ip(self.ip)
+        assert isValidFingerprint(self.fingerprint)
+        assert 1 <= self.orport <= 65535
+        if self.or_addresses:
+            for address, portlist in self.or_addresses.items():
+                assert is_valid_ip(address)
+                for port in portlist:
+                    assert type(port) is int
+                    assert 1 <= port <= 65535
+
+    def setStatus(self, running=None, stable=None):
+        if running is not None:
+            self.running = running
+        if stable is not None:
+            self.stable = stable
+
+    def isBlocked(self, countryCode, addressClass, methodname=None):
+        """ if at least one address:port of the selected addressClass and
+        (optional) transport type is not blocked in countryCode, return True
+        """
+        # 1) transport is specified
+        if methodname is not None:
+            for transport in self.transports:
+                key = "%s:%s" % (transport.address, transport.port)
+                if (isinstance(transport.address, addressClass)
+                        and transport.methodname.lower() == methodname.lower()):
+                    try:
+                        if countryCode not in self.blockingCountries[key]:
+                            return False
+                    except KeyError:
+                        return False # no blocklist
+            return True
+        # 2) no transport specified (default)
+        else:
+            # 3) check primary ip, port
+            # XXX: could be more elegant if ip,orport were not special case
+            if isinstance(self.ip, addressClass):
+                key = "%s:%s" % (self.ip, self.orport)
+                try:
+                    if countryCode not in self.blockingCountries[key]:
+                        return False
+                except KeyError: return False # no blocklist
+
+            # 4) check or addresses
+            for address,portlist in self.or_addresses.items():
+                if isinstance(address, addressClass):
+                    # check each port
+                    for port in portlist:
+                        key = "%s:%s" % (address, port)
+                        try:
+                            if countryCode not in self.blockingCountries[key]:
+                                return False
+                        except KeyError: return False # no blocklist
+            return True
+
+    # Bridge Stability (#5482) properties.
+    @property
+    def familiar(self):
+        """
+        A bridge is 'familiar' if 1/8 of all active bridges have appeared
+        more recently than it, or if it has been around for a Weighted Time of 8 days.
+        """
+        with bridgedb.Storage.getDB() as db:
+            return db.getBridgeHistory(self.fingerprint).familiar
+
+    @property
+    def wfu(self):
+        """Weighted Fractional Uptime"""
+        with bridgedb.Storage.getDB() as db:
+            return db.getBridgeHistory(self.fingerprint).weightedFractionalUptime
+
+    @property
+    def weightedTime(self):
+        """Weighted Time"""
+        with bridgedb.Storage.getDB() as db:
+            return db.getBridgeHistory(self.fingerprint).weightedTime
+
+    @property
+    def wmtbac(self):
+        """Weighted Mean Time Between Address Change"""
+        with bridgedb.Storage.getDB() as db:
+            return db.getBridgeHistory(self.fingerprint).wmtbac
+
+    @property
+    def tosa(self):
+        """the Time On Same Address (TOSA)"""
+        with bridgedb.Storage.getDB() as db:
+            return db.getBridgeHistory(self.fingerprint).tosa
+
+    @property
+    def weightedUptime(self):
+        """Weighted Uptime"""
+        with bridgedb.Storage.getDB() as db:
+            return db.getBridgeHistory(self.fingerprint).weightedUptime
+
+
+ at deprecate.deprecated(
+    Version('bridgedb', 0, 2, 4),
     replacement='bridgedb.bridges.PluggableTransport')
 class PluggableTransport(object):
     """A PT with reference to the parent bridge on which it is running.





More information about the tor-commits mailing list