def run(self): size = 55000 while True: data, address = self.sock.recvfrom(size) #ignore stuff sent from our own socket if address[0] == ZapConfig.ip and address[1] == self.ignore_port: continue query = ZapTorrentProtocolParser(data) zap_debug_print("Got some data! ", data) zap_debug_print("my address is", (ZapConfig.ip, self.port)) zap_debug_print("other address is", address) zap_debug_print("about to parse the query in FilesLister") query.parse() if query.message_type == "files": # Parse the files out of the query, and store them in the remote files zap_debug_print("got a files reponse: ", data) ip = query.get_field('ip') port = query.get_field('port') name = query.get_field('name') for f in query.get_files(): zf = ZapFile(status="not-present") zf.ip = ip zf.port = port zf.name = name zf.number_of_blocks = f['blocks'] zf.digest = f['digest'] zf.filename = f['filename'] zap_debug_print("Someone told me about a file named", zf.filename) self.remote_files.add(zf)
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