async def test_on_metadata_received_alert(mock_handle, test_download): """ Testing whether the right operations happen when we receive metadata """ test_future = Future() mocked_file = Mock() mocked_file.path = 'test' test_download.handle.trackers = lambda: [] test_download.handle.get_peer_info = lambda: [] test_download.handle.save_resume_data = lambda: test_future test_download.handle.rename_file = lambda *_: None with open(TESTS_DATA_DIR / "bak_single.torrent", mode='rb') as torrent_file: encoded_metainfo = torrent_file.read() decoded_metainfo = bdecode_compat(encoded_metainfo) get_info_from_handle(test_download.handle).metadata = lambda: bencode( decoded_metainfo[b'info']) get_info_from_handle(test_download.handle).files = lambda: [mocked_file] test_download.checkpoint = lambda: test_future.set_result(None) test_download.session = MockObject() test_download.session.torrent_db = None test_download.handle.save_path = lambda: None test_download.handle.prioritize_files = lambda _: None test_download.get_share_mode = lambda: False test_download.on_metadata_received_alert(None) await test_future
async def __prepare(self, download): # wait for an handle first await download.get_handle() self.destdir = download.get_content_dest() metainfo = None while not metainfo: # Wait for an actual tdef with an actual metadata is available metainfo = download.get_def().get_metainfo() if not metainfo: await sleep(1) tdef = download.get_def() self.piecelen = tdef.get_piece_length() self.files = tdef.get_files_with_length() # we use self.infohash also like a flag to detect that stream class is prepared self.infohash = tdef.get_infohash() info = get_info_from_handle(download.handle) self.mapfile = info.map_file # required callbacks used in this class but defined in download class. # an other approach would be using self.__download = download but # below method looks cleaner self.__lt_state = download.get_state self.__getpieceprios = download.get_piece_priorities self.__setpieceprios = download.set_piece_priorities self.__getfileprios = download.get_file_priorities self.__setselectedfiles = download.set_selected_files self.__setdeadline = download.set_piece_deadline self.__resetdeadline = download.reset_piece_deadline self.__resumedownload = download.resume
def on_metadata_received_alert(self, _): torrent_info = get_info_from_handle(self.handle) if not torrent_info: return metadata = { b'info': bdecode_compat(torrent_info.metadata()), b'leechers': 0, b'seeders': 0 } trackers = [ tracker['url'].encode('utf-8') for tracker in self.handle.trackers() ] if len(trackers) > 1: metadata[b"announce-list"] = [trackers] elif trackers: metadata[b"announce"] = trackers[0] for peer in self.handle.get_peer_info(): if peer.progress == 1: metadata[b"seeders"] += 1 else: metadata[b"leechers"] += 1 try: self.tdef = TorrentDef.load_from_dict(metadata) except ValueError as ve: self._logger.exception(ve) return self.set_selected_files() self.checkpoint()
def test_get_info_from_handle(self): mock_handle = MockObject() def mock_get_torrent_file(): raise RuntimeError mock_handle.torrent_file = mock_get_torrent_file self.assertIsNone(get_info_from_handle(mock_handle))
def test_get_info_from_handle(): mock_handle = Mock() def mock_get_torrent_file(): raise RuntimeError mock_handle.torrent_file = mock_get_torrent_file assert not get_info_from_handle(mock_handle)
def get_torrent(self): if not self.handle or not self.handle.is_valid( ) or not self.handle.has_metadata(): return None torrent_info = get_info_from_handle(self.handle) t = lt.create_torrent(torrent_info) return t.generate()
def get_torrent_data(self): """ Return torrent data, if the handle is valid and metadata is available. """ if not self.handle or not self.handle.is_valid( ) or not self.handle.has_metadata(): return None torrent_info = get_info_from_handle(self.handle) t = lt.create_torrent(torrent_info) return t.generate()
def test_metadata_received_invalid_torrent_with_value_error( mock_handle, test_download): """ Testing whether the right operations happen when we receive metadata but the torrent info is invalid and throws Value Error """ def mocked_checkpoint(): raise RuntimeError("This code should not be reached!") mocked_file = Mock() mocked_file.path = 'test' # The line below should trigger Value Error test_download.handle.trackers = lambda: [{'url': 'no-DHT'}] test_download.handle.get_peer_info = lambda: [] get_info_from_handle( test_download.handle).metadata = lambda: lt.bencode({}) get_info_from_handle(test_download.handle).files = lambda: [mocked_file] test_download.checkpoint = mocked_checkpoint test_download.on_metadata_received_alert(None)
async def get_torrent(self, request): infohash = unhexlify(request.match_info['infohash']) download = self.session.dlmgr.get_download(infohash) if not download: return DownloadsEndpoint.return_404(request) if not download.handle or not download.handle.is_valid( ) or not download.handle.has_metadata(): return DownloadsEndpoint.return_404(request) torrent_info = get_info_from_handle(download.handle) t = create_torrent(torrent_info) torrent = t.generate() return RESTResponse(bencode(torrent), headers={ 'content-type': 'application/x-bittorrent', 'Content-Disposition': 'attachment; filename=%s.torrent' % hexlify(infohash).encode('utf-8') })
def set_selected_files(self, selected_files=None, prio=4, force=False): if not force and self.stream.enabled: return if not isinstance(self.tdef, TorrentDefNoMetainfo) and not self.get_share_mode(): if selected_files is None: selected_files = self.config.get_selected_files() else: self.config.set_selected_files(selected_files) torrent_info = get_info_from_handle(self.handle) if not torrent_info or not hasattr(torrent_info, 'files'): self._logger.error("File info not available for torrent %s", hexlify(self.tdef.get_infohash())) return filepriorities = [] torrent_storage = torrent_info.files() for index, file_entry in enumerate(torrent_storage): filepriorities.append(prio if index in selected_files or not selected_files else 0) self.set_file_priorities(filepriorities)