Exemplo n.º 1
0
 def torrent(self):
   while not self.shutdown:
     self.pieces_left = len([m for m in self.pieces if not m['have']])
     self.update_peers(self.query_trackers())
     # Check whether we still have pieces left to send
     if not self.pieces_left:
       sys.stdout.write("\nDownload completed, cleaning up...\n")
       sys.exit(0)
     for peer_index, peer in enumerate(self.peers):
       # Process requests
       # TODO: Work on strategy for pieces that need be requested multiple times
       if peer.can_request():
         for piece_index, piece in [(n, m) for (n, m) in enumerate(self.pieces) if not m['have']]:
           if peer.can_request() and peer.has_piece(piece_index) and not piece['requested']:
             peer.request_piece(piece_index, piece.get('size', self.piece_size))
             piece['requested'] = True
             piece['attempts'] += 1
       # Process completed pieces
       if peer.has_complete_pieces():
         sys.stdout.write("\r%s/%s ({0:.2f}%%) pieces downloaded. Rate: %s/s".
           format((len(self.pieces) - self.pieces_left)/len(self.pieces)*100) %
           (len(self.pieces) - self.pieces_left, len(self.pieces), 
           strmanip.parse_filesize(self.downloaded/(time.time() - self.runtime), 1000)))
         sys.stdout.flush()
         for piece in peer.complete_pieces():
           if self.check_piece(piece['index'], piece['data']):
             self.write_piece(piece['index'], piece['data'])
           else:
             self.log.warn("Piece hash FAILED. Index: %s" % piece['index'])
             self.pieces[piece['index']]['requested'] = False
             sys.exit(0)
     Peer.loop()
   print("Exiting BitClient")
   sys.exit(1)
Exemplo n.º 2
0
 def map_pieces(self, current_map):
     '''Given the pieces string, map them 20-byte sized chunks
 The piece map contains a list of dictionaries (one per piece) each containing
 the keys: hash | have | requested | priority | attempts'''
     piece_length = 20  # the hash is 20 bytes long
     if isinstance(current_map, str):
         current_map = current_map.encode("latin-1")
     self.pieces = [{
         "hash": current_map[i:i + piece_length],
         "have": False,
         "requested": False,
         "priority": 0,
         "attempts": 0
     } for i in range(0, len(current_map), piece_length)]
     calc_total = len(self.pieces) * self.piece_size
     overage = calc_total - self.total_size
     if overage:
         self.pieces[-1]['size'] = self.piece_size - overage
         calc_total = calc_total - overage
     if calc_total != self.total_size:
         self.log.critical(
             "The pieces for the torrent were incorrectly mapped")
         sys.exit(0)
     self.log.debug("Attempting to download: %s\t%s" \
       % (calc_total, strmanip.parse_filesize(calc_total, 1000)))
     self.update_map()
Exemplo n.º 3
0
 def torrent(self):
     while not self.shutdown:
         self.pieces_left = len([m for m in self.pieces if not m['have']])
         self.update_peers(self.query_trackers())
         # Check whether we still have pieces left to send
         if not self.pieces_left:
             sys.stdout.write("\nDownload completed, cleaning up...\n")
             sys.exit(0)
         for peer_index, peer in enumerate(self.peers):
             # Process requests
             # TODO: Work on strategy for pieces that need be requested multiple times
             if peer.can_request():
                 for piece_index, piece in [
                     (n, m) for (n, m) in enumerate(self.pieces)
                         if not m['have']
                 ]:
                     if peer.can_request() and peer.has_piece(
                             piece_index) and not piece['requested']:
                         peer.request_piece(
                             piece_index, piece.get('size',
                                                    self.piece_size))
                         piece['requested'] = True
                         piece['attempts'] += 1
             # Process completed pieces
             if peer.has_complete_pieces():
                 sys.stdout.write(
                     "\r%s/%s ({0:.2f}%%) pieces downloaded. Rate: %s/s".
                     format((len(self.pieces) - self.pieces_left) /
                            len(self.pieces) * 100) %
                     (len(self.pieces) - self.pieces_left, len(self.pieces),
                      strmanip.parse_filesize(
                          self.downloaded /
                          (time.time() - self.runtime), 1000)))
                 sys.stdout.flush()
                 for piece in peer.complete_pieces():
                     if self.check_piece(piece['index'], piece['data']):
                         self.write_piece(piece['index'], piece['data'])
                     else:
                         self.log.warn("Piece hash FAILED. Index: %s" %
                                       piece['index'])
                         self.pieces[piece['index']]['requested'] = False
                         sys.exit(0)
         Peer.loop()
     print("Exiting BitClient")
     sys.exit(1)
Exemplo n.º 4
0
 def map_pieces(self, current_map):
   '''Given the pieces string, map them 20-byte sized chunks
   The piece map contains a list of dictionaries (one per piece) each containing
   the keys: hash | have | requested | priority | attempts'''
   piece_length = 20 # the hash is 20 bytes long
   if isinstance(current_map, str):
     current_map = current_map.encode("latin-1")
   self.pieces = [{"hash":current_map[i:i+piece_length],
     "have": False,  "requested": False, 
     "priority": 0,  "attempts": 0}
      for i in range(0, len(current_map), piece_length)]
   calc_total = len(self.pieces) * self.piece_size
   overage = calc_total - self.total_size
   if overage:
     self.pieces[-1]['size'] = self.piece_size - overage
     calc_total = calc_total - overage
   if calc_total != self.total_size:
     self.log.critical("The pieces for the torrent were incorrectly mapped")
     sys.exit(0)
   self.log.debug("Attempting to download: %s\t%s" \
     % (calc_total, strmanip.parse_filesize(calc_total, 1000)))
   self.update_map()