def from_torrent_dict(cls, metainfo, save_path): """ Takes a torrent metainfo dictionary object and processes it for use in this object. :param metainfo: :param save_path: A string path to where the torrent should be saved. """ info = metainfo['info'] files = OrderedDict() if 'files' in info: for f in info['files']: files[os.path.join(*f['path'])] = f['length'] else: files[info['name']] = info['length'] return cls( name=info['name'], announce_urls=map( lambda (url,): url, metainfo['announce-list'] ), # Note that info_hash is generated here because torrentool # returns the info_hash as hex encoded, which is really not # useful in most situations info_hash=sha1(Bencode.encode(info)).digest(), piece_length=info['piece length'], files=files, piece_hashes=splice(info['pieces'], 20), save_path=save_path )
def from_torrent_dict(cls, metainfo, save_path): """ Takes a torrent metainfo dictionary object and processes it for use in this object. :param metainfo: :param save_path: A string path to where the torrent should be saved. """ info = metainfo['info'] files = OrderedDict() if 'files' in info: for f in info['files']: files[os.path.join(*f['path'])] = f['length'] else: files[info['name']] = info['length'] return cls( name=info['name'], announce_urls=map(lambda (url, ): url, metainfo['announce-list']), # Note that info_hash is generated here because torrentool # returns the info_hash as hex encoded, which is really not # useful in most situations info_hash=sha1(Bencode.encode(info)).digest(), piece_length=info['piece length'], files=files, piece_hashes=splice(info['pieces'], 20), save_path=save_path)
def announce(self): """ Announces client to tracker and handles response. Returns dictionary of peers. """ # Send the request try: response = requests.get(self.tracker_url, params=self.announce_payload, allow_redirects=False) logging.debug("Tracker URL: {0}".format(response.url)) except requests.ConnectionError as e: logging.warn("Tracker not found: {0}".format(self.tracker_url)) return {} if response.status_code < 200 or response.status_code >= 300: raise BitTorrentException( "Tracker response error '{0}' for URL: {1}".format(response.content, response.url) ) self.last_run = self.now decoded_response = Bencode.decode(response.content) self.tracker_interval = decoded_response.get("interval", self.TRACKER_INTERVAL) logging.debug("Tracking interval set to: {interval}".format(interval=self.tracker_interval)) if "failure reason" in decoded_response: raise BitTorrentException(decoded_response["failure reason"]) if "peers" in decoded_response: # ignoring `peer6` (ipv6) for now peers = decode_binary_peers(decoded_response["peers"]) else: peers = [] return dict(map(lambda hostport: (hostport, self.PEER(hostport, self.torrent)), peers))
def from_string(cls, s, save_path): """ Takes a torrent file as a string and loads it. :param s: :param save_path: A string path to where the torrent should be saved. """ return cls.from_torrent_dict(Bencode.read_string(s), save_path)
def from_path(cls, path, save_path): """ Takes a torrent from a path and loads it. :param path: A path as string to the path torrent file. :param save_path: A string path to where the torrent should be saved. """ return cls.from_torrent_dict(Bencode.read_file(path), save_path)
def announce(self): """ Announces client to tracker and handles response. Returns dictionary of peers. """ # Send the request try: response = requests.get( self.tracker_url, params=self.announce_payload, allow_redirects=False ) logging.debug("Tracker URL: {0}".format(response.url)) except requests.ConnectionError as e: logging.warn( "Tracker not found: {0}".format( self.tracker_url ) ) return {} if response.status_code < 200 or response.status_code >= 300: raise BitTorrentException( "Tracker response error '{0}' for URL: {1}".format( response.content, response.url ) ) self.last_run = self.now decoded_response = Bencode.decode(response.content) self.tracker_interval = decoded_response.get( 'interval', self.TRACKER_INTERVAL ) logging.debug("Tracking interval set to: {interval}".format( interval=self.tracker_interval )) if "failure reason" in decoded_response: raise BitTorrentException(decoded_response["failure reason"]) if "peers" in decoded_response: # ignoring `peer6` (ipv6) for now peers = decode_binary_peers(decoded_response['peers']) else: peers = [] return dict(map( lambda hostport: ( hostport, self.PEER(hostport, self.torrent) ), peers ))
def from_string(cls, s, save_path): """ Takes a torrent file as a string and loads it. :param s: :param save_path: A string path to where the torrent should be saved. """ return cls.from_torrent_dict( Bencode.read_string(s), save_path )
def from_path(cls, path, save_path): """ Takes a torrent from a path and loads it. :param path: A path as string to the path torrent file. :param save_path: A string path to where the torrent should be saved. """ return cls.from_torrent_dict( Bencode.read_file(path), save_path )