pylint: fix trailing-whitespace

This commit is contained in:
Job Evers-Meltzer 2016-12-13 17:08:29 -06:00
parent 32fa2460ff
commit 14ac2bac39
17 changed files with 123 additions and 122 deletions

View file

@ -214,7 +214,7 @@ class ApplicationSettings(Settings):
self.BLOBFILES_DIR = "blobfiles" self.BLOBFILES_DIR = "blobfiles"
self.BLOB_SIZE = 2*MB self.BLOB_SIZE = 2*MB
self.LOG_FILE_NAME = "lbrynet.log" self.LOG_FILE_NAME = "lbrynet.log"
self.LOG_POST_URL = "https://lbry.io/log-upload" self.LOG_POST_URL = "https://lbry.io/log-upload"
self.CRYPTSD_FILE_EXTENSION = ".cryptsd" self.CRYPTSD_FILE_EXTENSION = ".cryptsd"
self.API_ADDRESS = "lbryapi" self.API_ADDRESS = "lbryapi"
self.ICON_PATH = "icons" if platform is WINDOWS else "app.icns" self.ICON_PATH = "icons" if platform is WINDOWS else "app.icns"
@ -230,7 +230,7 @@ class ApplicationSettings(Settings):
self.LOGGLY_TOKEN = 'LJEzATH4AzRgAwxjAP00LwZ2YGx3MwVgZTMuBQZ3MQuxLmOv' self.LOGGLY_TOKEN = 'LJEzATH4AzRgAwxjAP00LwZ2YGx3MwVgZTMuBQZ3MQuxLmOv'
self.ANALYTICS_ENDPOINT = 'https://api.segment.io/v1' self.ANALYTICS_ENDPOINT = 'https://api.segment.io/v1'
self.ANALYTICS_TOKEN = 'Ax5LZzR1o3q3Z3WjATASDwR5rKyHH0qOIRIbLmMXn2H=' self.ANALYTICS_TOKEN = 'Ax5LZzR1o3q3Z3WjATASDwR5rKyHH0qOIRIbLmMXn2H='
self.DB_REVISION_FILE_NAME = 'db_revision' self.DB_REVISION_FILE_NAME = 'db_revision'
Settings.__init__(self) Settings.__init__(self)
@ -299,7 +299,7 @@ class Config(DefaultSettings):
return os.path.join(self.ensure_data_dir(), self.LOG_FILE_NAME) return os.path.join(self.ensure_data_dir(), self.LOG_FILE_NAME)
def get_db_revision_filename(self): def get_db_revision_filename(self):
return os.path.join(self.ensure_data_dir(), self.DB_REVISION_FILE_NAME) return os.path.join(self.ensure_data_dir(), self.DB_REVISION_FILE_NAME)
def get_conf_filename(self): def get_conf_filename(self):
return get_settings_file_ext(self.ensure_data_dir()) return get_settings_file_ext(self.ensure_data_dir())

View file

@ -361,7 +361,7 @@ class Wallet(object):
except (TypeError, ValueError, ValidationError): except (TypeError, ValueError, ValidationError):
return Failure(InvalidStreamInfoError(name, result['value'])) return Failure(InvalidStreamInfoError(name, result['value']))
sd_hash = metadata['sources']['lbry_sd_hash'] sd_hash = metadata['sources']['lbry_sd_hash']
claim_outpoint = ClaimOutpoint(result['txid'], result['n']) claim_outpoint = ClaimOutpoint(result['txid'], result['n'])
d = self._save_name_metadata(name, claim_outpoint, sd_hash) d = self._save_name_metadata(name, claim_outpoint, sd_hash)
d.addCallback(lambda _: self.get_claimid(name, result['txid'], result['n'])) d.addCallback(lambda _: self.get_claimid(name, result['txid'], result['n']))
d.addCallback(lambda cid: _log_success(cid)) d.addCallback(lambda cid: _log_success(cid))
@ -382,7 +382,7 @@ class Wallet(object):
d.addCallback(lambda claims: next(c for c in claims if c['name'] == name and c['nOut'] == claim_outpoint['nout'])) d.addCallback(lambda claims: next(c for c in claims if c['name'] == name and c['nOut'] == claim_outpoint['nout']))
d.addCallback(lambda claim: self._update_claimid(claim['claimId'], name, ClaimOutpoint(txid, claim['nOut']))) d.addCallback(lambda claim: self._update_claimid(claim['claimId'], name, ClaimOutpoint(txid, claim['nOut'])))
return d return d
claim_outpoint = ClaimOutpoint(txid, nout) claim_outpoint = ClaimOutpoint(txid, nout)
d = self._get_claimid_for_tx(name, claim_outpoint) d = self._get_claimid_for_tx(name, claim_outpoint)
d.addCallback(_get_id_for_return) d.addCallback(_get_id_for_return)
return d return d
@ -583,7 +583,7 @@ class Wallet(object):
for claim in claims: for claim in claims:
if 'in claim trie' in claim: if 'in claim trie' in claim:
name_is_equal = 'name' in claim and str(claim['name']) == name name_is_equal = 'name' in claim and str(claim['name']) == name
nout_is_equal = 'nOut' in claim and claim['nOut'] == claim_outpoint['nout'] nout_is_equal = 'nOut' in claim and claim['nOut'] == claim_outpoint['nout']
if name_is_equal and nout_is_equal and 'value' in claim: if name_is_equal and nout_is_equal and 'value' in claim:
try: try:
value_dict = json.loads(claim['value']) value_dict = json.loads(claim['value'])
@ -682,7 +682,7 @@ class Wallet(object):
d.addCallback( d.addCallback(
lambda _: self.db.runQuery("delete from name_metadata where name=? and txid=? and n=? and sd_hash=?", lambda _: self.db.runQuery("delete from name_metadata where name=? and txid=? and n=? and sd_hash=?",
(name, claim_outpoint['txid'], UNSET_NOUT, sd_hash))) (name, claim_outpoint['txid'], UNSET_NOUT, sd_hash)))
d.addCallback(lambda _: self.db.runQuery("insert into name_metadata values (?, ?, ?, ?)", d.addCallback(lambda _: self.db.runQuery("insert into name_metadata values (?, ?, ?, ?)",
(name, claim_outpoint['txid'], claim_outpoint['nout'], sd_hash))) (name, claim_outpoint['txid'], claim_outpoint['nout'], sd_hash)))
return d return d
@ -698,7 +698,7 @@ class Wallet(object):
d.addCallback( d.addCallback(
lambda _: self.db.runQuery("delete from claim_ids where claimId=? and name=? and txid=? and n=?", lambda _: self.db.runQuery("delete from claim_ids where claimId=? and name=? and txid=? and n=?",
(claim_id, name, claim_outpoint['txid'], UNSET_NOUT))) (claim_id, name, claim_outpoint['txid'], UNSET_NOUT)))
d.addCallback(lambda r: self.db.runQuery("insert into claim_ids values (?, ?, ?, ?)", d.addCallback(lambda r: self.db.runQuery("insert into claim_ids values (?, ?, ?, ?)",
(claim_id, name, claim_outpoint['txid'], claim_outpoint['nout']))) (claim_id, name, claim_outpoint['txid'], claim_outpoint['nout'])))
d.addCallback(lambda _: claim_id) d.addCallback(lambda _: claim_id)
@ -997,7 +997,7 @@ class LBRYumWallet(Wallet):
def _send_name_claim_update(self, name, claim_id, claim_outpoint, value, amount): def _send_name_claim_update(self, name, claim_id, claim_outpoint, value, amount):
metadata = json.dumps(value) metadata = json.dumps(value)
log.debug("Update %s %d %f %s %s '%s'", claim_outpoint['txid'], claim_outpoint['nout'], log.debug("Update %s %d %f %s %s '%s'", claim_outpoint['txid'], claim_outpoint['nout'],
amount, name, claim_id, metadata) amount, name, claim_id, metadata)
cmd = known_commands['update'] cmd = known_commands['update']
func = getattr(self.cmd_runner, cmd.name) func = getattr(self.cmd_runner, cmd.name)

