def _parse_response(self, response): tracker_dict = btencode.btdecode(response) if 'failure reason' in tracker_dict: raise AnnounceError('''failure reason key in tracker response\ %s:''' % tracker_dict['failure reason']) peers_raw = tracker_dict['peers'] if isinstance(peers_raw, dict): raise AnnounceError('peers as dictionary model not implemented') return self.factory._decode_hosts_ports(peers_raw)
def parse_metainfo(self): try: with open(self.filename) as tor: torrent_dict = btencode.btdecode(tor.read()) except btencode.BTDecodeError: print "BTDecodeError handling %s" % self.filename sys.exit(1) except IOError: print "IOError handling %s" % self.filename sys.exit(1) try: self.announce_list = torrent_dict["announce-list"] except KeyError: self.announce_list = [[torrent_dict["announce"]]] # list of lists info = torrent_dict["info"] try: self.info_hash = sha1(btencode.btencode(info)).digest() except btencode.BTEncodeError as e: print "BTEncodeError handling %s: %s" % (self.filename, e.args[0]) sys.exit(1) self.piece_length = info["piece length"] if not "files" in info: self.length = info["length"] self.names_length = [[info["name"], self.length]] else: self.length = sum(f["length"] for f in info["files"]) self.names_length = [(f["path"][0], f["length"]) for f in info["files"]] # break string pieces up into a list of those pieces pieces_string = info["pieces"] hashes = [pieces_string[i : i + 20] for i in xrange(0, len(pieces_string), 20)] self.n_pieces = len(hashes) blocks = self.piece_length / BSIZE # calculate size of last piece leftover = self.length - ((self.n_pieces - 1) * self.piece_length) final_blocks = int(math.ceil(float(leftover) / BSIZE)) final_size = leftover % BSIZE self.pieces = [Piece(hashes[i], blocks) for i in xrange(self.n_pieces - 1)] self.pieces.append(FinalPiece(hashes[-1], final_blocks, final_size))