Example #1
0
    def run(self):
        #TODO: what if we don't receive it all at once?
        msg = self.sock.recv(54000)
        zap_debug_print("Got a message on the ZAPTCPResponseThread and it is", msg)
        response = ""
        query = ZapTorrentProtocolParser(msg)
        query.parse()
        if query.message_type == 'error':
            response = query.response
        elif query.message_type == 'inventory?':
            #Look for the file in local_files
            f = self.local_files.get(query.fields['filename'])
            if f is None:
                response = "ZT 1.0 error No file named %s" % query.fields['filename']
            else:
                f = f[0]
                r = ZapTorrentProtocolResponse(response_type="inventory", filename=f.filename, blocks=f.number_of_blocks)
                r.stuff_to_add = f.get_blocks(status='present')
                zap_debug_print("got back some blocks and they looks like this:", r.stuff_to_add)
                response = r.as_response()
        elif query.message_type == 'download?':
            #make sure we have the file
            f = self.local_files.get(query.fields['filename'])
            if f is None:
                response = "ZT 1.0 error No file named %s" % query.fields['filename']
            else:
                f = f[0]
                if f.block_is_present(int(query.fields['id'])):
                    r = ZapTorrentProtocolResponse(response_type="download", filename=f.filename, id=query.fields['id'],
                            bytes=f.get_block(int(query.fields['id'])).get_bytes())
                    response = r.as_response()
                    log_string = "upload %s %s %s %s %s %s" % (f.filename, ZapConfig.name,
                            query.fields['ip'], query.fields['port'], query.fields['id'],
                            len(f.get_block(int(query.fields['id'])).get_bytes()))
                    zap_log(log_string)
                else:
                    response = "ZT 1.0 error No block for %s at %s\n" % (f.filename, query.fields['id'])

        else:
            response = "ZT 1.0 error unknown TCP query type.\n"
        sent_length = 0
        zap_debug_print("sending %s as response" % response)
        while sent_length < len(response):
            message_remaining = response[sent_length:]
            length = self.sock.send(message_remaining)
            sent_length += length
        #TODO: do I close it on my end?
        self.sock.close()
Example #2
0
    def run(self):
        """Spawn off threads to download each block. When all
        threads return, check if the file is completely
        downloaded. If so, determine its digest and make
        sure it matches, and save it to disk."""
        start_time = time.time()
        file_info = self.remote_files[0]
        remote_file = ZapFile()
        remote_file.filename = file_info.filename
        remote_file.number_of_blocks = file_info.number_of_blocks
        remote_file.mark_as_remote()
        self.local_files.add(remote_file)
        child_threads = []

        for f in self.remote_files:
            remote_location = {}
            remote_location['ip'] = f.ip
            remote_location['port'] = f.port
            remote_location['name'] = f.name
            child_thread = self.remote_file_downloader(remote_file, f)
            child_thread.start()
            child_threads.append(child_thread)

        # How do we wait for them to finish?
        # TODO: what if I can't download the whole file?
        while not remote_file.is_downloaded():
            time.sleep(4)

        # Now all child threads are gone, I hope.
        remote_file.save_to_disk()
        zap_debug_print("remote file digest is ", remote_file.digest, "file_info.digest is ", file_info.digest)
        if remote_file.digest != file_info.digest:
            # Our file does not match. Quit this thread and return an error
            zap_debug_print("Digest does not match! I should delete downloaded file!")
            self.local_files.remove(remote_file)
            os.remove(remote_file.path)
            return False
        else:
            stop_time = time.time()
            log_string = "file %s %s %s" % (remote_file.filename, os.path.getsize(remote_file.path),
                    stop_time - start_time)
            zap_log(log_string)
            print("Finished downloading %s. Find it at %s." % (remote_file.filename, remote_file.path))
            return True
Example #3
0
 def run(self):
     # In a loop - aquire the lock
     # Check if the peer info has any stuff that I don't have
     # If so, mark it as downloading and release the lock
     # download it
     # Aquire the lock again
     # Mark the downloaded block as present
     # Release the lock
     while True:
         # We get the blocks each time in case the peer
         # has since received new blocks
         blocks_available = self.get_available_blocks(self.peer_info.ip,
                 self.peer_info.port, self.peer_info.filename)
         zap_debug_print("Blocks available are ", blocks_available)
         self.remote_file.sem.acquire()
         block_to_download = None
         for block_id in blocks_available:
             if self.remote_file.does_block_needs_downloading(int(block_id)):
                 block_to_download = int(block_id)
                 self.remote_file.mark_block_as('downloading', int(block_to_download))
                 break
         self.remote_file.sem.release()
         if block_to_download is None:
             zap_debug_print("No more blocks to download from" +
                     " this peer: ", self.peer_info)
             break
         data = self.download_block(self.peer_info.filename,
                 block_to_download, self.peer_info.ip,
                 self.peer_info.port)
         zap_debug_print("received %s back from the download query" % data)
         if data is not None:
             self.remote_file.set_block_data(block_to_download, data)
             self.remote_file.mark_block_as('present', block_to_download)
             log_string = "download %s %s %s %s %s %s" % (self.peer_info.filename,
                     self.peer_info.name, self.peer_info.ip, self.peer_info.port,
                     block_to_download, len(data))
             zap_log(log_string)
         else:
             # Mark the block to be downloaded again.
             print(("error downloading block %s from" % block_to_download), self.peer_info)
             self.remote_file.mark_block_as('not-present', int(block_to_download))