View file

@ -10,7 +10,7 @@
the terms and conditions of version 3 of the GNU General Public the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below. License, supplemented by the additional permissions listed below.
0. Additional Definitions. 0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License, and the "GNU GPL" refers to version 3 of the GNU
@ -111,7 +111,7 @@ the following:
a copy of the Library already present on the user's computer a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked of the Library that is interface-compatible with the Linked
Version. Version.
e) Provide Installation Information, but only if you would otherwise e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the be required to provide such information under section 6 of the

View file

@ -10,7 +10,7 @@
""" This module defines the charaterizing constants of the Kademlia network """ This module defines the charaterizing constants of the Kademlia network
C{checkRefreshInterval} and C{udpDatagramMaxSize} are implementation-specific C{checkRefreshInterval} and C{udpDatagramMaxSize} are implementation-specific
constants, and do not affect general Kademlia operation. constants, and do not affect general Kademlia operation.
""" """
######### KADEMLIA CONSTANTS ########### ######### KADEMLIA CONSTANTS ###########

View file

@ -10,7 +10,7 @@
class Contact(object): class Contact(object):
""" Encapsulation for remote contact """ Encapsulation for remote contact
This class contains information on a single remote contact, and also This class contains information on a single remote contact, and also
provides a direct RPC API to the remote node which it represents provides a direct RPC API to the remote node which it represents
""" """
@ -20,7 +20,7 @@ class Contact(object):
self.port = udpPort self.port = udpPort
self._networkProtocol = networkProtocol self._networkProtocol = networkProtocol
self.commTime = firstComm self.commTime = firstComm
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, Contact): if isinstance(other, Contact):
return self.id == other.id return self.id == other.id
@ -28,7 +28,7 @@ class Contact(object):
return self.id == other return self.id == other
else: else:
return False return False
def __ne__(self, other): def __ne__(self, other):
if isinstance(other, Contact): if isinstance(other, Contact):
return self.id != other.id return self.id != other.id
@ -41,20 +41,20 @@ class Contact(object):
compact_ip = reduce( compact_ip = reduce(
lambda buff, x: buff + bytearray([int(x)]), self.address.split('.'), bytearray()) lambda buff, x: buff + bytearray([int(x)]), self.address.split('.'), bytearray())
return str(compact_ip) return str(compact_ip)
def __str__(self): def __str__(self):
return '<%s.%s object; IP address: %s, UDP port: %d>' % ( return '<%s.%s object; IP address: %s, UDP port: %d>' % (
self.__module__, self.__class__.__name__, self.address, self.port) self.__module__, self.__class__.__name__, self.address, self.port)
def __getattr__(self, name): def __getattr__(self, name):
""" This override allows the host node to call a method of the remote """ This override allows the host node to call a method of the remote
node (i.e. this contact) as if it was a local function. node (i.e. this contact) as if it was a local function.
For instance, if C{remoteNode} is a instance of C{Contact}, the For instance, if C{remoteNode} is a instance of C{Contact}, the
following will result in C{remoteNode}'s C{test()} method to be following will result in C{remoteNode}'s C{test()} method to be
called with argument C{123}:: called with argument C{123}::
remoteNode.test(123) remoteNode.test(123)
Such a RPC method call will return a Deferred, which will callback Such a RPC method call will return a Deferred, which will callback
when the contact responds with the result (or an error occurs). when the contact responds with the result (or an error occurs).
This happens via this contact's C{_networkProtocol} object (i.e. the This happens via this contact's C{_networkProtocol} object (i.e. the

View file

@ -16,7 +16,7 @@ import constants
class DataStore(UserDict.DictMixin): class DataStore(UserDict.DictMixin):
""" Interface for classes implementing physical storage (for data """ Interface for classes implementing physical storage (for data
published via the "STORE" RPC) for the Kademlia DHT published via the "STORE" RPC) for the Kademlia DHT
@note: This provides an interface for a dict-like object @note: This provides an interface for a dict-like object
""" """
def keys(self): def keys(self):

View file

