def create_dconfig_from_params(parameters): """ Create a download configuration based on some given parameters. Possible parameters are: - anon_hops: the number of hops for the anonymous download. 0 hops is equivalent to a plain download - safe_seeding: whether the seeding of the download should be anonymous or not (0 = off, 1 = on) - destination: the destination path of the torrent (where it is saved on disk) """ download_config = DownloadConfig() anon_hops = parameters.get('anon_hops', 0) safe_seeding = bool(parameters.get('safe_seeding', 0)) if anon_hops > 0 and not safe_seeding: return None, "Cannot set anonymous download without safe seeding enabled" if anon_hops > 0: download_config.set_hops(anon_hops) if safe_seeding: download_config.set_safe_seeding(True) if 'destination' in parameters: download_config.set_dest_dir(parameters['destination']) if 'selected_files' in parameters: download_config.set_selected_files(parameters['selected_files']) return download_config, None
async def get_metainfo(self, infohash, timeout=30, hops=None, url=None): """ Lookup metainfo for a given infohash. The mechanism works by joining the swarm for the infohash connecting to a few peers, and downloading the metadata for the torrent. :param infohash: The (binary) infohash to lookup metainfo for. :param timeout: A timeout in seconds. :param hops: the number of tunnel hops to use for this lookup. If None, use config default. :param url: Optional URL. Can contain trackers info, etc. :return: The metainfo """ infohash_hex = hexlify(infohash) if infohash in self.metainfo_cache: self._logger.info('Returning metainfo from cache for %s', infohash_hex) return self.metainfo_cache[infohash]['meta_info'] self._logger.info('Trying to fetch metainfo for %s', infohash_hex) if infohash in self.metainfo_requests: download = self.metainfo_requests[infohash][0] self.metainfo_requests[infohash][1] += 1 elif infohash in self.downloads: download = self.downloads[infohash] else: tdef = TorrentDefNoMetainfo(infohash, 'metainfo request', url=url) dcfg = DownloadConfig() dcfg.set_hops(hops or self.download_defaults.number_hops) dcfg.set_upload_mode( True ) # Upload mode should prevent libtorrent from creating files dcfg.set_dest_dir(self.metadata_tmpdir) try: download = self.start_download(tdef=tdef, config=dcfg, hidden=True, checkpoint_disabled=True) except TypeError: return self.metainfo_requests[infohash] = [download, 1] try: metainfo = download.tdef.get_metainfo() or await wait_for( shield(download.future_metainfo), timeout) self._logger.info('Successfully retrieved metainfo for %s', infohash_hex) self.metainfo_cache[infohash] = { 'time': timemod.time(), 'meta_info': metainfo } except (CancelledError, asyncio.TimeoutError): metainfo = None self._logger.info('Failed to retrieve metainfo for %s', infohash_hex) if infohash in self.metainfo_requests: self.metainfo_requests[infohash][1] -= 1 if self.metainfo_requests[infohash][1] <= 0: await self.remove_download(download, remove_content=True) self.metainfo_requests.pop(infohash, None) return metainfo
async def hidden_seeder_comm(proxy_factory, video_tdef): # Also load the tunnel community in the seeder session comm = await proxy_factory.get(start_lt=True) comm.build_tunnels(1) dscfg_seed = DownloadConfig() dscfg_seed.set_dest_dir(TESTS_DATA_DIR) dscfg_seed.set_hops(1) upload = comm.dlmgr.start_download(tdef=video_tdef, config=dscfg_seed) def seeder_state_callback(ds): """ The callback of the seeder download. For now, this only logs the state of the download that's seeder and is useful for debugging purposes. """ comm.monitor_downloads([ds]) d = ds.get_download() print( f"seeder: {repr(d.get_def().get_name())} {dlstatus_strings[ds.get_status()]} {ds.get_progress()}" ) return 2 upload.set_state_callback(seeder_state_callback) await upload.wait_for_status(DLSTATUS_SEEDING) return comm
def start_anon_download(tunnel_community: TriblerTunnelCommunity, seeder_port, tdef: TorrentDef, hops=1): """ Start an anonymous download in the main Tribler session. """ download_manager = tunnel_community.dlmgr dscfg = DownloadConfig() dscfg.set_dest_dir(download_manager.state_dir) dscfg.set_hops(hops) download = download_manager.start_download(tdef=tdef, config=dscfg) tunnel_community.bittorrent_peers[download] = [("127.0.0.1", seeder_port)] return download
async def create_torrent(self, request): parameters = await request.json() params = {} if 'files' in parameters and parameters['files']: file_path_list = [ ensure_unicode(f, 'utf-8') for f in parameters['files'] ] else: return RESTResponse({"error": "files parameter missing"}, status=HTTP_BAD_REQUEST) if 'description' in parameters and parameters['description']: params['comment'] = parameters['description'] if 'trackers' in parameters and parameters['trackers']: tracker_url_list = parameters['trackers'] params['announce'] = tracker_url_list[0] params['announce-list'] = tracker_url_list name = 'unknown' if 'name' in parameters and parameters['name']: name = parameters['name'] params['name'] = name export_dir = None if 'export_dir' in parameters and parameters['export_dir']: export_dir = Path(parameters['export_dir']) from tribler_core.version import version_id params['created by'] = f"Tribler version: {version_id}" params['nodes'] = False params['httpseeds'] = False params['encoding'] = False params['piece length'] = 0 # auto try: result = await self.download_manager.create_torrent_file( file_path_list, recursive_bytes(params)) except (OSError, UnicodeDecodeError, RuntimeError) as e: self._logger.exception(e) return return_handled_exception(request, e) metainfo_dict = bdecode_compat(result['metainfo']) if export_dir and export_dir.exists(): save_path = export_dir / (f"{name}.torrent") with open(save_path, "wb") as fd: fd.write(result['metainfo']) # Download this torrent if specified if 'download' in request.query and request.query[ 'download'] and request.query['download'] == "1": download_config = DownloadConfig() download_config.set_dest_dir(result['base_dir']) download_config.set_hops( self.download_manager.download_defaults.number_hops) self.download_manager.start_download( tdef=TorrentDef(metainfo_dict), config=download_config) return RESTResponse( json.dumps({ "torrent": base64.b64encode(result['metainfo']).decode('utf-8') }))