def do_help(self, infohash, torrent_data, permid): basename = binascii.hexlify( infohash) + '.torrent' # ignore .tribe stuff, not vital torrentfilename = os.path.join(self.helpdir, basename) tfile = open(torrentfilename, "wb") tfile.write(torrent_data) tfile.close() if DEBUG: print >> sys.stderr, "helpmsg: Got metadata required for helping", show_permid_short( permid) print >> sys.stderr, "helpmsg: torrent: ", torrentfilename tdef = TorrentDef.load(torrentfilename) if self.dlconfig is None: dscfg = DownloadStartupConfig() else: dscfg = DownloadStartupConfig(self.dlconfig) dscfg.set_coopdl_coordinator_permid(permid) dscfg.set_dest_dir(self.helpdir) # Start new download self.session.start_download(tdef, dscfg)
def _on_torrent_created(result): """ Success callback :param result: from create_torrent_file """ with open(result['torrent_file_path'], 'rb') as f: torrent_64 = base64.b64encode(f.read()) # Download this torrent if specified if 'download' in request.args and len(request.args['download']) > 0 \ and request.args['download'][0] == "1": download_config = DownloadStartupConfig() download_config.set_dest_dir(result['base_path'] if len( file_path_list) == 1 else result['base_dir']) try: self.session.start_download_from_uri( 'file:' + result['torrent_file_path'], download_config) except DuplicateDownloadException: self._logger.warning( "The created torrent is already being downloaded.") request.write(json.dumps({"torrent": torrent_64})) # If the above request.write failed, the request will have already been finished if not request.finished: request.finish()
def copy(self): config = CallbackConfigParser() config._sections = { 'downloadconfig': copy.deepcopy(self.dlconfig._sections['downloadconfig']) } return DownloadStartupConfig(config)
def _on_torrent_created(result): """ Success callback :param result: from create_torrent_file """ metainfo_dict = bdecode(result['metainfo']) # Download this torrent if specified if 'download' in request.args and len(request.args['download']) > 0 \ and request.args['download'][0] == "1": download_config = DownloadStartupConfig() download_config.set_dest_dir(result['base_path'] if len( file_path_list) == 1 else result['base_dir']) try: self.session.lm.ltmgr.start_download( tdef=TorrentDef(metainfo=metainfo_dict), dconfig=download_config) except DuplicateDownloadException: self._logger.warning( "The created torrent is already being downloaded.") request.write( json.dumps({"torrent": base64.b64encode(result['metainfo'])})) # If the above request.write failed, the request will have already been finished if not request.finished: request.finish()
def download_channel(self, channel): """ Download a channel with a given infohash and title. :param channel: The channel metadata ORM object. """ dcfg = DownloadStartupConfig() dcfg.set_dest_dir(self.session.lm.mds.channels_dir) dcfg.set_channel_download(True) tdef = TorrentDefNoMetainfo(infohash=str(channel.infohash), name=channel.dir_name) download = self.session.start_download_from_tdef(tdef, dcfg) def on_channel_download_finished(dl): channel_dirname = os.path.join(self.session.lm.mds.channels_dir, dl.get_def().get_name()) self.session.lm.mds.process_channel_dir(channel_dirname, channel.public_key, external_thread=True) self.session.lm.mds._db.disconnect() def _on_failure(failure): self._logger.error( "Error when processing channel dir download: %s", failure) finished_deferred = download.finished_deferred.addCallback( lambda dl: deferToThread(on_channel_download_finished, dl)) finished_deferred.addErrback(_on_failure) return download, finished_deferred
def test_stop_download(self): """ Testing whether the API returns 200 if a download is being stopped """ video_tdef, _ = self.create_local_torrent( os.path.join(TESTS_DATA_DIR, 'video.avi')) download = self.session.start_download_from_tdef( video_tdef, DownloadStartupConfig()) infohash = video_tdef.get_infohash().encode('hex') original_stop = download.stop def mocked_stop(): download.should_stop = True download.stop = original_stop def verify_removed(_): self.assertEqual(len(self.session.get_downloads()), 1) download = self.session.get_downloads()[0] self.assertTrue(download.should_stop) download.stop = mocked_stop request_deferred = self.do_request( 'downloads/%s' % infohash, post_data={"state": "stop"}, expected_code=200, request_type='PATCH', expected_json={ "modified": True, "infohash": "8bb88a02da691636a7ed929b87d467f24700e490" }) return request_deferred.addCallback(verify_removed)
def setUpDownloadConfig(self): dscfg = DownloadStartupConfig() print >> sys.stderr, "test: Downloading to", self.config_path dscfg.set_dest_dir(self.config_path) dscfg.set_breakup_seed_bitfield(False) return dscfg
def setUpPostSession(self): """ override TestAsServer """ TestAsServer.setUpPostSession(self) # Let Tribler start downloading an non-functioning torrent, so # we can talk to a normal download engine. self.torrentfn = os.path.join('extend_hs_dir', 'dummydata.merkle.torrent') tdef = TorrentDef.load(self.torrentfn) dscfg = DownloadStartupConfig() dscfg.set_dest_dir(self.config_path) self.session.start_download(tdef, dscfg) # This is the infohash of the torrent in test/extend_hs_dir self.infohash = '\xccg\x07\xe2\x9e!]\x16\xae{\xb8\x10?\xf9\xa5\xf9\x07\xfdBk' self.setUpMyListenSocket() # Must be changed in test/extend_hs_dir/dummydata.merkle.torrent as well self.mytrackerport = 4901 # Must be Tribler version <= 3.5.0. Changing this to 351 makes this test # fail, so it's a good test. self.myid = 'R350-----HgUyPu56789' self.mytracker = MyTracker(self.mytrackerport, self.myid, '127.0.0.1', self.mylistenport) self.mytracker.background_serve() print >> sys.stderr, "test: Giving MyTracker and myself time to start" time.sleep(5)
def setup_tunnel_seeder(self, hops): """ Setup the seeder. """ from Tribler.Core.Session import Session self.seed_config = self.config.copy() self.seed_config.set_state_dir(self.getStateDir(2)) self.seed_config.set_tunnel_community_socks5_listen_ports( self.get_socks5_ports()) if self.session2 is None: self.session2 = Session(self.seed_config) self.session2.start() tdef = TorrentDef() tdef.add_content(os.path.join(TESTS_DATA_DIR, "video.avi")) tdef.set_tracker("http://localhost/announce") torrentfn = os.path.join(self.session2.config.get_state_dir(), "gen.torrent") tdef.save(torrent_filepath=torrentfn) self.seed_tdef = tdef if hops > 0: # Safe seeding enabled self.tunnel_community_seeder = self.load_tunnel_community_in_session( self.session2) self.tunnel_community_seeder.build_tunnels(hops) else: self.sanitize_network(self.session2) dscfg = DownloadStartupConfig() dscfg.set_dest_dir( TESTS_DATA_DIR) # basedir of the file we are seeding dscfg.set_hops(hops) d = self.session2.start_download_from_tdef(tdef, dscfg) d.set_state_callback(self.seeder_state_callback)
def setup_tunnel_seeder(self, hops): """ Setup the seeder. """ from Tribler.Core.Session import Session self.seed_config = self.config.copy() self.seed_config.set_state_dir(self.getStateDir(2)) self.seed_config.set_megacache_enabled(True) self.seed_config.set_tunnel_community_socks5_listen_ports(self.get_socks5_ports()) if self.session2 is None: self.session2 = Session(self.seed_config, ignore_singleton=True, autoload_discovery=False) self.session2.start() tdef = TorrentDef() tdef.add_content(os.path.join(TESTS_DATA_DIR, "video.avi")) tdef.set_tracker("http://localhost/announce") tdef.finalize() torrentfn = os.path.join(self.session2.config.get_state_dir(), "gen.torrent") tdef.save(torrentfn) self.seed_tdef = tdef if hops > 0: # Safe seeding enabled self.tunnel_community_seeder = self.load_tunnel_community_in_session(self.session2) self.tunnel_community_seeder.build_tunnels(hops) from twisted.internet import reactor, task while not list(self.tunnel_community_seeder.active_data_circuits()): yield task.deferLater(reactor, .05, lambda: None) dscfg = DownloadStartupConfig() dscfg.set_dest_dir(TESTS_DATA_DIR) # basedir of the file we are seeding dscfg.set_hops(hops) d = self.session2.start_download_from_tdef(tdef, dscfg) d.set_state_callback(self.seeder_state_callback)
def test_resume_download(self): """ Testing whether the API returns 200 if a download is being resumed """ video_tdef, _ = self.create_local_torrent( os.path.join(TESTS_DATA_DIR, 'video.avi')) download = self.session.start_download_from_tdef( video_tdef, DownloadStartupConfig()) infohash = video_tdef.get_infohash().encode('hex') def mocked_restart(): download.should_restart = True def verify_resumed(_): self.assertEqual(len(self.session.get_downloads()), 1) download = self.session.get_downloads()[0] self.assertTrue(download.should_restart) download.restart = mocked_restart request_deferred = self.do_request('downloads/%s' % infohash, post_data={"state": "resume"}, expected_code=200, expected_json={"modified": True}, request_type='PATCH') return request_deferred.addCallback(verify_resumed)
def test_select_download_file(self): """ Testing whether files can be correctly toggled in a download """ video_tdef, _ = self.create_local_torrent( os.path.join(TESTS_DATA_DIR, 'video.avi')) download = self.session.start_download_from_tdef( video_tdef, DownloadStartupConfig()) infohash = video_tdef.get_infohash().encode('hex') def mocked_set_selected_files(*_): mocked_set_selected_files.called = True mocked_set_selected_files.called = False def verify_method_called(_): self.assertTrue(mocked_set_selected_files.called) download.set_selected_files = mocked_set_selected_files return self.do_request('downloads/%s' % infohash, post_data={"selected_files[]": 0}, expected_code=200, request_type='PATCH', expected_json={"modified": True, "infohash": "8bb88a02da691636a7ed929b87d467f24700e490"})\ .addCallback(verify_method_called)
def test_recheck_download(self): """ Testing whether the API returns 200 if a download is being rechecked """ video_tdef, _ = self.create_local_torrent( os.path.join(TESTS_DATA_DIR, 'video.avi')) download = self.session.start_download_from_tdef( video_tdef, DownloadStartupConfig()) infohash = video_tdef.get_infohash().encode('hex') def mocked_recheck(): mocked_recheck.called = True mocked_recheck.called = False download.force_recheck = mocked_recheck def verify_rechecked(_): self.assertEqual(len(self.session.get_downloads()), 1) self.assertTrue(mocked_recheck.called) request_deferred = self.do_request( 'downloads/%s' % infohash, post_data={"state": "recheck"}, expected_code=200, request_type='PATCH', expected_json={ "modified": True, "infohash": "8bb88a02da691636a7ed929b87d467f24700e490" }) return request_deferred.addCallback(verify_rechecked)
def test_get_downloads_with_channels(self): """ Testing whether the API returns the right download when a download is added """ test_channel_name = 'testchan' def verify_download(downloads): downloads_json = json.loads(downloads) self.assertEqual(len(downloads_json['downloads']), 3) self.assertEqual(test_channel_name, [d for d in downloads_json["downloads"] if d["channel_download"]][0]["name"]) video_tdef, _ = self.create_local_torrent(os.path.join(TESTS_DATA_DIR, 'video.avi')) self.session.start_download_from_tdef(video_tdef, DownloadStartupConfig()) self.session.start_download_from_uri("file:" + pathname2url( os.path.join(TESTS_DATA_DIR, "bak_single.torrent"))) with db_session: my_channel = self.session.lm.mds.ChannelMetadata.create_channel(test_channel_name, 'test') my_channel.add_torrent_to_channel(video_tdef) torrent_dict = my_channel.commit_channel_torrent() self.session.lm.gigachannel_manager.updated_my_channel(TorrentDef.TorrentDef.load_from_dict(torrent_dict)) self.should_check_equality = False return self.do_request('downloads?get_peers=1&get_pieces=1', expected_code=200).addCallback(verify_download)
def create_torrent(self): [srchandle, sourcefn] = mkstemp() self.content = Rand.rand_bytes(self.contentlen) os.write(srchandle, self.content) os.close(srchandle) self.tdef = TorrentDef() self.tdef.add_content(sourcefn) self.tdef.set_piece_length(self.piecelen) self.tdef.set_tracker("http://127.0.0.1:12/announce") self.tdef.finalize() torrentfn = os.path.join(self.session.config.get_state_dir(), "gen.torrent") self.tdef.save(torrentfn) dscfg = DownloadStartupConfig() destdir = os.path.dirname(sourcefn) dscfg.set_dest_dir(destdir) dscfg.set_mode(DLMODE_VOD) download = self.session.start_download_from_tdef(self.tdef, dscfg) download.set_state_callback(self.state_callback) self.session.set_download_states_callback(self.states_callback)
def test_multifile_torrent(self): tdef = TorrentDef() dn = os.path.join(TESTS_DATA_DIR, "contentdir") tdef.add_content(dn, "dirintorrent") fn = os.path.join(TESTS_DATA_DIR, "video.avi") tdef.add_content(fn, os.path.join("dirintorrent", "video.avi")) tdef.set_tracker("http://tribler.org/announce") tdef.finalize() impl = LibtorrentDownloadImpl(self.session, tdef) # Override the add_torrent because it will be called impl.ltmgr = MockObject() impl.ltmgr.add_torrent = lambda _, _dummy2: fake_handler impl.set_selected_files = lambda: None fake_handler = MockObject() fake_handler.is_valid = lambda: True fake_handler.status = lambda: fake_status fake_handler.set_share_mode = lambda _: None fake_handler.resume = lambda: None fake_handler.resolve_countries = lambda _: None fake_status = MockObject() fake_status.share_mode = False # Create a dummy download config impl.dlconfig = DownloadStartupConfig().dlconfig.copy() # Create a dummy pstate pstate = CallbackConfigParser() pstate.add_section("state") test_dict = dict() test_dict["a"] = "b" pstate.set("state", "engineresumedata", test_dict) return impl.network_create_engine_wrapper(pstate)
def setupSeeder(self): from Tribler.Core.Session import Session from Tribler.Core.TorrentDef import TorrentDef from Tribler.Core.DownloadConfig import DownloadStartupConfig self.setUpPreSession() self.config.set_libtorrent(True) self.config2 = self.config.copy() self.session2 = Session(self.config2, ignore_singleton=True) upgrader = self.session2.prestart() while not upgrader.is_done: time.sleep(0.1) assert not upgrader.failed, upgrader.current_status self.session2.start() tdef = TorrentDef() tdef.add_content(os.path.join(TESTS_DATA_DIR, "video.avi")) tdef.set_tracker("http://fake.net/announce") tdef.finalize() torrentfn = os.path.join(self.session.get_state_dir(), "gen.torrent") tdef.save(torrentfn) dscfg = DownloadStartupConfig() dscfg.set_dest_dir( TESTS_DATA_DIR) # basedir of the file we are seeding d = self.session2.start_download(tdef, dscfg) d.set_state_callback(self.seeder_state_callback) return torrentfn
def test_stop_download(self): """ Testing whether the API returns 200 if a download is being stopped """ video_tdef, _ = self.create_local_torrent(os.path.join(TESTS_DATA_DIR, 'video.avi')) download = self.session.start_download_from_tdef(video_tdef, DownloadStartupConfig()) infohash = get_hex_infohash(video_tdef) original_stop = download.stop def mocked_stop(): download.should_stop = True download.stop = original_stop def verify_removed(_): self.assertEqual(len(self.session.get_downloads()), 1) download = self.session.get_downloads()[0] self.assertTrue(download.should_stop) download.stop = mocked_stop request_deferred = self.do_request('downloads/%s' % infohash, post_data={"state": "stop"}, expected_code=200, request_type='PATCH', expected_json={"modified": True, "infohash": "c9a19e7fe5d9a6c106d6ea3c01746ac88ca3c7a5"}) return request_deferred.addCallback(verify_removed)
def test_change_hops_fail(self): def on_remove_download(d, remove_content=False, remove_state=True, hidden=False): return fail(RuntimeError()) self.session.remove_download = on_remove_download video_tdef, _ = self.create_local_torrent( os.path.join(TESTS_DATA_DIR, 'video.avi')) self.session.start_download_from_tdef(video_tdef, DownloadStartupConfig()) infohash = video_tdef.get_infohash().encode('hex') return self.do_request('downloads/%s' % infohash, post_data={"remove_data": True}, expected_code=500, expected_json={ u'error': { u'message': u'', u'code': u'RuntimeError', u'handled': True } }, request_type='DELETE')
def resume_download(self, filename, setupDelay=0): tdef = dscfg = pstate = None try: pstate = self.load_download_pstate(filename) # SWIFTPROC metainfo = pstate.get('state', 'metainfo') if 'infohash' in metainfo: tdef = TorrentDefNoMetainfo(metainfo['infohash'], metainfo['name'], metainfo.get('url', None)) else: tdef = TorrentDef.load_from_dict(metainfo) if pstate.has_option('download_defaults', 'saveas') and \ isinstance(pstate.get('download_defaults', 'saveas'), tuple): pstate.set('download_defaults', 'saveas', pstate.get('download_defaults', 'saveas')[-1]) dscfg = DownloadStartupConfig(pstate) except: # pstate is invalid or non-existing _, file = os.path.split(filename) infohash = binascii.unhexlify(file[:-6]) torrent_data = self.torrent_store.get(infohash) if torrent_data: try: tdef = TorrentDef.load_from_memory(torrent_data) defaultDLConfig = DefaultDownloadStartupConfig.getInstance() dscfg = defaultDLConfig.copy() if self.mypref_db is not None: dest_dir = self.mypref_db.getMyPrefStatsInfohash(infohash) if dest_dir and os.path.isdir(dest_dir): dscfg.set_dest_dir(dest_dir) except ValueError: self._logger.warning("tlm: torrent data invalid") if pstate is not None: has_resume_data = pstate.get('state', 'engineresumedata') is not None self._logger.debug("tlm: load_checkpoint: resumedata %s", 'len %s ' % len(pstate.get('state', 'engineresumedata')) if has_resume_data else 'None') if tdef and dscfg: if dscfg.get_dest_dir() != '': # removed torrent ignoring try: if not self.download_exists(tdef.get_infohash()): self.add(tdef, dscfg, pstate, setupDelay=setupDelay) else: self._logger.info("tlm: not resuming checkpoint because download has already been added") except Exception as e: self._logger.exception("tlm: load check_point: exception while adding download %s", tdef) else: self._logger.info("tlm: removing checkpoint %s destdir is %s", filename, dscfg.get_dest_dir()) os.remove(filename) else: self._logger.info("tlm: could not resume checkpoint %s %s %s", filename, tdef, dscfg)
def setup_seeder(self): self.seeder_setup_complete = threading.Event() self.dscfg = DownloadStartupConfig() self.dscfg.set_dest_dir(TESTS_API_DIR) self.download = self.session.start_download(self.tdef, self.dscfg) self.download.set_state_callback(self.seeder_state_callback) assert self.seeder_setup_complete.wait(30)
def test_change_hops(self): """ Testing whether the API returns 200 if we change the amount of hops of a download """ video_tdef, _ = self.create_local_torrent(os.path.join(TESTS_DATA_DIR, 'video.avi')) self.session.start_download_from_tdef(video_tdef, DownloadStartupConfig()) infohash = video_tdef.get_infohash().encode('hex') return self.do_request('downloads/%s' % infohash, post_data={'anon_hops': 1}, expected_code=200, expected_json={'modified': True}, request_type='PATCH')
def test_download_unknown_state(self): """ Testing whether the API returns error 400 if an unknown state is passed when modifying a download """ video_tdef, _ = self.create_local_torrent(os.path.join(TESTS_DATA_DIR, 'video.avi')) self.session.start_download_from_tdef(video_tdef, DownloadStartupConfig()) self.should_check_equality = False return self.do_request('downloads/%s' % video_tdef.get_infohash().encode('hex'), expected_code=400, post_data={"state": "abc"}, request_type='PATCH')
def start_anon_download(self, hops=1): """ Start an anonymous download in the main Tribler session. """ dscfg = DownloadStartupConfig() dscfg.set_dest_dir(self.getDestDir()) dscfg.set_hops(hops) download = self.session.start_download_from_tdef(self.seed_tdef, dscfg) download.add_peer(("127.0.0.1", self.session2.config.get_libtorrent_port())) return download
def new_download(self, permid, infohash, torrent_data): """ Start a new download in order to get the pieces that will be requested by the doe. After the download is started, find the appropriate proxy object and call it's method. @param permid: The permid of the peer who sent the message @param infohash: the infohash of the torrent for which relay is requested @param torrent_data: the content of the .torrent file """ # Create the name for the .torrent file in the proxy cache basename = binascii.hexlify(infohash) + '.torrent' torrentfilename = os.path.join(self.proxydir, basename) # Write the .torrent information in the .torrent proxy cache file tfile = open(torrentfilename, "wb") tfile.write(torrent_data) tfile.close() if DEBUG: print >> sys.stderr, "proxy: new_download: Got metadata required for relaying" print >> sys.stderr, "proxy: new_download: torrent: ", torrentfilename tdef = TorrentDef.load(torrentfilename) if self.dlconfig is None: dscfg = DownloadStartupConfig() else: dscfg = DownloadStartupConfig(self.dlconfig) dscfg.set_proxyservice_role(PROXYSERVICE_ROLE_PROXY) dscfg.set_dest_dir(self.proxydir) dscfg.set_doe_mode( DOE_MODE_OFF ) # a proxy does not use other proxies for downloading data in the current stage # Start new download if DEBUG: print >> sys.stderr, "proxy: new_download: Starting a new download" self.session.add_observer(self.proxydownloader_started, NTFY_PROXYDOWNLOADER, [NTFY_STARTED]) d = self.session.start_download(tdef, dscfg) d.set_state_callback(self.state_callback, getpeerlist=False)
def test_change_hops_error(self): """ Testing whether the API returns 400 if we supply both anon_hops and another parameter """ video_tdef, _ = self.create_local_torrent(os.path.join(TESTS_DATA_DIR, 'video.avi')) self.session.start_download_from_tdef(video_tdef, DownloadStartupConfig()) infohash = video_tdef.get_infohash().encode('hex') self.should_check_equality = False return self.do_request('downloads/%s' % infohash, post_data={"state": "resume", 'anon_hops': 1}, expected_code=400, request_type='PATCH')
def test_select_download_file_range(self): """ Testing whether an error is returned when we toggle a file for inclusion out of range """ video_tdef, _ = self.create_local_torrent(os.path.join(TESTS_DATA_DIR, 'video.avi')) self.session.start_download_from_tdef(video_tdef, DownloadStartupConfig()) infohash = video_tdef.get_infohash().encode('hex') self.should_check_equality = False return self.do_request('downloads/%s' % infohash, expected_code=400, post_data={"selected_files[]": 1234}, request_type='PATCH')
def start_vod_download(self): self.tdef = TorrentDef() self.tdef.add_content(self.sourcefn) self.tdef.set_tracker("http://127.0.0.1:12/announce") self.tdef.finalize() dscfg = DownloadStartupConfig() dscfg.set_dest_dir(os.path.dirname(self.sourcefn)) download = self.session.start_download_from_tdef(self.tdef, dscfg) return download.get_handle()
def setUpPreSession(self): """ override TestAsServer """ super(TestSeeding, self).setUpPreSession() self.config.set_libtorrent(True) self.config2 = self.config.copy() # not really necess self.config2.set_state_dir(self.getStateDir(2)) self.dscfg2 = DownloadStartupConfig() self.dscfg2.set_dest_dir(self.getDestDir(2))
def register_file_stream(self): self.tdef = TorrentDef() self.tdef.add_content(self.sourcefn) self.tdef.set_tracker("http://127.0.0.1:12/announce") self.tdef.finalize() dscfg = DownloadStartupConfig() dscfg.set_dest_dir(os.path.dirname(self.sourcefn)) download = self.session.start_download(self.tdef, dscfg) while not download.handle: time.sleep(1)