@ -14,47 +14,47 @@ class DecodeError(Exception):
class Encoding(object): class Encoding(object):
""" Interface for RPC message encoders/decoders """ Interface for RPC message encoders/decoders
All encoding implementations used with this library should inherit and All encoding implementations used with this library should inherit and
implement this. implement this.
""" """
def encode(self, data): def encode(self, data):
""" Encode the specified data """ Encode the specified data
@param data: The data to encode @param data: The data to encode
This method has to support encoding of the following This method has to support encoding of the following
types: C{str}, C{int} and C{long} types: C{str}, C{int} and C{long}
Any additional data types may be supported as long as the Any additional data types may be supported as long as the
implementing class's C{decode()} method can successfully implementing class's C{decode()} method can successfully
decode them. decode them.
@return: The encoded data @return: The encoded data
@rtype: str @rtype: str
""" """
def decode(self, data): def decode(self, data):
""" Decode the specified data string """ Decode the specified data string
@param data: The data (byte string) to decode. @param data: The data (byte string) to decode.
@type data: str @type data: str
@return: The decoded data (in its correct type) @return: The decoded data (in its correct type)
""" """
class Bencode(Encoding): class Bencode(Encoding):
""" Implementation of a Bencode-based algorithm (Bencode is the encoding """ Implementation of a Bencode-based algorithm (Bencode is the encoding
algorithm used by Bittorrent). algorithm used by Bittorrent).
@note: This algorithm differs from the "official" Bencode algorithm in @note: This algorithm differs from the "official" Bencode algorithm in
that it can encode/decode floating point values in addition to that it can encode/decode floating point values in addition to
integers. integers.
""" """
def encode(self, data): def encode(self, data):
""" Encoder implementation of the Bencode algorithm """ Encoder implementation of the Bencode algorithm
@param data: The data to encode @param data: The data to encode
@type data: int, long, tuple, list, dict or str @type data: int, long, tuple, list, dict or str
@return: The encoded data @return: The encoded data
@rtype: str @rtype: str
""" """
@ -76,7 +76,7 @@ class Bencode(Encoding):
encodedDictItems += self.encode(data[key]) encodedDictItems += self.encode(data[key])
return 'd%se' % encodedDictItems return 'd%se' % encodedDictItems
elif type(data) == float: elif type(data) == float:
# This (float data type) is a non-standard extension to the original Bencode algorithm # This (float data type) is a non-standard extension to the original Bencode algorithm
return 'f%fe' % data return 'f%fe' % data
elif data == None: elif data == None:
# This (None/NULL data type) is a non-standard extension # This (None/NULL data type) is a non-standard extension
@ -85,16 +85,16 @@ class Bencode(Encoding):
else: else:
print data print data
raise TypeError, "Cannot bencode '%s' object" % type(data) raise TypeError, "Cannot bencode '%s' object" % type(data)
def decode(self, data): def decode(self, data):
""" Decoder implementation of the Bencode algorithm """ Decoder implementation of the Bencode algorithm
@param data: The encoded data @param data: The encoded data
@type data: str @type data: str
@note: This is a convenience wrapper for the recursive decoding @note: This is a convenience wrapper for the recursive decoding
algorithm, C{_decodeRecursive} algorithm, C{_decodeRecursive}
@return: The decoded data, as a native Python type @return: The decoded data, as a native Python type
@rtype: int, list, dict or str @rtype: int, list, dict or str
""" """
@ -104,11 +104,11 @@ class Bencode(Encoding):
return self._decodeRecursive(data)[0] return self._decodeRecursive(data)[0]
except ValueError as e: except ValueError as e:
raise DecodeError, e.message raise DecodeError, e.message
@staticmethod @staticmethod
def _decodeRecursive(data, startIndex=0): def _decodeRecursive(data, startIndex=0):
""" Actual implementation of the recursive Bencode algorithm """ Actual implementation of the recursive Bencode algorithm
Do not call this; use C{decode()} instead Do not call this; use C{decode()} instead
""" """
if data[startIndex] == 'i': if data[startIndex] == 'i':

View file

@ -31,11 +31,11 @@ class KBucket(object):
def addContact(self, contact): def addContact(self, contact):
""" Add contact to _contact list in the right order. This will move the """ Add contact to _contact list in the right order. This will move the
contact to the end of the k-bucket if it is already present. contact to the end of the k-bucket if it is already present.
@raise kademlia.kbucket.BucketFull: Raised when the bucket is full and @raise kademlia.kbucket.BucketFull: Raised when the bucket is full and
the contact isn't in the bucket the contact isn't in the bucket
already already
@param contact: The contact to add @param contact: The contact to add
@type contact: kademlia.contact.Contact @type contact: kademlia.contact.Contact
""" """
@ -57,7 +57,7 @@ class KBucket(object):
def getContacts(self, count=-1, excludeContact=None): def getContacts(self, count=-1, excludeContact=None):
""" Returns a list containing up to the first count number of contacts """ Returns a list containing up to the first count number of contacts
@param count: The amount of contacts to return (if 0 or less, return @param count: The amount of contacts to return (if 0 or less, return
all contacts) all contacts)
@type count: int @type count: int
@ -65,12 +65,12 @@ class KBucket(object):
the list of returned values, it will be the list of returned values, it will be
discarded before returning. If a C{str} is discarded before returning. If a C{str} is
passed as this argument, it must be the passed as this argument, it must be the
contact's ID. contact's ID.
@type excludeContact: kademlia.contact.Contact or str @type excludeContact: kademlia.contact.Contact or str
@raise IndexError: If the number of requested contacts is too large @raise IndexError: If the number of requested contacts is too large
@return: Return up to the first count number of contacts in a list @return: Return up to the first count number of contacts in a list
If no contacts are present an empty is returned If no contacts are present an empty is returned
@rtype: list @rtype: list
@ -97,7 +97,7 @@ class KBucket(object):
# enough contacts in list # enough contacts in list
else: else:
contactList = self._contacts[0:count] contactList = self._contacts[0:count]
if excludeContact in contactList: if excludeContact in contactList:
contactList.remove(excludeContact) contactList.remove(excludeContact)
@ -105,24 +105,24 @@ class KBucket(object):
def removeContact(self, contact): def removeContact(self, contact):
""" Remove given contact from list """ Remove given contact from list
@param contact: The contact to remove, or a string containing the @param contact: The contact to remove, or a string containing the
contact's node ID contact's node ID
@type contact: kademlia.contact.Contact or str @type contact: kademlia.contact.Contact or str
@raise ValueError: The specified contact is not in this bucket @raise ValueError: The specified contact is not in this bucket
""" """
self._contacts.remove(contact) self._contacts.remove(contact)
def keyInRange(self, key): def keyInRange(self, key):
""" Tests whether the specified key (i.e. node ID) is in the range """ Tests whether the specified key (i.e. node ID) is in the range
of the n-bit ID space covered by this k-bucket (in otherwords, it of the n-bit ID space covered by this k-bucket (in otherwords, it
returns whether or not the specified key should be placed in this returns whether or not the specified key should be placed in this
k-bucket) k-bucket)
@param key: The key to test @param key: The key to test
@type key: str or int @type key: str or int
@return: C{True} if the key is in this k-bucket's range, or C{False} @return: C{True} if the key is in this k-bucket's range, or C{False}
if not. if not.
@rtype: bool @rtype: bool

