def __init__(self, filename): metafile = open(filename, 'rb') try: self._metainfo = debencode.decode(metafile.read()) except Exception: raise ValueError("Invalid BitTorrent metainfo file format") if 'announce' not in self._metainfo or 'info' not in self._metainfo: raise ValueError("Invalid BitTorrent metainfo file format") info = self._metainfo['info'] if ('piece length' not in info or 'pieces' not in info or 'name' not in info): raise ValueError("Invalid BitTorrent metainfo file format") try: if 'length' in info: # Single file mode self._directory = '../result/' self._files = [([info['name']], info['length'])] self._length = info['length'] else: # Multi file mode self._directory = info['name'] self._files = [(d['path'], d['length']) for d in self._metainfo['info']['files']] self._length = sum([length for (_, length) in self._files]) except: raise ValueError("Invalid BitTorrent metainfo file format") self._hash = hashlib.sha1(bencode.encode(info)).digest() self._num_pieces = len(self._metainfo['info']['pieces'])/20
def __init__(self, metainfo, port, peer_id): self._metainfo = metainfo self._port = port self._peer_id = peer_id params = {'info_hash': self._metainfo.info_hash, 'peer_id': self._peer_id, 'port': self._port, 'uploaded': 0, 'downloaded': 0, 'left': sum([pair[1] for pair in self._metainfo.files]), 'compact': 1, 'event': 'started'} try: response = requests.get( self._metainfo.announce, params=params) except requests.ConnectionError: raise TrackerError( "Can't connect to the tracker at {}" .format(self._metainfo.announce)) response = debencode.decode(response.content) if 'failure reason' in response: raise TrackerError( "Failure reason: {}".format( response['failure reason'])) if 'warning message' in response: logger.warning( "Warning: {}".format(response['warning message'])) print >> sys.stderr, ( "Warning: {}".format(response['warning message'])) try: self._min_interval = response.get('min interval', 0) if 'tracker id' in response: self._tracker_id = response['tracker id'] self._interval = response['interval'] self._complete = response['complete'] self._incomplete = response['incomplete'] if isinstance(response['peers'], list): self._peers = response['peers'] else: self._peers = [] peers = response['peers'] for offset in xrange(0, len(peers), 6): self._peers.append( {'ip': "{}.{}.{}.{}" .format(str(ord(peers[offset])), str(ord(peers[offset+1])), str(ord(peers[offset+2])), str(ord(peers[offset+3]))), 'port': (ord(peers[offset+4])*256 + ord(peers[offset+5]))}) except Exception: raise TrackerError("Invalid tracker response")