Example #1
0
 def __init__(self, file_name, info_dict=None):
     """Reads existing metainfo file, or writes a new one.
        Builds client, fetches peer list, and construct peers.
     """
     self.logger = logging.getLogger('bt.torrent.Torrent')
     with open(file_name, 'r') as f:
         contents = f.read()
     self.info_dict = info_dict or bencode.bdecode(
         contents)  # If read, bdecode
     self.info_hash = util.sha1_hash(
         bencode.bencode(
             self.info_dict['info'])  # metainfo file is bencoded
     )
     self.piece_length = self.info_dict['info']['piece length']
     self.last_piece_length = self.length(
     ) % self.piece_length or self.piece_length
     pieces = self.info_dict['info']['pieces']
     self.pieces_hashes = list(self._read_pieces_hashes(pieces))
     self.num_pieces = len(self.pieces_hashes)
     assert len(self.pieces_hashes) == self.num_pieces
     # assert (self.num_pieces-1) * self.piece_length + self.last_piece_length \
     #        == file_length
     self.files = [f for f in self._create_files()]
     self.tmp_file = open('temp.tmp', 'w+')
     """ Data structure for easy lookup of piece rarity
         pieces[hash] has list of Peer instances with that piece
         Get rarity: len(pieces[hash])
     """
     self.pieces = [(Piece(self, i, self.pieces_hashes[i]), [])
                    for i in range(self.num_pieces)]
     for p, _ in self.pieces:
         logging.debug('Piece {} has length {}.'.format(
             p.index, p.piece_length))
     self._pieces_added = 0
Example #2
0
 def is_valid(self):
     """Return true if the hash of this entire piece is what we expected.
     """
     self.torrent.tmp_file.seek(self.start_pos)
     # ... but we read only the # of bytes this piece actually has.
     f = self.torrent.tmp_file.read(self.piece_length)
     self.logger.debug('HASH: length of piece {} was {}'.format(
         self.index, len(f)))
     actual_hash = util.sha1_hash(f)
     return actual_hash == self.piece_hash
Example #3
0
    def _pieces_hashes(cls, string, piece_length):
        """Return array built from 20-byte SHA1 hashes
            of the string's pieces.
        """
        output = ""
        current_pos = 0
        num_bytes = len(string)
        while current_pos < num_bytes:
            if current_pos + piece_length > num_bytes:
                to_position = num_bytes
            else:
                to_position = current_pos + piece_length

            piece_hash = util.sha1_hash(string[current_pos:to_position])
            output += piece_hash
            current_pos += piece_length

        return output
Example #4
0
    def __init__(self, ip, port, client, peer_id=None, conn=None):
        self.logger = logging.getLogger('bt.peer.Peer')
        self.ip = ip
        self.port = port
        self.client = client
        self.outstanding_requests = 0

        if peer_id:
            self.peer_id = peer_id
        else:
            seed = self.ip + str(time.time())
            self.peer_id = util.sha1_hash(self.ip)  # Until handshake

        self.am_choking = True  # Client choking remote
        self.am_interested = False  # Client interested
        self.choking = True  # Remote choking client
        self.interested = False  # Remote interested
        if conn:
            self.conn = MsgConnection(self, conn)
        else:
            self.conn = MsgConnection(self)
Example #5
0
 def connect(self, port=6881):
     """Try to connect to tracker.
        Return tracker's response.
     """
     params = {
         'info_hash': util.sha1_hash(str(
             bencode.bencode(self.torrent.info_dict['info'])
             )),
         'peer_id': self.client.peer_id,
         'port': port,
         'uploaded': 0,
         'downloaded': 0,
         'left': self.torrent.length(),
         'event': 'started'
     }
     announce_url = self.torrent.info_dict['announce']
     get_url = announce_url + "?" + urllib.urlencode(params)
     try:
         get_url=self._make_req(get_url)
     except Exception,e:
         print e
         return None
Example #6
0
 def _is_valid_piece(self, piece, index):
     piece_hash = util.sha1_hash(piece)
     expected_hash = self.client.torrent.pieces[index][0].piece_hash
     return piece_hash == expected_hash