View file

@ -11,37 +11,37 @@ import msgtypes
class MessageTranslator(object): class MessageTranslator(object):
""" Interface for RPC message translators/formatters """ Interface for RPC message translators/formatters
Classes inheriting from this should provide a translation services between Classes inheriting from this should provide a translation services between
the classes used internally by this Kademlia implementation and the actual the classes used internally by this Kademlia implementation and the actual
data that is transmitted between nodes. data that is transmitted between nodes.
""" """
def fromPrimitive(self, msgPrimitive): def fromPrimitive(self, msgPrimitive):
""" Create an RPC Message from a message's string representation """ Create an RPC Message from a message's string representation
@param msgPrimitive: The unencoded primitive representation of a message @param msgPrimitive: The unencoded primitive representation of a message
@type msgPrimitive: str, int, list or dict @type msgPrimitive: str, int, list or dict
@return: The translated message object @return: The translated message object
@rtype: entangled.kademlia.msgtypes.Message @rtype: entangled.kademlia.msgtypes.Message
""" """
def toPrimitive(self, message): def toPrimitive(self, message):
""" Create a string representation of a message """ Create a string representation of a message
@param message: The message object @param message: The message object
@type message: msgtypes.Message @type message: msgtypes.Message
@return: The message's primitive representation in a particular @return: The message's primitive representation in a particular
messaging format messaging format
@rtype: str, int, list or dict @rtype: str, int, list or dict
""" """
class DefaultFormat(MessageTranslator): class DefaultFormat(MessageTranslator):
""" The default on-the-wire message format for this library """ """ The default on-the-wire message format for this library """
typeRequest, typeResponse, typeError = range(3) typeRequest, typeResponse, typeError = range(3)
headerType, headerMsgID, headerNodeID, headerPayload, headerArgs = range(5) headerType, headerMsgID, headerNodeID, headerPayload, headerArgs = range(5)
def fromPrimitive(self, msgPrimitive): def fromPrimitive(self, msgPrimitive):
msgType = msgPrimitive[self.headerType] msgType = msgPrimitive[self.headerType]
if msgType == self.typeRequest: if msgType == self.typeRequest:
@ -62,8 +62,8 @@ class DefaultFormat(MessageTranslator):
# Unknown message, no payload # Unknown message, no payload
msg = msgtypes.Message(msgPrimitive[self.headerMsgID], msgPrimitive[self.headerNodeID]) msg = msgtypes.Message(msgPrimitive[self.headerMsgID], msgPrimitive[self.headerNodeID])
return msg return msg
def toPrimitive(self, message): def toPrimitive(self, message):
msg = {self.headerMsgID: message.id, msg = {self.headerMsgID: message.id,
self.headerNodeID: message.nodeID} self.headerNodeID: message.nodeID}
if isinstance(message, msgtypes.RequestMessage): if isinstance(message, msgtypes.RequestMessage):

View file

@ -22,7 +22,7 @@ class RequestMessage(Message):
def __init__(self, nodeID, method, methodArgs, rpcID=None): def __init__(self, nodeID, method, methodArgs, rpcID=None):
if rpcID == None: if rpcID == None:
hash = hashlib.sha384() hash = hashlib.sha384()
hash.update(str(random.getrandbits(255))) hash.update(str(random.getrandbits(255)))
rpcID = hash.digest() rpcID = hash.digest()
Message.__init__(self, rpcID, nodeID) Message.__init__(self, rpcID, nodeID)
self.request = method self.request = method

View file

@ -27,7 +27,7 @@ log = logging.getLogger(__name__)
def rpcmethod(func): def rpcmethod(func):
""" Decorator to expose Node methods as remote procedure calls """ Decorator to expose Node methods as remote procedure calls
Apply this decorator to methods in the Node class (or a subclass) in order Apply this decorator to methods in the Node class (or a subclass) in order
to make them remotely callable via the DHT's RPC mechanism. to make them remotely callable via the DHT's RPC mechanism.
""" """
@ -36,13 +36,13 @@ def rpcmethod(func):
class Node(object): class Node(object):
""" Local node in the Kademlia network """ Local node in the Kademlia network
This class represents a single local node in a Kademlia network; in other This class represents a single local node in a Kademlia network; in other
words, this class encapsulates an Entangled-using application's "presence" words, this class encapsulates an Entangled-using application's "presence"
in a Kademlia network. in a Kademlia network.
In Entangled, all interactions with the Kademlia network by a client In Entangled, all interactions with the Kademlia network by a client
application is performed via this class (or a subclass). application is performed via this class (or a subclass).
""" """
def __init__(self, id=None, udpPort=4000, dataStore=None, def __init__(self, id=None, udpPort=4000, dataStore=None,
routingTableClass=None, networkProtocol=None, lbryid=None, routingTableClass=None, networkProtocol=None, lbryid=None,
@ -61,7 +61,7 @@ class Node(object):
exposed. This should be a class, not an object, exposed. This should be a class, not an object,
in order to allow the Node to pass an in order to allow the Node to pass an
auto-generated node ID to the routingtable object auto-generated node ID to the routingtable object
upon instantiation (if necessary). upon instantiation (if necessary).
@type routingTable: entangled.kademlia.routingtable.RoutingTable @type routingTable: entangled.kademlia.routingtable.RoutingTable
@param networkProtocol: The network protocol to use. This can be @param networkProtocol: The network protocol to use. This can be
overridden from the default to (for example) overridden from the default to (for example)
@ -138,7 +138,7 @@ class Node(object):
def joinNetwork(self, knownNodeAddresses=None): def joinNetwork(self, knownNodeAddresses=None):
""" Causes the Node to join the Kademlia network; normally, this """ Causes the Node to join the Kademlia network; normally, this
should be called before any other DHT operations. should be called before any other DHT operations.
@param knownNodeAddresses: A sequence of tuples containing IP address @param knownNodeAddresses: A sequence of tuples containing IP address
information for existing nodes on the information for existing nodes on the
Kademlia network, in the format: Kademlia network, in the format:
@ -329,12 +329,12 @@ class Node(object):
def iterativeFindNode(self, key): def iterativeFindNode(self, key):
""" The basic Kademlia node lookup operation """ The basic Kademlia node lookup operation
Call this to find a remote node in the P2P overlay network. Call this to find a remote node in the P2P overlay network.
@param key: the n-bit key (i.e. the node or value ID) to search for @param key: the n-bit key (i.e. the node or value ID) to search for
@type key: str @type key: str
@return: This immediately returns a deferred object, which will return @return: This immediately returns a deferred object, which will return
a list of k "closest" contacts (C{kademlia.contact.Contact} a list of k "closest" contacts (C{kademlia.contact.Contact}
objects) to the specified key as soon as the operation is objects) to the specified key as soon as the operation is
@ -345,12 +345,12 @@ class Node(object):
def iterativeFindValue(self, key): def iterativeFindValue(self, key):
""" The Kademlia search operation (deterministic) """ The Kademlia search operation (deterministic)
Call this to retrieve data from the DHT. Call this to retrieve data from the DHT.
@param key: the n-bit key (i.e. the value ID) to search for @param key: the n-bit key (i.e. the value ID) to search for
@type key: str @type key: str
@return: This immediately returns a deferred object, which will return @return: This immediately returns a deferred object, which will return
either one of two things: either one of two things:
- If the value was found, it will return a Python - If the value was found, it will return a Python
@ -409,7 +409,7 @@ class Node(object):
""" Remove the contact with the specified node ID from this node's """ Remove the contact with the specified node ID from this node's
table of known nodes. This is a simple wrapper for the same method table of known nodes. This is a simple wrapper for the same method
in this object's RoutingTable object in this object's RoutingTable object
@param contactID: The node ID of the contact to remove @param contactID: The node ID of the contact to remove
@type contactID: str @type contactID: str
""" """
@ -418,10 +418,10 @@ class Node(object):
def findContact(self, contactID): def findContact(self, contactID):
""" Find a entangled.kademlia.contact.Contact object for the specified """ Find a entangled.kademlia.contact.Contact object for the specified
cotact ID cotact ID
@param contactID: The contact ID of the required Contact object @param contactID: The contact ID of the required Contact object
@type contactID: str @type contactID: str
@return: Contact object of remote node with the specified node ID, @return: Contact object of remote node with the specified node ID,
or None if the contact was not found or None if the contact was not found
@rtype: twisted.internet.defer.Deferred @rtype: twisted.internet.defer.Deferred
@ -444,7 +444,7 @@ class Node(object):
@rpcmethod @rpcmethod
def ping(self): def ping(self):
""" Used to verify contact between two Kademlia nodes """ Used to verify contact between two Kademlia nodes
@rtype: str @rtype: str
""" """
return 'pong' return 'pong'
@ -452,7 +452,7 @@ class Node(object):
@rpcmethod @rpcmethod
def store(self, key, value, originalPublisherID=None, self_store=False, **kwargs): def store(self, key, value, originalPublisherID=None, self_store=False, **kwargs):
""" Store the received data in this node's local hash table """ Store the received data in this node's local hash table
@param key: The hashtable key of the data @param key: The hashtable key of the data
@type key: str @type key: str
@param value: The actual data (the value associated with C{key}) @param value: The actual data (the value associated with C{key})
@ -467,7 +467,7 @@ class Node(object):
@type age: int @type age: int
@rtype: str @rtype: str
@todo: Since the data (value) may be large, passing it around as a buffer @todo: Since the data (value) may be large, passing it around as a buffer
(which is the case currently) might not be a good idea... will have (which is the case currently) might not be a good idea... will have
to fix this (perhaps use a stream from the Protocol class?) to fix this (perhaps use a stream from the Protocol class?)
@ -576,7 +576,7 @@ class Node(object):
def _generateID(self): def _generateID(self):
""" Generates an n-bit pseudo-random identifier """ Generates an n-bit pseudo-random identifier
@return: A globally unique n-bit pseudo-random identifier @return: A globally unique n-bit pseudo-random identifier
@rtype: str @rtype: str
""" """
@ -586,12 +586,12 @@ class Node(object):
def _iterativeFind(self, key, startupShortlist=None, rpc='findNode'): def _iterativeFind(self, key, startupShortlist=None, rpc='findNode'):
""" The basic Kademlia iterative lookup operation (for nodes/values) """ The basic Kademlia iterative lookup operation (for nodes/values)
This builds a list of k "closest" contacts through iterative use of This builds a list of k "closest" contacts through iterative use of
the "FIND_NODE" RPC, or if C{findValue} is set to C{True}, using the the "FIND_NODE" RPC, or if C{findValue} is set to C{True}, using the
"FIND_VALUE" RPC, in which case the value (if found) may be returned "FIND_VALUE" RPC, in which case the value (if found) may be returned
instead of a list of contacts instead of a list of contacts
@param key: the n-bit key (i.e. the node or value ID) to search for @param key: the n-bit key (i.e. the node or value ID) to search for
@type key: str @type key: str
@param startupShortlist: A list of contacts to use as the starting @param startupShortlist: A list of contacts to use as the starting
@ -605,7 +605,7 @@ class Node(object):
other operations that piggy-back on the basic Kademlia other operations that piggy-back on the basic Kademlia
lookup operation (Entangled's "delete" RPC, for instance). lookup operation (Entangled's "delete" RPC, for instance).
@type rpc: str @type rpc: str
@return: If C{findValue} is C{True}, the algorithm will stop as soon @return: If C{findValue} is C{True}, the algorithm will stop as soon
as a data value for C{key} is found, and return a dictionary as a data value for C{key} is found, and return a dictionary
containing the key and the found value. Otherwise, it will containing the key and the found value. Otherwise, it will

View file

@ -192,7 +192,7 @@ class KademliaProtocol(protocol.DatagramProtocol):
@note: The header used for breaking up large data segments will @note: The header used for breaking up large data segments will
possibly be moved out of the KademliaProtocol class in the possibly be moved out of the KademliaProtocol class in the
future, into something similar to a message translator/encoder future, into something similar to a message translator/encoder
class (see C{kademlia.msgformat} and C{kademlia.encoding}). class (see C{kademlia.msgformat} and C{kademlia.encoding}).
""" """
if len(data) > self.msgSizeLimit: if len(data) > self.msgSizeLimit:
# We have to spread the data over multiple UDP datagrams, # We have to spread the data over multiple UDP datagrams,

View file

@ -30,10 +30,10 @@ class RoutingTable(object):
@param contact: The contact to add to this node's k-buckets @param contact: The contact to add to this node's k-buckets
@type contact: kademlia.contact.Contact @type contact: kademlia.contact.Contact
""" """
def distance(self, keyOne, keyTwo): def distance(self, keyOne, keyTwo):
""" Calculate the XOR result between two string variables """ Calculate the XOR result between two string variables
@return: XOR result of two long variables @return: XOR result of two long variables
@rtype: long @rtype: long
""" """
@ -44,7 +44,7 @@ class RoutingTable(object):
def findCloseNodes(self, key, count, _rpcNodeID=None): def findCloseNodes(self, key, count, _rpcNodeID=None):
""" Finds a number of known nodes closest to the node/value with the """ Finds a number of known nodes closest to the node/value with the
specified key. specified key.
@param key: the n-bit key (i.e. the node or value ID) to search for @param key: the n-bit key (i.e. the node or value ID) to search for
@type key: str @type key: str
@param count: the amount of contacts to return @param count: the amount of contacts to return
@ -53,9 +53,9 @@ class RoutingTable(object):
Whatever ID is passed in the paramater will get Whatever ID is passed in the paramater will get
excluded from the list of returned contacts. excluded from the list of returned contacts.
@type _rpcNodeID: str @type _rpcNodeID: str
@return: A list of node contacts (C{kademlia.contact.Contact instances}) @return: A list of node contacts (C{kademlia.contact.Contact instances})
closest to the specified key. closest to the specified key.
This method will return C{k} (or C{count}, if specified) This method will return C{k} (or C{count}, if specified)
contacts if at all possible; it will only return fewer if the contacts if at all possible; it will only return fewer if the
node is returning all of the contacts that it knows of. node is returning all of the contacts that it knows of.
@ -63,7 +63,7 @@ class RoutingTable(object):
""" """
def getContact(self, contactID): def getContact(self, contactID):
""" Returns the (known) contact with the specified node ID """ Returns the (known) contact with the specified node ID
@raise ValueError: No contact with the specified contact ID is known @raise ValueError: No contact with the specified contact ID is known
by this node by this node
""" """
@ -83,7 +83,7 @@ class RoutingTable(object):
will be refreshed, regardless of the time they were last will be refreshed, regardless of the time they were last
accessed. accessed.
@type force: bool @type force: bool
@return: A list of node ID's that the parent node should search for @return: A list of node ID's that the parent node should search for
in order to refresh the routing Table in order to refresh the routing Table
@rtype: list @rtype: list
@ -91,14 +91,14 @@ class RoutingTable(object):
def removeContact(self, contactID): def removeContact(self, contactID):
""" Remove the contact with the specified node ID from the routing """ Remove the contact with the specified node ID from the routing
table table
@param contactID: The node ID of the contact to remove @param contactID: The node ID of the contact to remove
@type contactID: str @type contactID: str
""" """
def touchKBucket(self, key): def touchKBucket(self, key):
""" Update the "last accessed" timestamp of the k-bucket which covers """ Update the "last accessed" timestamp of the k-bucket which covers
the range containing the specified key in the key/ID space the range containing the specified key in the key/ID space
@param key: A key in the range of the target k-bucket @param key: A key in the range of the target k-bucket
@type key: str @type key: str
""" """
@ -106,13 +106,13 @@ class RoutingTable(object):
class TreeRoutingTable(RoutingTable): class TreeRoutingTable(RoutingTable):
""" This class implements a routing table used by a Node class. """ This class implements a routing table used by a Node class.
The Kademlia routing table is a binary tree whose leaves are k-buckets, The Kademlia routing table is a binary tree whose leaves are k-buckets,
where each k-bucket contains nodes with some common prefix of their IDs. where each k-bucket contains nodes with some common prefix of their IDs.
This prefix is the k-bucket's position in the binary tree; it therefore This prefix is the k-bucket's position in the binary tree; it therefore
covers some range of ID values, and together all of the k-buckets cover covers some range of ID values, and together all of the k-buckets cover
the entire n-bit ID (or key) space (with no overlap). the entire n-bit ID (or key) space (with no overlap).
@note: In this implementation, nodes in the tree (the k-buckets) are @note: In this implementation, nodes in the tree (the k-buckets) are
added dynamically, as needed; this technique is described in the 13-page added dynamically, as needed; this technique is described in the 13-page
version of the Kademlia paper, in section 2.4. It does, however, use the version of the Kademlia paper, in section 2.4. It does, however, use the
@ -162,11 +162,11 @@ class TreeRoutingTable(RoutingTable):
# the k-bucket. This implementation follows section # the k-bucket. This implementation follows section
# 2.2 regarding this point. # 2.2 regarding this point.
headContact = self._buckets[bucketIndex]._contacts[0] headContact = self._buckets[bucketIndex]._contacts[0]
def replaceContact(failure): def replaceContact(failure):
""" Callback for the deferred PING RPC to see if the head """ Callback for the deferred PING RPC to see if the head
node in the k-bucket is still responding node in the k-bucket is still responding
@type failure: twisted.python.failure.Failure @type failure: twisted.python.failure.Failure
""" """
failure.trap(TimeoutError) failure.trap(TimeoutError)
@ -180,18 +180,18 @@ class TreeRoutingTable(RoutingTable):
pass pass
# ...and add the new one at the tail of the bucket # ...and add the new one at the tail of the bucket
self.addContact(contact) self.addContact(contact)
# Ping the least-recently seen contact in this k-bucket # Ping the least-recently seen contact in this k-bucket
headContact = self._buckets[bucketIndex]._contacts[0] headContact = self._buckets[bucketIndex]._contacts[0]
df = headContact.ping() df = headContact.ping()
# If there's an error (i.e. timeout), remove the head # If there's an error (i.e. timeout), remove the head
# contact, and append the new one # contact, and append the new one
df.addErrback(replaceContact) df.addErrback(replaceContact)
def findCloseNodes(self, key, count, _rpcNodeID=None): def findCloseNodes(self, key, count, _rpcNodeID=None):
""" Finds a number of known nodes closest to the node/value with the """ Finds a number of known nodes closest to the node/value with the
specified key. specified key.
@param key: the n-bit key (i.e. the node or value ID) to search for @param key: the n-bit key (i.e. the node or value ID) to search for
@type key: str @type key: str
@param count: the amount of contacts to return @param count: the amount of contacts to return
@ -200,9 +200,9 @@ class TreeRoutingTable(RoutingTable):
Whatever ID is passed in the paramater will get Whatever ID is passed in the paramater will get
excluded from the list of returned contacts. excluded from the list of returned contacts.
@type _rpcNodeID: str @type _rpcNodeID: str
@return: A list of node contacts (C{kademlia.contact.Contact instances}) @return: A list of node contacts (C{kademlia.contact.Contact instances})
closest to the specified key. closest to the specified key.
This method will return C{k} (or C{count}, if specified) This method will return C{k} (or C{count}, if specified)
contacts if at all possible; it will only return fewer if the contacts if at all possible; it will only return fewer if the
node is returning all of the contacts that it knows of. node is returning all of the contacts that it knows of.
@ -219,7 +219,7 @@ class TreeRoutingTable(RoutingTable):
i = 1 i = 1
canGoLower = bucketIndex-i >= 0 canGoLower = bucketIndex-i >= 0
canGoHigher = bucketIndex+i < len(self._buckets) canGoHigher = bucketIndex+i < len(self._buckets)
# Fill up the node list to k nodes, starting with the closest neighbouring nodes known # Fill up the node list to k nodes, starting with the closest neighbouring nodes known
while len(closestNodes) < constants.k and (canGoLower or canGoHigher): while len(closestNodes) < constants.k and (canGoLower or canGoHigher):
#TODO: this may need to be optimized #TODO: this may need to be optimized
if canGoLower: if canGoLower:
@ -237,7 +237,7 @@ class TreeRoutingTable(RoutingTable):
def getContact(self, contactID): def getContact(self, contactID):
""" Returns the (known) contact with the specified node ID """ Returns the (known) contact with the specified node ID
@raise ValueError: No contact with the specified contact ID is known @raise ValueError: No contact with the specified contact ID is known
by this node by this node
""" """
@ -265,7 +265,7 @@ class TreeRoutingTable(RoutingTable):
will be refreshed, regardless of the time they were last will be refreshed, regardless of the time they were last
accessed. accessed.
@type force: bool @type force: bool
@return: A list of node ID's that the parent node should search for @return: A list of node ID's that the parent node should search for
in order to refresh the routing Table in order to refresh the routing Table
@rtype: list @rtype: list
@ -282,7 +282,7 @@ class TreeRoutingTable(RoutingTable):
def removeContact(self, contactID): def removeContact(self, contactID):
""" Remove the contact with the specified node ID from the routing """ Remove the contact with the specified node ID from the routing
table table
@param contactID: The node ID of the contact to remove @param contactID: The node ID of the contact to remove
@type contactID: str @type contactID: str
""" """
@ -296,7 +296,7 @@ class TreeRoutingTable(RoutingTable):
def touchKBucket(self, key): def touchKBucket(self, key):
""" Update the "last accessed" timestamp of the k-bucket which covers """ Update the "last accessed" timestamp of the k-bucket which covers
the range containing the specified key in the key/ID space the range containing the specified key in the key/ID space
@param key: A key in the range of the target k-bucket @param key: A key in the range of the target k-bucket
@type key: str @type key: str
""" """
@ -306,10 +306,10 @@ class TreeRoutingTable(RoutingTable):
def _kbucketIndex(self, key): def _kbucketIndex(self, key):
""" Calculate the index of the k-bucket which is responsible for the """ Calculate the index of the k-bucket which is responsible for the
specified key (or ID) specified key (or ID)
@param key: The key for which to find the appropriate k-bucket index @param key: The key for which to find the appropriate k-bucket index
@type key: str @type key: str
@return: The index of the k-bucket responsible for the specified key @return: The index of the k-bucket responsible for the specified key
@rtype: int @rtype: int
""" """
@ -324,7 +324,7 @@ class TreeRoutingTable(RoutingTable):
def _randomIDInBucketRange(self, bucketIndex): def _randomIDInBucketRange(self, bucketIndex):
""" Returns a random ID in the specified k-bucket's range """ Returns a random ID in the specified k-bucket's range
@param bucketIndex: The index of the k-bucket to use @param bucketIndex: The index of the k-bucket to use
@type bucketIndex: int @type bucketIndex: int
""" """
@ -342,7 +342,7 @@ class TreeRoutingTable(RoutingTable):
def _splitBucket(self, oldBucketIndex): def _splitBucket(self, oldBucketIndex):
""" Splits the specified k-bucket into two new buckets which together """ Splits the specified k-bucket into two new buckets which together
cover the same range in the key/ID space cover the same range in the key/ID space
@param oldBucketIndex: The index of k-bucket to split (in this table's @param oldBucketIndex: The index of k-bucket to split (in this table's
list of k-buckets) list of k-buckets)
@type oldBucketIndex: int @type oldBucketIndex: int
@ -372,7 +372,7 @@ class OptimizedTreeRoutingTable(TreeRoutingTable):
TreeRoutingTable.__init__(self, parentNodeID) TreeRoutingTable.__init__(self, parentNodeID)
# Cache containing nodes eligible to replace stale k-bucket entries # Cache containing nodes eligible to replace stale k-bucket entries
self._replacementCache = {} self._replacementCache = {}
def addContact(self, contact): def addContact(self, contact):
""" Add the given contact to the correct k-bucket; if it already """ Add the given contact to the correct k-bucket; if it already
exists, its status will be updated exists, its status will be updated
@ -415,11 +415,11 @@ class OptimizedTreeRoutingTable(TreeRoutingTable):
elif len(self._replacementCache) >= constants.k: elif len(self._replacementCache) >= constants.k:
self._replacementCache.pop(0) self._replacementCache.pop(0)
self._replacementCache[bucketIndex].append(contact) self._replacementCache[bucketIndex].append(contact)
def removeContact(self, contactID): def removeContact(self, contactID):
""" Remove the contact with the specified node ID from the routing """ Remove the contact with the specified node ID from the routing
table table
@param contactID: The node ID of the contact to remove @param contactID: The node ID of the contact to remove
@type contactID: str @type contactID: str
""" """
@ -430,7 +430,7 @@ class OptimizedTreeRoutingTable(TreeRoutingTable):
#print 'removeContact(): Contact not in routing table' #print 'removeContact(): Contact not in routing table'
return return
contact.failedRPCs += 1 contact.failedRPCs += 1
if contact.failedRPCs >= 5: if contact.failedRPCs >= 5:
self._buckets[bucketIndex].removeContact(contactID) self._buckets[bucketIndex].removeContact(contactID)
# Replace this stale contact with one from our replacemnent cache, if we have any # Replace this stale contact with one from our replacemnent cache, if we have any
if self._replacementCache.has_key(bucketIndex): if self._replacementCache.has_key(bucketIndex):

View file

@ -407,7 +407,7 @@ class Daemon(AuthJSONRPCServer):
# claim_out is dictionary containing 'txid' and 'nout' # claim_out is dictionary containing 'txid' and 'nout'
def _add_to_pending_claims(self, name, claim_out): def _add_to_pending_claims(self, name, claim_out):
txid = claim_out['txid'] txid = claim_out['txid']
nout = claim_out['nout'] nout = claim_out['nout']
log.info("Adding lbry://%s to pending claims, txid %s nout %d" % (name, txid, nout)) log.info("Adding lbry://%s to pending claims, txid %s nout %d" % (name, txid, nout))
self.pending_claims[name] = (txid, nout) self.pending_claims[name] = (txid, nout)
return claim_out return claim_out
@ -1498,7 +1498,7 @@ class Daemon(AuthJSONRPCServer):
'name': name to look up, string, do not include lbry:// prefix 'name': name to look up, string, do not include lbry:// prefix
'txid': optional, if specified, look for claim with this txid 'txid': optional, if specified, look for claim with this txid
'nout': optional, if specified, look for claim with this nout 'nout': optional, if specified, look for claim with this nout
Returns: Returns:
txid, amount, value, n, height txid, amount, value, n, height
""" """

View file

@ -40,11 +40,11 @@ class Publisher(object):
def start(self, name, file_path, bid, metadata): def start(self, name, file_path, bid, metadata):
log.info('Starting publish for %s', name) log.info('Starting publish for %s', name)
def _show_result(): def _show_result():
log.info("Success! Published %s --> lbry://%s txid: %s nout: %d", log.info("Success! Published %s --> lbry://%s txid: %s nout: %d",
self.file_name, self.publish_name, self.txid, self.nout) self.file_name, self.publish_name, self.txid, self.nout)
out = {} out = {}
out['nout'] = self.nout out['nout'] = self.nout
out['txid'] = self.txid out['txid'] = self.txid
return defer.succeed(out) return defer.succeed(out)
self.publish_name = name self.publish_name = name
@ -137,10 +137,10 @@ class Publisher(object):
msg = 'Failed to claim name:{}'.format(claim_out['reason']) msg = 'Failed to claim name:{}'.format(claim_out['reason'])
defer.fail(Exception(msg)) defer.fail(Exception(msg))
txid = claim_out['txid'] txid = claim_out['txid']
nout = claim_out['nout'] nout = claim_out['nout']
log.debug('Name claimed using txid: %s, nout: %d', txid, nout) log.debug('Name claimed using txid: %s, nout: %d', txid, nout)
self.txid = txid self.txid = txid
self.nout = nout self.nout = nout
d = self.wallet.claim_name(self.publish_name, self.bid_amount, m) d = self.wallet.claim_name(self.publish_name, self.bid_amount, m)
d.addCallback(set_txid_nout) d.addCallback(set_txid_nout)

View file

@ -38,7 +38,7 @@ class Metadata(StructuredDict):
def __init__(self, metadata, migrate=True, target_version=None): def __init__(self, metadata, migrate=True, target_version=None):
if not isinstance(metadata, dict): if not isinstance(metadata, dict):
raise TypeError("metadata is not a dictionary") raise TypeError("metadata is not a dictionary")
starting_version = metadata.get('ver', '0.0.1') starting_version = metadata.get('ver', '0.0.1')
StructuredDict.__init__(self, metadata, starting_version, migrate, target_version) StructuredDict.__init__(self, metadata, starting_version, migrate, target_version)

View file

@ -8,4 +8,5 @@ pylint -E --disable=inherit-non-class --disable=no-member \
--enable=unused-import \ --enable=unused-import \
--enable=bad-whitespace \ --enable=bad-whitespace \
--enable=line-too-long \ --enable=line-too-long \
--enable=trailing-whitespace \
lbrynet $@ lbrynet $@